diff options
Diffstat (limited to 'src/cmd')
942 files changed, 55477 insertions, 33349 deletions
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go index 578d88e432..992d7ac11e 100644 --- a/src/cmd/addr2line/addr2line_test.go +++ b/src/cmd/addr2line/addr2line_test.go @@ -8,7 +8,6 @@ import ( "bufio" "bytes" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -73,33 +72,41 @@ func testAddr2Line(t *testing.T, exepath, addr string) { if err != nil { t.Fatalf("Stat failed: %v", err) } + // Debug paths are stored slash-separated, so convert to system-native. srcPath = filepath.FromSlash(srcPath) fi2, err := os.Stat(srcPath) - if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" && strings.HasPrefix(srcPath, gorootFinal) { - if os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2)) { - // srcPath has had GOROOT_FINAL substituted for GOROOT, and it doesn't - // match the actual file. GOROOT probably hasn't been moved to its final - // location yet, so try the original location instead. + + // If GOROOT_FINAL is set and srcPath is not the file we expect, perhaps + // srcPath has had GOROOT_FINAL substituted for GOROOT and GOROOT hasn't been + // moved to its final location yet. If so, try the original location instead. + if gorootFinal := os.Getenv("GOROOT_FINAL"); gorootFinal != "" && + (os.IsNotExist(err) || (err == nil && !os.SameFile(fi1, fi2))) { + // srcPath is clean, but GOROOT_FINAL itself might not be. + // (See https://golang.org/issue/41447.) + gorootFinal = filepath.Clean(gorootFinal) + + if strings.HasPrefix(srcPath, gorootFinal) { fi2, err = os.Stat(runtime.GOROOT() + strings.TrimPrefix(srcPath, gorootFinal)) } } + if err != nil { t.Fatalf("Stat failed: %v", err) } if !os.SameFile(fi1, fi2) { t.Fatalf("addr2line_test.go and %s are not same file", srcPath) } - if srcLineNo != "99" { - t.Fatalf("line number = %v; want 99", srcLineNo) + if srcLineNo != "106" { + t.Fatalf("line number = %v; want 106", srcLineNo) } } -// This is line 98. The test depends on that. +// This is line 106. The test depends on that. func TestAddr2Line(t *testing.T) { testenv.MustHaveGoBuild(t) - tmpDir, err := ioutil.TempDir("", "TestAddr2Line") + tmpDir, err := os.MkdirTemp("", "TestAddr2Line") if err != nil { t.Fatal("TempDir failed: ", err) } diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go index 01b17b8839..ba42812fa6 100644 --- a/src/cmd/api/goapi.go +++ b/src/cmd/api/goapi.go @@ -17,7 +17,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "log" "os" "os/exec" @@ -87,7 +86,10 @@ var contexts = []*build.Context{ func contextName(c *build.Context) string { s := c.GOOS + "-" + c.GOARCH if c.CgoEnabled { - return s + "-cgo" + s += "-cgo" + } + if c.Dir != "" { + s += fmt.Sprintf(" [%s]", c.Dir) } return s } @@ -323,15 +325,29 @@ func compareAPI(w io.Writer, features, required, optional, exception []string, a return } +// aliasReplacer applies type aliases to earlier API files, +// to avoid misleading negative results. +// This makes all the references to os.FileInfo in go1.txt +// be read as if they said fs.FileInfo, since os.FileInfo is now an alias. +// If there are many of these, we could do a more general solution, +// but for now the replacer is fine. +var aliasReplacer = strings.NewReplacer( + "os.FileInfo", "fs.FileInfo", + "os.FileMode", "fs.FileMode", + "os.PathError", "fs.PathError", +) + func fileFeatures(filename string) []string { if filename == "" { return nil } - bs, err := ioutil.ReadFile(filename) + bs, err := os.ReadFile(filename) if err != nil { log.Fatalf("Error reading file %s: %v", filename, err) } - lines := strings.Split(string(bs), "\n") + s := string(bs) + s = aliasReplacer.Replace(s) + lines := strings.Split(s, "\n") var nonblank []string for _, line := range lines { line = strings.TrimSpace(line) @@ -478,6 +494,9 @@ func (w *Walker) loadImports() { cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std") cmd.Env = listEnv(w.context) + if w.context.Dir != "" { + cmd.Dir = w.context.Dir + } out, err := cmd.CombinedOutput() if err != nil { log.Fatalf("loading imports: %v\n%s", err, out) @@ -491,6 +510,7 @@ func (w *Walker) loadImports() { var pkg struct { ImportPath, Dir string ImportMap map[string]string + Standard bool } err := dec.Decode(&pkg) if err == io.EOF { @@ -503,11 +523,13 @@ func (w *Walker) loadImports() { // - Package "unsafe" contains special signatures requiring // extra care when printing them - ignore since it is not // going to change w/o a language change. - // - internal and vendored packages do not contribute to our - // API surface. + // - Internal and vendored packages do not contribute to our + // API surface. (If we are running within the "std" module, + // vendored dependencies appear as themselves instead of + // their "vendor/" standard-library copies.) // - 'go list std' does not include commands, which cannot be // imported anyway. - if ip := pkg.ImportPath; ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) { + if ip := pkg.ImportPath; pkg.Standard && ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) { stdPackages = append(stdPackages, ip) } importDir[pkg.ImportPath] = pkg.Dir @@ -847,6 +869,10 @@ func (w *Walker) emitObj(obj types.Object) { func (w *Walker) emitType(obj *types.TypeName) { name := obj.Name() typ := obj.Type() + if obj.IsAlias() { + w.emitf("type %s = %s", name, w.typeString(typ)) + return + } switch typ := typ.Underlying().(type) { case *types.Struct: w.emitStructType(name, typ) diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go index eaccc5ceb5..16e0058e5e 100644 --- a/src/cmd/api/goapi_test.go +++ b/src/cmd/api/goapi_test.go @@ -9,7 +9,6 @@ import ( "flag" "fmt" "go/build" - "io/ioutil" "os" "path/filepath" "sort" @@ -75,7 +74,7 @@ func TestGolden(t *testing.T) { f.Close() } - bs, err := ioutil.ReadFile(goldenFile) + bs, err := os.ReadFile(goldenFile) if err != nil { t.Fatalf("opening golden.txt for package %q: %v", fi.Name(), err) } @@ -216,3 +215,16 @@ func TestIssue29837(t *testing.T) { } } } + +func TestIssue41358(t *testing.T) { + context := new(build.Context) + *context = build.Default + context.Dir = filepath.Join(context.GOROOT, "src") + + w := NewWalker(context, context.Dir) + for _, pkg := range w.stdPackages { + if strings.HasPrefix(pkg, "vendor/") || strings.HasPrefix(pkg, "golang.org/x/") { + t.Fatalf("stdPackages contains unexpected package %s", pkg) + } + } +} diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go index 2e5d0ff991..a62e55191e 100644 --- a/src/cmd/asm/internal/arch/arch.go +++ b/src/cmd/asm/internal/arch/arch.go @@ -535,6 +535,9 @@ func archRISCV64() *Arch { // Standard register names. for i := riscv.REG_X0; i <= riscv.REG_X31; i++ { + if i == riscv.REG_G { + continue + } name := fmt.Sprintf("X%d", i-riscv.REG_X0) register[name] = int16(i) } @@ -571,7 +574,7 @@ func archRISCV64() *Arch { register["S8"] = riscv.REG_S8 register["S9"] = riscv.REG_S9 register["S10"] = riscv.REG_S10 - register["S11"] = riscv.REG_S11 + // Skip S11 as it is the g register. register["T3"] = riscv.REG_T3 register["T4"] = riscv.REG_T4 register["T5"] = riscv.REG_T5 diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index 3817fcd5c2..e557630ca6 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -75,13 +75,35 @@ func IsARM64STLXR(op obj.As) bool { arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW: return true } - // atomic instructions + // LDADDx/SWPx/CASx atomic instructions if arm64.IsAtomicInstruction(op) { return true } return false } +// IsARM64TBL reports whether the op (as defined by an arm64.A* +// constant) is one of the TBL-like instructions and one of its +// inputs does not fit into prog.Reg, so require special handling. +func IsARM64TBL(op obj.As) bool { + switch op { + case arm64.AVTBL, arm64.AVMOVQ: + return true + } + return false +} + +// IsARM64CASP reports whether the op (as defined by an arm64.A* +// constant) is one of the CASP-like instructions, and its 2nd +// destination is a register pair that require special handling. +func IsARM64CASP(op obj.As) bool { + switch op { + case arm64.ACASPD, arm64.ACASPW: + return true + } + return false +} + // ARM64Suffix handles the special suffix for the ARM64. // It returns a boolean to indicate success; failure means // cond was unrecognized. @@ -125,13 +147,6 @@ func arm64RegisterNumber(name string, n int16) (int16, bool) { return 0, false } -// IsARM64TBL reports whether the op (as defined by an arm64.A* -// constant) is one of the table lookup instructions that require special -// handling. -func IsARM64TBL(op obj.As) bool { - return op == arm64.AVTBL -} - // ARM64RegisterExtension parses an ARM64 register with extension or arrangement. func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error { Rnum := (reg & 31) + int16(num<<5) diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 42e217dc23..c4032759bb 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -181,7 +181,7 @@ func (p *Parser) asmText(operands [][]lex.Token) { // Argsize set below. }, } - nameAddr.Sym.Func.Text = prog + nameAddr.Sym.Func().Text = prog prog.To.Val = int32(argSize) p.append(prog, "", true) } @@ -622,8 +622,9 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { prog.SetFrom3(a[1]) prog.To = a[2] case sys.ARM64: - // ARM64 instructions with one input and two outputs. - if arch.IsARM64STLXR(op) { + switch { + case arch.IsARM64STLXR(op): + // ARM64 instructions with one input and two outputs. prog.From = a[0] prog.To = a[1] if a[2].Type != obj.TYPE_REG { @@ -631,20 +632,28 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { return } prog.RegTo2 = a[2].Reg - break - } - if arch.IsARM64TBL(op) { + case arch.IsARM64TBL(op): + // one of its inputs does not fit into prog.Reg. prog.From = a[0] - if a[1].Type != obj.TYPE_REGLIST { - p.errorf("%s: expected list; found %s", op, obj.Dconv(prog, &a[1])) - } prog.SetFrom3(a[1]) prog.To = a[2] - break + case arch.IsARM64CASP(op): + prog.From = a[0] + prog.To = a[1] + // both 1st operand and 3rd operand are (Rs, Rs+1) register pair. + // And the register pair must be contiguous. + if (a[0].Type != obj.TYPE_REGREG) || (a[2].Type != obj.TYPE_REGREG) { + p.errorf("invalid addressing modes for 1st or 3rd operand to %s instruction, must be register pair", op) + return + } + // For ARM64 CASP-like instructions, its 2nd destination operand is register pair(Rt, Rt+1) that can + // not fit into prog.RegTo2, so save it to the prog.RestArgs. + prog.SetTo2(a[2]) + default: + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + prog.To = a[2] } - prog.From = a[0] - prog.Reg = p.getRegister(prog, op, &a[1]) - prog.To = a[2] case sys.I386: prog.From = a[0] prog.SetFrom3(a[1]) @@ -728,7 +737,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { } if p.arch.Family == sys.AMD64 { prog.From = a[0] - prog.RestArgs = []obj.Addr{a[1], a[2]} + prog.SetRestArgs([]obj.Addr{a[1], a[2]}) prog.To = a[3] break } @@ -811,13 +820,13 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { } if p.arch.Family == sys.AMD64 { prog.From = a[0] - prog.RestArgs = []obj.Addr{a[1], a[2], a[3]} + prog.SetRestArgs([]obj.Addr{a[1], a[2], a[3]}) prog.To = a[4] break } if p.arch.Family == sys.S390X { prog.From = a[0] - prog.RestArgs = []obj.Addr{a[1], a[2], a[3]} + prog.SetRestArgs([]obj.Addr{a[1], a[2], a[3]}) prog.To = a[4] break } diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index 0759b7d10f..7472507caf 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -31,7 +31,7 @@ func testEndToEnd(t *testing.T, goarch, file string) { architecture, ctxt := setArch(goarch) architecture.Init(ctxt) lexer := lex.NewLexer(input) - parser := NewParser(ctxt, architecture, lexer) + parser := NewParser(ctxt, architecture, lexer, false) pList := new(obj.Plist) var ok bool testOut = new(bytes.Buffer) // The assembler writes test output to this buffer. @@ -257,11 +257,11 @@ func isHexes(s string) bool { return true } -// It would be nice if the error messages began with +// It would be nice if the error messages always began with // the standard file:line: prefix, // but that's not where we are today. // It might be at the beginning but it might be in the middle of the printed instruction. -var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\))`) +var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\)|:)`) // Same as in test/run.go var ( @@ -273,7 +273,7 @@ func testErrors(t *testing.T, goarch, file string) { input := filepath.Join("testdata", file+".s") architecture, ctxt := setArch(goarch) lexer := lex.NewLexer(input) - parser := NewParser(ctxt, architecture, lexer) + parser := NewParser(ctxt, architecture, lexer, false) pList := new(obj.Plist) var ok bool testOut = new(bytes.Buffer) // The assembler writes test output to this buffer. @@ -281,6 +281,7 @@ func testErrors(t *testing.T, goarch, file string) { defer ctxt.Bso.Flush() failed := false var errBuf bytes.Buffer + parser.errorWriter = &errBuf ctxt.DiagFunc = func(format string, args ...interface{}) { failed = true s := fmt.Sprintf(format, args...) @@ -292,7 +293,7 @@ func testErrors(t *testing.T, goarch, file string) { pList.Firstpc, ok = parser.Parse() obj.Flushplist(ctxt, pList, nil, "") if ok && !failed { - t.Errorf("asm: %s had no errors", goarch) + t.Errorf("asm: %s had no errors", file) } errors := map[string]string{} @@ -353,12 +354,7 @@ func testErrors(t *testing.T, goarch, file string) { } func Test386EndToEnd(t *testing.T) { - defer func(old string) { objabi.GO386 = old }(objabi.GO386) - for _, go386 := range []string{"387", "sse2"} { - t.Logf("GO386=%v", go386) - objabi.GO386 = go386 - testEndToEnd(t, "386", "386") - } + testEndToEnd(t, "386", "386") } func TestARMEndToEnd(t *testing.T) { @@ -373,6 +369,10 @@ func TestARMEndToEnd(t *testing.T) { } } +func TestGoBuildErrors(t *testing.T) { + testErrors(t, "amd64", "buildtagerror") +} + func TestARMErrors(t *testing.T) { testErrors(t, "arm", "armerror") } @@ -390,12 +390,7 @@ func TestARM64Errors(t *testing.T) { } func TestAMD64EndToEnd(t *testing.T) { - defer func(old string) { objabi.GOAMD64 = old }(objabi.GOAMD64) - for _, goamd64 := range []string{"normaljumps", "alignedjumps"} { - t.Logf("GOAMD64=%s", goamd64) - objabi.GOAMD64 = goamd64 - testEndToEnd(t, "amd64", "amd64") - } + testEndToEnd(t, "amd64", "amd64") } func Test386Encoder(t *testing.T) { @@ -442,10 +437,6 @@ func TestPPC64EndToEnd(t *testing.T) { testEndToEnd(t, "ppc64", "ppc64") } -func TestPPC64Encoder(t *testing.T) { - testEndToEnd(t, "ppc64", "ppc64enc") -} - func TestRISCVEncoder(t *testing.T) { testEndToEnd(t, "riscv64", "riscvenc") } diff --git a/src/cmd/asm/internal/asm/expr_test.go b/src/cmd/asm/internal/asm/expr_test.go index 1251594349..e9c92df1f3 100644 --- a/src/cmd/asm/internal/asm/expr_test.go +++ b/src/cmd/asm/internal/asm/expr_test.go @@ -57,7 +57,7 @@ var exprTests = []exprTest{ } func TestExpr(t *testing.T) { - p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. + p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser. for i, test := range exprTests { p.start(lex.Tokenize(test.input)) result := int64(p.expr()) @@ -113,7 +113,7 @@ func TestBadExpr(t *testing.T) { } func runBadTest(i int, test badExprTest, t *testing.T) (err error) { - p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. + p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser. p.start(lex.Tokenize(test.input)) return tryParse(t, func() { p.expr() diff --git a/src/cmd/asm/internal/asm/line_test.go b/src/cmd/asm/internal/asm/line_test.go index 01b058bd95..da857ced3a 100644 --- a/src/cmd/asm/internal/asm/line_test.go +++ b/src/cmd/asm/internal/asm/line_test.go @@ -39,7 +39,7 @@ func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) { for i, test := range tests { arch, ctxt := setArch(goarch) tokenizer := lex.NewTokenizer("", strings.NewReader(test.input+"\n"), nil) - parser := NewParser(ctxt, arch, tokenizer) + parser := NewParser(ctxt, arch, tokenizer, false) err := tryParse(t, func() { parser.Parse() diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go index f187d0b166..2e83e176b2 100644 --- a/src/cmd/asm/internal/asm/operand_test.go +++ b/src/cmd/asm/internal/asm/operand_test.go @@ -28,7 +28,7 @@ func setArch(goarch string) (*arch.Arch, *obj.Link) { func newParser(goarch string) *Parser { architecture, ctxt := setArch(goarch) - return NewParser(ctxt, architecture, nil) + return NewParser(ctxt, architecture, nil, false) } // tryParse executes parse func in panicOnError=true context. @@ -75,7 +75,12 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) { parser.start(lex.Tokenize(test.input)) addr := obj.Addr{} parser.operand(&addr) - result := obj.Dconv(&emptyProg, &addr) + var result string + if parser.compilingRuntime { + result = obj.DconvWithABIDetail(&emptyProg, &addr) + } else { + result = obj.Dconv(&emptyProg, &addr) + } if result != test.output { t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output) } @@ -86,6 +91,9 @@ func TestAMD64OperandParser(t *testing.T) { parser := newParser("amd64") testOperandParser(t, parser, amd64OperandTests) testBadOperandParser(t, parser, amd64BadOperandTests) + parser.compilingRuntime = true + testOperandParser(t, parser, amd64RuntimeOperandTests) + testBadOperandParser(t, parser, amd64BadOperandRuntimeTests) } func Test386OperandParser(t *testing.T) { @@ -141,7 +149,7 @@ func TestFuncAddress(t *testing.T) { parser := newParser(sub.arch) for _, test := range sub.tests { parser.start(lex.Tokenize(test.input)) - name, ok := parser.funcAddress() + name, _, ok := parser.funcAddress() isFuncSym := strings.HasSuffix(test.input, "(SB)") && // Ignore static symbols. @@ -298,6 +306,11 @@ var amd64OperandTests = []operandTest{ {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } +var amd64RuntimeOperandTests = []operandTest{ + {"$bar<ABI0>(SB)", "$bar<ABI0>(SB)"}, + {"$foo<ABIInternal>(SB)", "$foo<ABIInternal>(SB)"}, +} + var amd64BadOperandTests = []badOperandTest{ {"[", "register list: expected ']', found EOF"}, {"[4", "register list: bad low register in `[4`"}, @@ -311,6 +324,11 @@ var amd64BadOperandTests = []badOperandTest{ {"[X0-X1-X2]", "register list: expected ']' after `[X0-X1`, found '-'"}, {"[X0,X3]", "register list: expected '-' after `[X0`, found ','"}, {"[X0,X1,X2,X3]", "register list: expected '-' after `[X0`, found ','"}, + {"$foo<ABI0>", "ABI selector only permitted when compiling runtime, reference was to \"foo\""}, +} + +var amd64BadOperandRuntimeTests = []badOperandTest{ + {"$foo<bletch>", "malformed ABI selector \"bletch\" in reference to \"foo\""}, } var x86OperandTests = []operandTest{ diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 17d40ee415..154cf9c7a7 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -25,24 +25,26 @@ import ( ) type Parser struct { - lex lex.TokenReader - lineNum int // Line number in source file. - errorLine int // Line number of last error. - errorCount int // Number of errors. - pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA. - input []lex.Token - inputPos int - pendingLabels []string // Labels to attach to next instruction. - labels map[string]*obj.Prog - toPatch []Patch - addr []obj.Addr - arch *arch.Arch - ctxt *obj.Link - firstProg *obj.Prog - lastProg *obj.Prog - dataAddr map[string]int64 // Most recent address for DATA for this symbol. - isJump bool // Instruction being assembled is a jump. - errorWriter io.Writer + lex lex.TokenReader + lineNum int // Line number in source file. + errorLine int // Line number of last error. + errorCount int // Number of errors. + sawCode bool // saw code in this file (as opposed to comments and blank lines) + pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA. + input []lex.Token + inputPos int + pendingLabels []string // Labels to attach to next instruction. + labels map[string]*obj.Prog + toPatch []Patch + addr []obj.Addr + arch *arch.Arch + ctxt *obj.Link + firstProg *obj.Prog + lastProg *obj.Prog + dataAddr map[string]int64 // Most recent address for DATA for this symbol. + isJump bool // Instruction being assembled is a jump. + compilingRuntime bool + errorWriter io.Writer } type Patch struct { @@ -50,14 +52,15 @@ type Patch struct { label string } -func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser { +func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader, compilingRuntime bool) *Parser { return &Parser{ - ctxt: ctxt, - arch: ar, - lex: lexer, - labels: make(map[string]*obj.Prog), - dataAddr: make(map[string]int64), - errorWriter: os.Stderr, + ctxt: ctxt, + arch: ar, + lex: lexer, + labels: make(map[string]*obj.Prog), + dataAddr: make(map[string]int64), + errorWriter: os.Stderr, + compilingRuntime: compilingRuntime, } } @@ -132,6 +135,30 @@ func (p *Parser) ParseSymABIs(w io.Writer) bool { return p.errorCount == 0 } +// nextToken returns the next non-build-comment token from the lexer. +// It reports misplaced //go:build comments but otherwise discards them. +func (p *Parser) nextToken() lex.ScanToken { + for { + tok := p.lex.Next() + if tok == lex.BuildComment { + if p.sawCode { + p.errorf("misplaced //go:build comment") + } + continue + } + if tok != '\n' { + p.sawCode = true + } + if tok == '#' { + // A leftover wisp of a #include/#define/etc, + // to let us know that p.sawCode should be true now. + // Otherwise ignored. + continue + } + return tok + } +} + // line consumes a single assembly line from p.lex of the form // // {label:} WORD[.cond] [ arg {, arg} ] (';' | '\n') @@ -146,7 +173,7 @@ next: // Skip newlines. var tok lex.ScanToken for { - tok = p.lex.Next() + tok = p.nextToken() // We save the line number here so error messages from this instruction // are labeled with this line. Otherwise we complain after we've absorbed // the terminating newline and the line numbers are off by one in errors. @@ -179,11 +206,11 @@ next: items = make([]lex.Token, 0, 3) } for { - tok = p.lex.Next() + tok = p.nextToken() if len(operands) == 0 && len(items) == 0 { if p.arch.InFamily(sys.ARM, sys.ARM64, sys.AMD64, sys.I386) && tok == '.' { // Suffixes: ARM conditionals or x86 modifiers. - tok = p.lex.Next() + tok = p.nextToken() str := p.lex.Text() if tok != scanner.Ident { p.errorf("instruction suffix expected identifier, found %s", str) @@ -285,8 +312,8 @@ func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) { // Defines text symbol in operands[0]. if len(operands) > 0 { p.start(operands[0]) - if name, ok := p.funcAddress(); ok { - fmt.Fprintf(w, "def %s ABI0\n", name) + if name, abi, ok := p.funcAddress(); ok { + fmt.Fprintf(w, "def %s %s\n", name, abi) } } return @@ -304,8 +331,8 @@ func (p *Parser) symDefRef(w io.Writer, word string, operands [][]lex.Token) { // Search for symbol references. for _, op := range operands { p.start(op) - if name, ok := p.funcAddress(); ok { - fmt.Fprintf(w, "ref %s ABI0\n", name) + if name, abi, ok := p.funcAddress(); ok { + fmt.Fprintf(w, "ref %s %s\n", name, abi) } } } @@ -740,20 +767,19 @@ func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) { case '*': a.Type = obj.TYPE_INDIR } - // Weirdness with statics: Might now have "<>". - isStatic := false - if p.peek() == '<' { - isStatic = true - p.next() - p.get('>') - } + + // Parse optional <> (indicates a static symbol) or + // <ABIxxx> (selecting text symbol with specific ABI). + doIssueError := true + isStatic, abi := p.symRefAttrs(name, doIssueError) + if p.peek() == '+' || p.peek() == '-' { a.Offset = int64(p.expr()) } if isStatic { a.Sym = p.ctxt.LookupStatic(name) } else { - a.Sym = p.ctxt.Lookup(name) + a.Sym = p.ctxt.LookupABI(name, abi) } if p.peek() == scanner.EOF { if prefix == 0 && p.isJump { @@ -798,12 +824,60 @@ func (p *Parser) setPseudoRegister(addr *obj.Addr, reg string, isStatic bool, pr } } +// symRefAttrs parses an optional function symbol attribute clause for +// the function symbol 'name', logging an error for a malformed +// attribute clause if 'issueError' is true. The return value is a +// (boolean, ABI) pair indicating that the named symbol is either +// static or a particular ABI specification. +// +// The expected form of the attribute clause is: +// +// empty, yielding (false, obj.ABI0) +// "<>", yielding (true, obj.ABI0) +// "<ABI0>" yielding (false, obj.ABI0) +// "<ABIInternal>" yielding (false, obj.ABIInternal) +// +// Anything else beginning with "<" logs an error if issueError is +// true, otherwise returns (false, obj.ABI0). +// +func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) { + abi := obj.ABI0 + isStatic := false + if p.peek() != '<' { + return isStatic, abi + } + p.next() + tok := p.peek() + if tok == '>' { + isStatic = true + } else if tok == scanner.Ident { + abistr := p.get(scanner.Ident).String() + if !p.compilingRuntime { + if issueError { + p.errorf("ABI selector only permitted when compiling runtime, reference was to %q", name) + } + } else { + theabi, valid := obj.ParseABI(abistr) + if !valid { + if issueError { + p.errorf("malformed ABI selector %q in reference to %q", + abistr, name) + } + } else { + abi = theabi + } + } + } + p.get('>') + return isStatic, abi +} + // funcAddress parses an external function address. This is a // constrained form of the operand syntax that's always SB-based, // non-static, and has at most a simple integer offset: // -// [$|*]sym[+Int](SB) -func (p *Parser) funcAddress() (string, bool) { +// [$|*]sym[<abi>][+Int](SB) +func (p *Parser) funcAddress() (string, obj.ABI, bool) { switch p.peek() { case '$', '*': // Skip prefix. @@ -813,25 +887,32 @@ func (p *Parser) funcAddress() (string, bool) { tok := p.next() name := tok.String() if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) { - return "", false + return "", obj.ABI0, false + } + // Parse optional <> (indicates a static symbol) or + // <ABIxxx> (selecting text symbol with specific ABI). + noErrMsg := false + isStatic, abi := p.symRefAttrs(name, noErrMsg) + if isStatic { + return "", obj.ABI0, false // This function rejects static symbols. } tok = p.next() if tok.ScanToken == '+' { if p.next().ScanToken != scanner.Int { - return "", false + return "", obj.ABI0, false } tok = p.next() } if tok.ScanToken != '(' { - return "", false + return "", obj.ABI0, false } if reg := p.next(); reg.ScanToken != scanner.Ident || reg.String() != "SB" { - return "", false + return "", obj.ABI0, false } if p.next().ScanToken != ')' || p.peek() != scanner.EOF { - return "", false + return "", obj.ABI0, false } - return name, true + return name, abi, true } // registerIndirect parses the general form of a register indirection. diff --git a/src/cmd/asm/internal/asm/pseudo_test.go b/src/cmd/asm/internal/asm/pseudo_test.go index 100bef91cf..622ee25ce7 100644 --- a/src/cmd/asm/internal/asm/pseudo_test.go +++ b/src/cmd/asm/internal/asm/pseudo_test.go @@ -37,6 +37,7 @@ func TestErroneous(t *testing.T) { {"TEXT", "$0É:0, 0, $1", "expected end of operand, found É"}, // Issue #12467. {"TEXT", "$:0:(SB, 0, $1", "expected '(', found 0"}, // Issue 12468. {"TEXT", "@B(SB),0,$0", "expected '(', found B"}, // Issue 23580. + {"TEXT", "foo<ABIInternal>(SB),0", "ABI selector only permitted when compiling runtime, reference was to \"foo\""}, {"FUNCDATA", "", "expect two operands for FUNCDATA"}, {"FUNCDATA", "(SB ", "expect two operands for FUNCDATA"}, {"DATA", "", "expect two operands for DATA"}, diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index f0c716a2b5..91e3a0ca0a 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -10,14 +10,8 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 -// -// ADD -// -// LTYPE1 imsr ',' spreg ',' reg -// { -// outcode($1, &$2, $4, &$6); -// } -// imsr comes from the old 7a, we only support immediates and registers + +// arithmetic operations ADDW $1, R2, R3 ADDW R1, R2, R3 ADDW R1, ZR, R3 @@ -25,18 +19,29 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 ADD R1, R2, R3 ADD R1, ZR, R3 ADD $1, R2, R3 - ADD $0x000aaa, R2, R3 // ADD $2730, R2, R3 // 43a82a91 - ADD $0x000aaa, R2 // ADD $2730, R2 // 42a82a91 - ADD $0xaaa000, R2, R3 // ADD $11182080, R2, R3 // 43a86a91 - ADD $0xaaa000, R2 // ADD $11182080, R2 // 42a86a91 - ADD $0xaaaaaa, R2, R3 // ADD $11184810, R2, R3 // 43a82a9163a86a91 - ADD $0xaaaaaa, R2 // ADD $11184810, R2 // 42a82a9142a86a91 - SUB $0x000aaa, R2, R3 // SUB $2730, R2, R3 // 43a82ad1 - SUB $0x000aaa, R2 // SUB $2730, R2 // 42a82ad1 - SUB $0xaaa000, R2, R3 // SUB $11182080, R2, R3 // 43a86ad1 - SUB $0xaaa000, R2 // SUB $11182080, R2 // 42a86ad1 - SUB $0xaaaaaa, R2, R3 // SUB $11184810, R2, R3 // 43a82ad163a86ad1 - SUB $0xaaaaaa, R2 // SUB $11184810, R2 // 42a82ad142a86ad1 + ADDW $1, R2 + ADDW R1, R2 + ADD $1, R2 + ADD R1, R2 + ADD R1>>11, R2 + ADD R1<<22, R2 + ADD R1->33, R2 + ADD $0x000aaa, R2, R3 // ADD $2730, R2, R3 // 43a82a91 + ADD $0x000aaa, R2 // ADD $2730, R2 // 42a82a91 + ADD $0xaaa000, R2, R3 // ADD $11182080, R2, R3 // 43a86a91 + ADD $0xaaa000, R2 // ADD $11182080, R2 // 42a86a91 + ADD $0xaaaaaa, R2, R3 // ADD $11184810, R2, R3 // 43a82a9163a86a91 + ADD $0xaaaaaa, R2 // ADD $11184810, R2 // 42a82a9142a86a91 + SUB $0x000aaa, R2, R3 // SUB $2730, R2, R3 // 43a82ad1 + SUB $0x000aaa, R2 // SUB $2730, R2 // 42a82ad1 + SUB $0xaaa000, R2, R3 // SUB $11182080, R2, R3 // 43a86ad1 + SUB $0xaaa000, R2 // SUB $11182080, R2 // 42a86ad1 + SUB $0xaaaaaa, R2, R3 // SUB $11184810, R2, R3 // 43a82ad163a86ad1 + SUB $0xaaaaaa, R2 // SUB $11184810, R2 // 42a82ad142a86ad1 + ADDW $0x60060, R2 // ADDW $393312, R2 // 4280011142804111 + ADD $0x186a0, R2, R5 // ADD $100000, R2, R5 // 45801a91a5604091 + SUB $0xe7791f700, R3, R1 // SUB $62135596800, R3, R1 // 1be09ed23bf2aef2db01c0f261001bcb + ADD $0x3fffffffc000, R5 // ADD $70368744161280, R5 // fb7f72b2a5001b8b ADD R1>>11, R2, R3 ADD R1<<22, R2, R3 ADD R1->33, R2, R3 @@ -59,6 +64,30 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 CMN R1.SXTX<<2, R10 // 5fe921ab CMPW R2.UXTH<<3, R11 // 7f2d226b CMNW R1.SXTB, R9 // 3f81212b + CMPW $0x60060, R2 // CMPW $393312, R2 // 1b0c8052db00a0725f001b6b + CMPW $40960, R0 // 1f284071 + CMPW $27745, R2 // 3b8c8d525f001b6b + CMNW $0x3fffffc0, R2 // CMNW $1073741760, R2 // fb5f1a325f001b2b + CMPW $0xffff0, R1 // CMPW $1048560, R1 // fb3f1c323f001b6b + CMP $0xffffffffffa0, R3 // CMP $281474976710560, R3 // fb0b80921b00e0f27f001beb + CMP $0xf4240, R1 // CMP $1000000, R1 // 1b4888d2fb01a0f23f001beb + CMP $3343198598084851058, R3 // 5bae8ed2db8daef23badcdf2bbcce5f27f001beb + CMP $3, R2 + CMP R1, R2 + CMP R1->11, R2 + CMP R1>>22, R2 + CMP R1<<33, R2 + CMP R22.SXTX, RSP // ffe336eb + CMP $0x22220000, RSP // CMP $572653568, RSP // 5b44a4d2ff633beb + CMPW $0x22220000, RSP // CMPW $572653568, RSP // 5b44a452ff633b6b + CCMN MI, ZR, R1, $4 // e44341ba + // MADD Rn,Rm,Ra,Rd + MADD R1, R2, R3, R4 // 6408019b + // CLS + CLSW R1, R2 + CLS R1, R2 + +// fp/simd instructions. VADDP V1.B16, V2.B16, V3.B16 // 43bc214e VADDP V1.S4, V2.S4, V3.S4 // 43bca14e VADDP V1.D2, V2.D2, V3.D2 // 43bce14e @@ -67,20 +96,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VORR V5.B16, V4.B16, V3.B16 // 831ca54e VADD V16.S4, V5.S4, V9.S4 // a984b04e VEOR V0.B16, V1.B16, V0.B16 // 201c206e - SHA256H V9.S4, V3, V2 // 6240095e - SHA256H2 V9.S4, V4, V3 // 8350095e - SHA256SU0 V8.S4, V7.S4 // 0729285e - SHA256SU1 V6.S4, V5.S4, V7.S4 // a760065e - SHA1SU0 V11.S4, V8.S4, V6.S4 // 06310b5e - SHA1SU1 V5.S4, V1.S4 // a118285e - SHA1C V1.S4, V2, V3 // 4300015e - SHA1H V5, V4 // a408285e - SHA1M V8.S4, V7, V6 // e620085e - SHA1P V11.S4, V10, V9 // 49110b5e - SHA512H V2.D2, V1, V0 // 208062ce - SHA512H2 V4.D2, V3, V2 // 628464ce - SHA512SU0 V9.D2, V8.D2 // 2881c0ce - SHA512SU1 V7.D2, V6.D2, V5.D2 // c58867ce VADDV V0.S4, V0 // 00b8b14e VMOVI $82, V0.B16 // 40e6024f VUADDLV V6.B16, V6 // c638306e @@ -94,10 +109,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VFMLS V1.D2, V12.D2, V1.D2 // 81cde14e VFMLS V1.S2, V12.S2, V1.S2 // 81cda10e VFMLS V1.S4, V12.S4, V1.S4 // 81cda14e - VPMULL V2.D1, V1.D1, V3.Q1 // 23e0e20e - VPMULL2 V2.D2, V1.D2, V4.Q1 // 24e0e24e - VPMULL V2.B8, V1.B8, V3.H8 // 23e0220e - VPMULL2 V2.B16, V1.B16, V4.H8 // 24e0224e VEXT $4, V2.B8, V1.B8, V3.B8 // 2320022e VEXT $8, V2.B16, V1.B16, V3.B16 // 2340026e VRBIT V24.B16, V24.B16 // 185b606e @@ -123,6 +134,14 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VSRI $8, V1.H8, V2.H8 // 2244186f VSRI $2, V1.B8, V2.B8 // 22440e2f VSRI $2, V1.B16, V2.B16 // 22440e6f + VSLI $7, V2.B16, V3.B16 // 43540f6f + VSLI $15, V3.H4, V4.H4 // 64541f2f + VSLI $31, V5.S4, V6.S4 // a6543f6f + VSLI $63, V7.D2, V8.D2 // e8547f6f + VUSRA $8, V2.B16, V3.B16 // 4314086f + VUSRA $16, V3.H4, V4.H4 // 6414102f + VUSRA $32, V5.S4, V6.S4 // a614206f + VUSRA $64, V7.D2, V8.D2 // e814406f VTBL V22.B16, [V28.B16, V29.B16], V11.B16 // 8b23164e VTBL V18.B8, [V17.B16, V18.B16, V19.B16], V22.B8 // 3642120e VTBL V31.B8, [V14.B16, V15.B16, V16.B16, V17.B16], V15.B8 // cf611f0e @@ -145,108 +164,126 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VZIP2 V10.D2, V13.D2, V3.D2 // a379ca4e VZIP1 V17.S2, V4.S2, V26.S2 // 9a38910e VZIP2 V25.S2, V14.S2, V25.S2 // d979990e - MOVD (R2)(R6.SXTW), R4 // 44c866f8 - MOVD (R3)(R6), R5 // MOVD (R3)(R6*1), R5 // 656866f8 - MOVD (R2)(R6), R4 // MOVD (R2)(R6*1), R4 // 446866f8 - MOVWU (R19)(R20<<2), R20 // 747a74b8 - MOVD (R2)(R6<<3), R4 // 447866f8 - MOVD (R3)(R7.SXTX<<3), R8 // 68f867f8 - MOVWU (R5)(R4.UXTW), R10 // aa4864b8 - MOVBU (R3)(R9.UXTW), R8 // 68486938 - MOVBU (R5)(R8), R10 // MOVBU (R5)(R8*1), R10 // aa686838 - MOVHU (R2)(R7.SXTW<<1), R11 // 4bd86778 - MOVHU (R1)(R2<<1), R5 // 25786278 - MOVB (R9)(R3.UXTW), R6 // 2649a338 - MOVB (R10)(R6), R15 // MOVB (R10)(R6*1), R15 // 4f69a638 - MOVH (R5)(R7.SXTX<<1), R19 // b3f8a778 - MOVH (R8)(R4<<1), R10 // 0a79a478 - MOVW (R9)(R8.SXTW<<2), R19 // 33d9a8b8 - MOVW (R1)(R4.SXTX), R11 // 2be8a4b8 - MOVW (R1)(R4.SXTX), ZR // 3fe8a4b8 - MOVW (R2)(R5), R12 // MOVW (R2)(R5*1), R12 // 4c68a5b8 - MOVD R5, (R2)(R6<<3) // 457826f8 - MOVD R9, (R6)(R7.SXTX<<3) // c9f827f8 - MOVD ZR, (R6)(R7.SXTX<<3) // dff827f8 - MOVW R8, (R2)(R3.UXTW<<2) // 485823b8 - MOVW R7, (R3)(R4.SXTW) // 67c824b8 - MOVB R4, (R2)(R6.SXTX) // 44e82638 - MOVB R8, (R3)(R9.UXTW) // 68482938 - MOVB R10, (R5)(R8) // MOVB R10, (R5)(R8*1) // aa682838 - MOVH R11, (R2)(R7.SXTW<<1) // 4bd82778 - MOVH R5, (R1)(R2<<1) // 25782278 - MOVH R7, (R2)(R5.SXTX<<1) // 47f82578 - MOVH R8, (R3)(R6.UXTW) // 68482678 - MOVB (R29)(R30<<0), R14 // ae7bbe38 - MOVB (R29)(R30), R14 // MOVB (R29)(R30*1), R14 // ae6bbe38 - MOVB R4, (R2)(R6.SXTX) // 44e82638 + VUXTL V30.B8, V30.H8 // dea7082f + VUXTL V30.H4, V29.S4 // dda7102f + VUXTL V29.S2, V2.D2 // a2a7202f + VUXTL2 V30.H8, V30.S4 // dea7106f + VUXTL2 V29.S4, V2.D2 // a2a7206f + VUXTL2 V30.B16, V2.H8 // c2a7086f + VBIT V21.B16, V25.B16, V4.B16 // 241fb56e + VBSL V23.B16, V3.B16, V7.B16 // 671c776e + VCMTST V2.B8, V29.B8, V2.B8 // a28f220e + VCMTST V2.D2, V23.D2, V3.D2 // e38ee24e + VSUB V2.B8, V30.B8, V30.B8 // de87222e + VUZP1 V0.B8, V30.B8, V1.B8 // c11b000e + VUZP1 V1.B16, V29.B16, V2.B16 // a21b014e + VUZP1 V2.H4, V28.H4, V3.H4 // 831b420e + VUZP1 V3.H8, V27.H8, V4.H8 // 641b434e + VUZP1 V28.S2, V2.S2, V5.S2 // 45189c0e + VUZP1 V29.S4, V1.S4, V6.S4 // 26189d4e + VUZP1 V30.D2, V0.D2, V7.D2 // 0718de4e + VUZP2 V0.D2, V30.D2, V1.D2 // c15bc04e + VUZP2 V30.D2, V0.D2, V29.D2 // 1d58de4e + VUSHLL $0, V30.B8, V30.H8 // dea7082f + VUSHLL $0, V30.H4, V29.S4 // dda7102f + VUSHLL $0, V29.S2, V2.D2 // a2a7202f + VUSHLL2 $0, V30.B16, V2.H8 // c2a7086f + VUSHLL2 $0, V30.H8, V30.S4 // dea7106f + VUSHLL2 $0, V29.S4, V2.D2 // a2a7206f + VUSHLL $7, V30.B8, V30.H8 // dea70f2f + VUSHLL $15, V30.H4, V29.S4 // dda71f2f + VUSHLL2 $31, V30.S4, V2.D2 // c2a73f6f + VBIF V0.B8, V30.B8, V1.B8 // c11fe02e + VBIF V30.B16, V0.B16, V2.B16 // 021cfe6e FMOVS $(4.0), F0 // 0010221e FMOVD $(4.0), F0 // 0010621e FMOVS $(0.265625), F1 // 01302a1e FMOVD $(0.1796875), F2 // 02f0681e FMOVS $(0.96875), F3 // 03f02d1e FMOVD $(28.0), F4 // 0490671e + VUADDW V9.B8, V12.H8, V14.H8 // 8e11292e + VUADDW V13.H4, V10.S4, V11.S4 // 4b116d2e + VUADDW V21.S2, V24.D2, V29.D2 // 1d13b52e + VUADDW2 V9.B16, V12.H8, V14.H8 // 8e11296e + VUADDW2 V13.H8, V20.S4, V30.S4 // 9e126d6e + VUADDW2 V21.S4, V24.D2, V29.D2 // 1d13b56e + FCCMPS LT, F1, F2, $1 // 41b4211e + FMADDS F1, F3, F2, F4 // 440c011f + FMADDD F4, F5, F4, F4 // 8414441f + FMSUBS F13, F21, F13, F19 // b3d50d1f + FMSUBD F11, F7, F15, F31 // ff9d4b1f + FNMADDS F1, F3, F2, F4 // 440c211f + FNMADDD F1, F3, F2, F4 // 440c611f + FNMSUBS F1, F3, F2, F4 // 448c211f + FNMSUBD F1, F3, F2, F4 // 448c611f + FADDS F2, F3, F4 // 6428221e + FADDD F1, F2 // 4228611e + VDUP V19.S[0], V17.S4 // 7106044e - FMOVS (R2)(R6), F4 // FMOVS (R2)(R6*1), F4 // 446866bc - FMOVS (R2)(R6<<2), F4 // 447866bc - FMOVD (R2)(R6), F4 // FMOVD (R2)(R6*1), F4 // 446866fc - FMOVD (R2)(R6<<3), F4 // 447866fc - FMOVS F4, (R2)(R6) // FMOVS F4, (R2)(R6*1) // 446826bc - FMOVS F4, (R2)(R6<<2) // 447826bc - FMOVD F4, (R2)(R6) // FMOVD F4, (R2)(R6*1) // 446826fc - FMOVD F4, (R2)(R6<<3) // 447826fc - CMPW $40960, R0 // 1f284071 - CMPW $27745, R2 // 3b8c8d525f001b6b - CMNW $0x3fffffc0, R2 // CMNW $1073741760, R2 // fb5f1a325f001b2b - CMPW $0xffff0, R1 // CMPW $1048560, R1 // fb3f1c323f001b6b - CMP $0xffffffffffa0, R3 // CMP $281474976710560, R3 // fb0b80921b00e0f27f001beb - CMP $0xf4240, R1 // CMP $1000000, R1 // 1b4888d2fb01a0f23f001beb - ADD $0x186a0, R2, R5 // ADD $100000, R2, R5 // 45801a91a5604091 - SUB $0xe7791f700, R3, R1 // SUB $62135596800, R3, R1 // 1be09ed23bf2aef2db01c0f261001bcb - CMP $3343198598084851058, R3 // 5bae8ed2db8daef23badcdf2bbcce5f27f001beb - ADD $0x3fffffffc000, R5 // ADD $70368744161280, R5 // fb7f72b2a5001b8b -// LTYPE1 imsr ',' spreg ',' -// { -// outcode($1, &$2, $4, &nullgen); -// } -// LTYPE1 imsr ',' reg -// { -// outcode($1, &$2, NREG, &$4); -// } - ADDW $1, R2 - ADDW R1, R2 - ADD $1, R2 - ADD R1, R2 - ADD R1>>11, R2 - ADD R1<<22, R2 - ADD R1->33, R2 - AND R1@>33, R2 +// special + PRFM (R2), PLDL1KEEP // 400080f9 + PRFM 16(R2), PLDL1KEEP // 400880f9 + PRFM 48(R6), PSTL2STRM // d31880f9 + PRFM 8(R12), PLIL3STRM // 8d0580f9 + PRFM (R8), $25 // 190180f9 + PRFM 8(R9), $30 // 3e0580f9 + NOOP // 1f2003d5 + HINT $0 // 1f2003d5 + DMB $1 + SVC + +// encryption + SHA256H V9.S4, V3, V2 // 6240095e + SHA256H2 V9.S4, V4, V3 // 8350095e + SHA256SU0 V8.S4, V7.S4 // 0729285e + SHA256SU1 V6.S4, V5.S4, V7.S4 // a760065e + SHA1SU0 V11.S4, V8.S4, V6.S4 // 06310b5e + SHA1SU1 V5.S4, V1.S4 // a118285e + SHA1C V1.S4, V2, V3 // 4300015e + SHA1H V5, V4 // a408285e + SHA1M V8.S4, V7, V6 // e620085e + SHA1P V11.S4, V10, V9 // 49110b5e + SHA512H V2.D2, V1, V0 // 208062ce + SHA512H2 V4.D2, V3, V2 // 628464ce + SHA512SU0 V9.D2, V8.D2 // 2881c0ce + SHA512SU1 V7.D2, V6.D2, V5.D2 // c58867ce + VRAX1 V26.D2, V29.D2, V30.D2 // be8f7ace + VXAR $63, V27.D2, V21.D2, V26.D2 // bafe9bce + VPMULL V2.D1, V1.D1, V3.Q1 // 23e0e20e + VPMULL2 V2.D2, V1.D2, V4.Q1 // 24e0e24e + VPMULL V2.B8, V1.B8, V3.H8 // 23e0220e + VPMULL2 V2.B16, V1.B16, V4.H8 // 24e0224e + VEOR3 V2.B16, V7.B16, V12.B16, V25.B16 // 990907ce + VBCAX V1.B16, V2.B16, V26.B16, V31.B16 // 5f0722ce + VREV32 V5.B16, V5.B16 // a508206e + VREV64 V2.S2, V3.S2 // 4308a00e + VREV64 V2.S4, V3.S4 // 4308a04e // logical ops +// // make sure constants get encoded into an instruction when it could - AND $(1<<63), R1 // AND $-9223372036854775808, R1 // 21004192 - AND $(1<<63-1), R1 // AND $9223372036854775807, R1 // 21f84092 - ORR $(1<<63), R1 // ORR $-9223372036854775808, R1 // 210041b2 - ORR $(1<<63-1), R1 // ORR $9223372036854775807, R1 // 21f840b2 - EOR $(1<<63), R1 // EOR $-9223372036854775808, R1 // 210041d2 - EOR $(1<<63-1), R1 // EOR $9223372036854775807, R1 // 21f840d2 - - ANDW $0x3ff00000, R2 // ANDW $1072693248, R2 // 42240c12 - BICW $0x3ff00000, R2 // BICW $1072693248, R2 // 42540212 - ORRW $0x3ff00000, R2 // ORRW $1072693248, R2 // 42240c32 - ORNW $0x3ff00000, R2 // ORNW $1072693248, R2 // 42540232 - EORW $0x3ff00000, R2 // EORW $1072693248, R2 // 42240c52 - EONW $0x3ff00000, R2 // EONW $1072693248, R2 // 42540252 - - AND $0x22220000, R3, R4 // AND $572653568, R3, R4 // 5b44a4d264001b8a - ORR $0x22220000, R3, R4 // ORR $572653568, R3, R4 // 5b44a4d264001baa - EOR $0x22220000, R3, R4 // EOR $572653568, R3, R4 // 5b44a4d264001bca - BIC $0x22220000, R3, R4 // BIC $572653568, R3, R4 // 5b44a4d264003b8a - ORN $0x22220000, R3, R4 // ORN $572653568, R3, R4 // 5b44a4d264003baa - EON $0x22220000, R3, R4 // EON $572653568, R3, R4 // 5b44a4d264003bca - ANDS $0x22220000, R3, R4 // ANDS $572653568, R3, R4 // 5b44a4d264001bea - BICS $0x22220000, R3, R4 // BICS $572653568, R3, R4 // 5b44a4d264003bea - + AND R1@>33, R2 + AND $(1<<63), R1 // AND $-9223372036854775808, R1 // 21004192 + AND $(1<<63-1), R1 // AND $9223372036854775807, R1 // 21f84092 + ORR $(1<<63), R1 // ORR $-9223372036854775808, R1 // 210041b2 + ORR $(1<<63-1), R1 // ORR $9223372036854775807, R1 // 21f840b2 + EOR $(1<<63), R1 // EOR $-9223372036854775808, R1 // 210041d2 + EOR $(1<<63-1), R1 // EOR $9223372036854775807, R1 // 21f840d2 + ANDW $0x3ff00000, R2 // ANDW $1072693248, R2 // 42240c12 + BICW $0x3ff00000, R2 // BICW $1072693248, R2 // 42540212 + ORRW $0x3ff00000, R2 // ORRW $1072693248, R2 // 42240c32 + ORNW $0x3ff00000, R2 // ORNW $1072693248, R2 // 42540232 + EORW $0x3ff00000, R2 // EORW $1072693248, R2 // 42240c52 + EONW $0x3ff00000, R2 // EONW $1072693248, R2 // 42540252 + AND $0x22220000, R3, R4 // AND $572653568, R3, R4 // 5b44a4d264001b8a + ORR $0x22220000, R3, R4 // ORR $572653568, R3, R4 // 5b44a4d264001baa + EOR $0x22220000, R3, R4 // EOR $572653568, R3, R4 // 5b44a4d264001bca + BIC $0x22220000, R3, R4 // BIC $572653568, R3, R4 // 5b44a4d264003b8a + ORN $0x22220000, R3, R4 // ORN $572653568, R3, R4 // 5b44a4d264003baa + EON $0x22220000, R3, R4 // EON $572653568, R3, R4 // 5b44a4d264003bca + ANDS $0x22220000, R3, R4 // ANDS $572653568, R3, R4 // 5b44a4d264001bea + BICS $0x22220000, R3, R4 // BICS $572653568, R3, R4 // 5b44a4d264003bea EOR $0xe03fffffffffffff, R20, R22 // EOR $-2287828610704211969, R20, R22 // 96e243d2 TSTW $0x600000006, R1 // TSTW $25769803782, R1 // 3f041f72 TST $0x4900000049, R0 // TST $313532612681, R0 // 3b0980d23b09c0f21f001bea @@ -275,19 +312,22 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 EONW $0x6006000060060, R5 // EONW $1689262177517664, R5 // 1b0c8052db00a072a5003b4a ORNW $0x6006000060060, R5 // ORNW $1689262177517664, R5 // 1b0c8052db00a072a5003b2a BICSW $0x6006000060060, R5 // BICSW $1689262177517664, R5 // 1b0c8052db00a072a5003b6a - ADDW $0x60060, R2 // ADDW $393312, R2 // 4280011142804111 - CMPW $0x60060, R2 // CMPW $393312, R2 // 1b0c8052db00a0725f001b6b - // TODO: this could have better encoding - ANDW $-1, R10 // 1b0080124a011b0a - - AND $8, R0, RSP // 1f007d92 - ORR $8, R0, RSP // 1f007db2 - EOR $8, R0, RSP // 1f007dd2 - BIC $8, R0, RSP // 1ff87c92 - ORN $8, R0, RSP // 1ff87cb2 - EON $8, R0, RSP // 1ff87cd2 + ANDW $-1, R10 // 1b0080124a011b0a + AND $8, R0, RSP // 1f007d92 + ORR $8, R0, RSP // 1f007db2 + EOR $8, R0, RSP // 1f007dd2 + BIC $8, R0, RSP // 1ff87c92 + ORN $8, R0, RSP // 1ff87cb2 + EON $8, R0, RSP // 1ff87cd2 + TST $15, R2 // 5f0c40f2 + TST R1, R2 // 5f0001ea + TST R1->11, R2 // 5f2c81ea + TST R1>>22, R2 // 5f5841ea + TST R1<<33, R2 // 5f8401ea + TST $0x22220000, R3 // TST $572653568, R3 // 5b44a4d27f001bea +// move an immediate to a Rn. MOVD $0x3fffffffc000, R0 // MOVD $70368744161280, R0 // e07f72b2 MOVW $1000000, R4 // 04488852e401a072 MOVW $0xaaaa0000, R1 // MOVW $2863267840, R1 // 4155b552 @@ -305,37 +345,39 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 MOVD $0x1111ffff1111aaaa, R1 // MOVD $1230045644216969898, R1 // a1aa8a922122a2f22122e2f2 MOVD $0, R1 // 010080d2 MOVD $-1, R1 // 01008092 - MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2 - MOVD $0xffffffffffffaaaa, R1 // MOVD $-21846, R1 // a1aa8a92 + MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2 + MOVD $0xffffffffffffaaaa, R1 // MOVD $-21846, R1 // a1aa8a92 + MOVW $1, ZR + MOVW $1, R1 + MOVD $1, ZR + MOVD $1, R1 + MOVK $1, R1 -// -// CLS -// -// LTYPE2 imsr ',' reg -// { -// outcode($1, &$2, NREG, &$4); -// } - CLSW R1, R2 - CLS R1, R2 +// move a large constant to a Vd. + VMOVS $0x80402010, V11 // VMOVS $2151686160, V11 + VMOVD $0x8040201008040201, V20 // VMOVD $-9205322385119247871, V20 + VMOVQ $0x7040201008040201, $0x8040201008040201, V10 // VMOVQ $8088500183983456769, $-9205322385119247871, V10 + VMOVQ $0x8040201008040202, $0x7040201008040201, V20 // VMOVQ $-9205322385119247870, $8088500183983456769, V20 -// -// MOV -// -// LTYPE3 addr ',' addr -// { -// outcode($1, &$2, NREG, &$4); -// } +// mov(to/from sp) + MOVD $0x1002(RSP), R1 // MOVD $4098(RSP), R1 // fb074091610b0091 + MOVD $0x1708(RSP), RSP // MOVD $5896(RSP), RSP // fb0740917f231c91 + MOVD $0x2001(R7), R1 // MOVD $8193(R7), R1 // fb08409161070091 + MOVD $0xffffff(R7), R1 // MOVD $16777215(R7), R1 // fbfc7f9161ff3f91 + MOVD $-0x1(R7), R1 // MOVD $-1(R7), R1 // e10400d1 + MOVD $-0x30(R7), R1 // MOVD $-48(R7), R1 // e1c000d1 + MOVD $-0x708(R7), R1 // MOVD $-1800(R7), R1 // e1201cd1 + MOVD $-0x2000(RSP), R1 // MOVD $-8192(RSP), R1 // e10b40d1 + MOVD $-0x10000(RSP), RSP // MOVD $-65536(RSP), RSP // ff4340d1 MOVW R1, R2 MOVW ZR, R1 MOVW R1, ZR - MOVW $1, ZR - MOVW $1, R1 - MOVW ZR, (R1) MOVD R1, R2 MOVD ZR, R1 - MOVD $1, ZR - MOVD $1, R1 - MOVD ZR, (R1) + +// store and load +// +// LD1/ST1 VLD1 (R8), [V1.B16, V2.B16] // 01a1404c VLD1.P (R3), [V31.H8, V0.H8] // 7fa4df4c VLD1.P (R8)(R20), [V21.B16, V22.B16] // VLD1.P (R8)(R20*1), [V21.B16,V22.B16] // 15a1d44c @@ -393,34 +435,21 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VST4 [V22.D2, V23.D2, V24.D2, V25.D2], (R3) // 760c004c VST4.P [V14.D2, V15.D2, V16.D2, V17.D2], 64(R15) // ee0d9f4c VST4.P [V24.B8, V25.B8, V26.B8, V27.B8], (R3)(R23) // VST4.P [V24.B8, V25.B8, V26.B8, V27.B8], (R3)(R23*1) // 7800970c - FMOVS F20, (R0) // 140000bd + +// pre/post-indexed FMOVS.P F20, 4(R0) // 144400bc FMOVS.W F20, 4(R0) // 144c00bc - FMOVS (R0), F20 // 140040bd + FMOVD.P F20, 8(R1) // 348400fc + FMOVQ.P F13, 11(R10) // 4db5803c + FMOVQ.W F15, 11(R20) // 8fbe803c + FMOVS.P 8(R0), F20 // 148440bc FMOVS.W 8(R0), F20 // 148c40bc - FMOVD F20, (R2) // 540000fd - FMOVD.P F20, 8(R1) // 348400fc FMOVD.W 8(R1), F20 // 348c40fc - PRFM (R2), PLDL1KEEP // 400080f9 - PRFM 16(R2), PLDL1KEEP // 400880f9 - PRFM 48(R6), PSTL2STRM // d31880f9 - PRFM 8(R12), PLIL3STRM // 8d0580f9 - PRFM (R8), $25 // 190180f9 - PRFM 8(R9), $30 // 3e0580f9 + FMOVQ.P 11(R10), F13 // 4db5c03c + FMOVQ.W 11(R20), F15 // 8fbec03c - // small offset fits into instructions - MOVB 1(R1), R2 // 22048039 - MOVH 1(R1), R2 // 22108078 - MOVH 2(R1), R2 // 22048079 - MOVW 1(R1), R2 // 221080b8 - MOVW 4(R1), R2 // 220480b9 - MOVD 1(R1), R2 // 221040f8 - MOVD 8(R1), R2 // 220440f9 - FMOVS 1(R1), F2 // 221040bc - FMOVS 4(R1), F2 // 220440bd - FMOVD 1(R1), F2 // 221040fc - FMOVD 8(R1), F2 // 220440fd +// small offset fits into instructions MOVB R1, 1(R2) // 41040039 MOVH R1, 1(R2) // 41100078 MOVH R1, 2(R2) // 41040079 @@ -428,18 +457,37 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 MOVW R1, 4(R2) // 410400b9 MOVD R1, 1(R2) // 411000f8 MOVD R1, 8(R2) // 410400f9 + MOVD ZR, (R1) + MOVW ZR, (R1) FMOVS F1, 1(R2) // 411000bc FMOVS F1, 4(R2) // 410400bd + FMOVS F20, (R0) // 140000bd FMOVD F1, 1(R2) // 411000fc FMOVD F1, 8(R2) // 410400fd + FMOVD F20, (R2) // 540000fd + FMOVQ F0, 32(R5)// a008803d + FMOVQ F10, 65520(R10) // 4afdbf3d + FMOVQ F11, 64(RSP) // eb13803d + FMOVQ F11, 8(R20) // 8b82803c + FMOVQ F11, 4(R20) // 8b42803c - // large aligned offset, use two instructions - MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039 - MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079 - MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9 - MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9 - FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd - FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd + MOVB 1(R1), R2 // 22048039 + MOVH 1(R1), R2 // 22108078 + MOVH 2(R1), R2 // 22048079 + MOVW 1(R1), R2 // 221080b8 + MOVW 4(R1), R2 // 220480b9 + MOVD 1(R1), R2 // 221040f8 + MOVD 8(R1), R2 // 220440f9 + FMOVS (R0), F20 // 140040bd + FMOVS 1(R1), F2 // 221040bc + FMOVS 4(R1), F2 // 220440bd + FMOVD 1(R1), F2 // 221040fc + FMOVD 8(R1), F2 // 220440fd + FMOVQ 32(R5), F2 // a208c03d + FMOVQ 65520(R10), F10 // 4afdff3d + FMOVQ 64(RSP), F11 // eb13c03d + +// large aligned offset, use two instructions(add+ldr/store). MOVB R1, 0x1001(R2) // MOVB R1, 4097(R2) // 5b04409161070039 MOVH R1, 0x2002(R2) // MOVH R1, 8194(R2) // 5b08409161070079 MOVW R1, 0x4004(R2) // MOVW R1, 16388(R2) // 5b104091610700b9 @@ -447,15 +495,16 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 FMOVS F1, 0x4004(R2) // FMOVS F1, 16388(R2) // 5b104091610700bd FMOVD F1, 0x8008(R2) // FMOVD F1, 32776(R2) // 5b204091610700fd - // very large or unaligned offset uses constant pool - // the encoding cannot be checked as the address of the constant pool is unknown. - // here we only test that they can be assembled. - MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2 - MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2 - MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2 - MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2 - FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2 - FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2 + MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039 + MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079 + MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9 + MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9 + FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd + FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd + +// very large or unaligned offset uses constant pool. +// the encoding cannot be checked as the address of the constant pool is unknown. +// here we only test that they can be assembled. MOVB R1, 0x44332211(R2) // MOVB R1, 1144201745(R2) MOVH R1, 0x44332211(R2) // MOVH R1, 1144201745(R2) MOVW R1, 0x44332211(R2) // MOVW R1, 1144201745(R2) @@ -463,14 +512,59 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2) FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2) -// -// MOVK -// -// LMOVK imm ',' reg -// { -// outcode($1, &$2, NREG, &$4); -// } - MOVK $1, R1 + MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2 + MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2 + MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2 + MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2 + FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2 + FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2 + +// shifted or extended register offset. + MOVD (R2)(R6.SXTW), R4 // 44c866f8 + MOVD (R3)(R6), R5 // MOVD (R3)(R6*1), R5 // 656866f8 + MOVD (R2)(R6), R4 // MOVD (R2)(R6*1), R4 // 446866f8 + MOVWU (R19)(R20<<2), R20 // 747a74b8 + MOVD (R2)(R6<<3), R4 // 447866f8 + MOVD (R3)(R7.SXTX<<3), R8 // 68f867f8 + MOVWU (R5)(R4.UXTW), R10 // aa4864b8 + MOVBU (R3)(R9.UXTW), R8 // 68486938 + MOVBU (R5)(R8), R10 // MOVBU (R5)(R8*1), R10 // aa686838 + MOVHU (R2)(R7.SXTW<<1), R11 // 4bd86778 + MOVHU (R1)(R2<<1), R5 // 25786278 + MOVB (R9)(R3.UXTW), R6 // 2649a338 + MOVB (R10)(R6), R15 // MOVB (R10)(R6*1), R15 // 4f69a638 + MOVB (R29)(R30<<0), R14 // ae7bbe38 + MOVB (R29)(R30), R14 // MOVB (R29)(R30*1), R14 // ae6bbe38 + MOVH (R5)(R7.SXTX<<1), R19 // b3f8a778 + MOVH (R8)(R4<<1), R10 // 0a79a478 + MOVW (R9)(R8.SXTW<<2), R19 // 33d9a8b8 + MOVW (R1)(R4.SXTX), R11 // 2be8a4b8 + MOVW (R1)(R4.SXTX), ZR // 3fe8a4b8 + MOVW (R2)(R5), R12 // MOVW (R2)(R5*1), R12 // 4c68a5b8 + FMOVS (R2)(R6), F4 // FMOVS (R2)(R6*1), F4 // 446866bc + FMOVS (R2)(R6<<2), F4 // 447866bc + FMOVD (R2)(R6), F4 // FMOVD (R2)(R6*1), F4 // 446866fc + FMOVD (R2)(R6<<3), F4 // 447866fc + + MOVD R5, (R2)(R6<<3) // 457826f8 + MOVD R9, (R6)(R7.SXTX<<3) // c9f827f8 + MOVD ZR, (R6)(R7.SXTX<<3) // dff827f8 + MOVW R8, (R2)(R3.UXTW<<2) // 485823b8 + MOVW R7, (R3)(R4.SXTW) // 67c824b8 + MOVB R4, (R2)(R6.SXTX) // 44e82638 + MOVB R8, (R3)(R9.UXTW) // 68482938 + MOVB R10, (R5)(R8) // MOVB R10, (R5)(R8*1) // aa682838 + MOVH R11, (R2)(R7.SXTW<<1) // 4bd82778 + MOVH R5, (R1)(R2<<1) // 25782278 + MOVH R7, (R2)(R5.SXTX<<1) // 47f82578 + MOVH R8, (R3)(R6.UXTW) // 68482678 + MOVB R4, (R2)(R6.SXTX) // 44e82638 + FMOVS F4, (R2)(R6) // FMOVS F4, (R2)(R6*1) // 446826bc + FMOVS F4, (R2)(R6<<2) // 447826bc + FMOVD F4, (R2)(R6) // FMOVD F4, (R2)(R6*1) // 446826fc + FMOVD F4, (R2)(R6<<3) // 447826fc + +// vmov VMOV V8.S[1], R1 // 013d0c0e VMOV V0.D[0], R11 // 0b3c084e VMOV V0.D[1], R11 // 0b3c184e @@ -485,205 +579,28 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 VMOV V9.H[0], V12.H[1] // 2c05066e VMOV V8.B[0], V12.B[1] // 0c05036e VMOV V8.B[7], V4.B[8] // 043d116e - VREV32 V5.B16, V5.B16 // a508206e - VREV64 V2.S2, V3.S2 // 4308a00e - VREV64 V2.S4, V3.S4 // 4308a04e - VDUP V19.S[0], V17.S4 // 7106044e -// -// B/BL -// -// LTYPE4 comma rel -// { -// outcode($1, &nullgen, NREG, &$3); -// } - BL 1(PC) // CALL 1(PC) - -// LTYPE4 comma nireg -// { -// outcode($1, &nullgen, NREG, &$3); -// } - BL (R2) // CALL (R2) - BL foo(SB) // CALL foo(SB) - BL bar<>(SB) // CALL bar<>(SB) -// -// BEQ -// -// LTYPE5 comma rel -// { -// outcode($1, &nullgen, NREG, &$3); -// } - BEQ 1(PC) -// -// SVC -// -// LTYPE6 -// { -// outcode($1, &nullgen, NREG, &nullgen); -// } - SVC - -// -// CMP -// -// LTYPE7 imsr ',' spreg comma -// { -// outcode($1, &$2, $4, &nullgen); -// } - CMP $3, R2 - CMP R1, R2 - CMP R1->11, R2 - CMP R1>>22, R2 - CMP R1<<33, R2 - CMP R22.SXTX, RSP // ffe336eb - - CMP $0x22220000, RSP // CMP $572653568, RSP // 5b44a4d2ff633beb - CMPW $0x22220000, RSP // CMPW $572653568, RSP // 5b44a452ff633b6b - -// TST - TST $15, R2 // 5f0c40f2 - TST R1, R2 // 5f0001ea - TST R1->11, R2 // 5f2c81ea - TST R1>>22, R2 // 5f5841ea - TST R1<<33, R2 // 5f8401ea - TST $0x22220000, R3 // TST $572653568, R3 // 5b44a4d27f001bea -// // CBZ -// -// LTYPE8 reg ',' rel -// { -// outcode($1, &$2, NREG, &$4); -// } again: CBZ R1, again // CBZ R1 -// -// CSET -// -// LTYPER cond ',' reg -// { -// outcode($1, &$2, NREG, &$4); -// } - CSET GT, R1 // e1d79f9a - CSETW HI, R2 // e2979f1a -// -// CSEL/CSINC/CSNEG/CSINV -// -// LTYPES cond ',' reg ',' reg ',' reg -// { -// outgcode($1, &$2, $6.reg, &$4, &$8); -// } +// conditional operations + CSET GT, R1 // e1d79f9a + CSETW HI, R2 // e2979f1a CSEL LT, R1, R2, ZR // 3fb0829a CSELW LT, R2, R3, R4 // 44b0831a CSINC GT, R1, ZR, R3 // 23c49f9a CSNEG MI, R1, R2, R3 // 234482da CSINV CS, R1, R2, R3 // CSINV HS, R1, R2, R3 // 232082da CSINVW MI, R2, ZR, R2 // 42409f5a - -// LTYPES cond ',' reg ',' reg -// { -// outcode($1, &$2, $4.reg, &$6); -// } CINC EQ, R4, R9 // 8914849a CINCW PL, R2, ZR // 5f44821a CINV PL, R11, R22 // 76418bda CINVW LS, R7, R13 // ed80875a CNEG LS, R13, R7 // a7858dda CNEGW EQ, R8, R13 // 0d15885a -// -// CCMN -// -// LTYPEU cond ',' imsr ',' reg ',' imm comma -// { -// outgcode($1, &$2, $6.reg, &$4, &$8); -// } - CCMN MI, ZR, R1, $4 // e44341ba - -// -// FADDD -// -// LTYPEK frcon ',' freg -// { -// outcode($1, &$2, NREG, &$4); -// } -// FADDD $0.5, F1 // FADDD $(0.5), F1 - FADDD F1, F2 - -// LTYPEK frcon ',' freg ',' freg -// { -// outcode($1, &$2, $4.reg, &$6); -// } -// FADDD $0.7, F1, F2 // FADDD $(0.69999999999999996), F1, F2 - FADDD F1, F2, F3 - -// -// FCMP -// -// LTYPEL frcon ',' freg comma -// { -// outcode($1, &$2, $4.reg, &nullgen); -// } -// FCMP $0.2, F1 -// FCMP F1, F2 -// -// FCCMP -// -// LTYPEF cond ',' freg ',' freg ',' imm comma -// { -// outgcode($1, &$2, $6.reg, &$4, &$8); -// } - FCCMPS LT, F1, F2, $1 // 41b4211e - -// -// FMULA -// -// LTYPE9 freg ',' freg ',' freg ',' freg comma -// { -// outgcode($1, &$2, $4.reg, &$6, &$8); -// } -// FMULA F1, F2, F3, F4 - -// -// FCSEL -// -// LFCSEL cond ',' freg ',' freg ',' freg -// { -// outgcode($1, &$2, $6.reg, &$4, &$8); -// } -// -// MADD Rn,Rm,Ra,Rd -// -// LTYPEM reg ',' reg ',' sreg ',' reg -// { -// outgcode($1, &$2, $6, &$4, &$8); -// } -// MADD R1, R2, R3, R4 - - FMADDS F1, F3, F2, F4 // 440c011f - FMADDD F4, F5, F4, F4 // 8414441f - FMSUBS F13, F21, F13, F19 // b3d50d1f - FMSUBD F11, F7, F15, F31 // ff9d4b1f - FNMADDS F1, F3, F2, F4 // 440c211f - FNMADDD F1, F3, F2, F4 // 440c611f - FNMSUBS F1, F3, F2, F4 // 448c211f - FNMSUBD F1, F3, F2, F4 // 448c611f - -// DMB, HINT -// -// LDMB imm -// { -// outcode($1, &$2, NREG, &nullgen); -// } - DMB $1 - -// -// STXR -// -// LSTXR reg ',' addr ',' reg -// { -// outcode($1, &$2, &$4, &$6); -// } +// atomic ops LDARB (R25), R2 // 22ffdf08 LDARH (R5), R7 // a7fcdf48 LDAXPW (R10), (R20, R16) // 54c17f88 @@ -764,38 +681,38 @@ again: LDADDLH R5, (RSP), R7 // e7036578 LDADDLB R5, (R6), R7 // c7006538 LDADDLB R5, (RSP), R7 // e7036538 - LDANDAD R5, (R6), R7 // c710a5f8 - LDANDAD R5, (RSP), R7 // e713a5f8 - LDANDAW R5, (R6), R7 // c710a5b8 - LDANDAW R5, (RSP), R7 // e713a5b8 - LDANDAH R5, (R6), R7 // c710a578 - LDANDAH R5, (RSP), R7 // e713a578 - LDANDAB R5, (R6), R7 // c710a538 - LDANDAB R5, (RSP), R7 // e713a538 - LDANDALD R5, (R6), R7 // c710e5f8 - LDANDALD R5, (RSP), R7 // e713e5f8 - LDANDALW R5, (R6), R7 // c710e5b8 - LDANDALW R5, (RSP), R7 // e713e5b8 - LDANDALH R5, (R6), R7 // c710e578 - LDANDALH R5, (RSP), R7 // e713e578 - LDANDALB R5, (R6), R7 // c710e538 - LDANDALB R5, (RSP), R7 // e713e538 - LDANDD R5, (R6), R7 // c71025f8 - LDANDD R5, (RSP), R7 // e71325f8 - LDANDW R5, (R6), R7 // c71025b8 - LDANDW R5, (RSP), R7 // e71325b8 - LDANDH R5, (R6), R7 // c7102578 - LDANDH R5, (RSP), R7 // e7132578 - LDANDB R5, (R6), R7 // c7102538 - LDANDB R5, (RSP), R7 // e7132538 - LDANDLD R5, (R6), R7 // c71065f8 - LDANDLD R5, (RSP), R7 // e71365f8 - LDANDLW R5, (R6), R7 // c71065b8 - LDANDLW R5, (RSP), R7 // e71365b8 - LDANDLH R5, (R6), R7 // c7106578 - LDANDLH R5, (RSP), R7 // e7136578 - LDANDLB R5, (R6), R7 // c7106538 - LDANDLB R5, (RSP), R7 // e7136538 + LDCLRAD R5, (R6), R7 // c710a5f8 + LDCLRAD R5, (RSP), R7 // e713a5f8 + LDCLRAW R5, (R6), R7 // c710a5b8 + LDCLRAW R5, (RSP), R7 // e713a5b8 + LDCLRAH R5, (R6), R7 // c710a578 + LDCLRAH R5, (RSP), R7 // e713a578 + LDCLRAB R5, (R6), R7 // c710a538 + LDCLRAB R5, (RSP), R7 // e713a538 + LDCLRALD R5, (R6), R7 // c710e5f8 + LDCLRALD R5, (RSP), R7 // e713e5f8 + LDCLRALW R5, (R6), R7 // c710e5b8 + LDCLRALW R5, (RSP), R7 // e713e5b8 + LDCLRALH R5, (R6), R7 // c710e578 + LDCLRALH R5, (RSP), R7 // e713e578 + LDCLRALB R5, (R6), R7 // c710e538 + LDCLRALB R5, (RSP), R7 // e713e538 + LDCLRD R5, (R6), R7 // c71025f8 + LDCLRD R5, (RSP), R7 // e71325f8 + LDCLRW R5, (R6), R7 // c71025b8 + LDCLRW R5, (RSP), R7 // e71325b8 + LDCLRH R5, (R6), R7 // c7102578 + LDCLRH R5, (RSP), R7 // e7132578 + LDCLRB R5, (R6), R7 // c7102538 + LDCLRB R5, (RSP), R7 // e7132538 + LDCLRLD R5, (R6), R7 // c71065f8 + LDCLRLD R5, (RSP), R7 // e71365f8 + LDCLRLW R5, (R6), R7 // c71065b8 + LDCLRLW R5, (RSP), R7 // e71365b8 + LDCLRLH R5, (R6), R7 // c7106578 + LDCLRLH R5, (RSP), R7 // e7136578 + LDCLRLB R5, (R6), R7 // c7106538 + LDCLRLB R5, (RSP), R7 // e7136538 LDEORAD R5, (R6), R7 // c720a5f8 LDEORAD R5, (RSP), R7 // e723a5f8 LDEORAW R5, (R6), R7 // c720a5b8 @@ -860,21 +777,36 @@ again: LDORLH R5, (RSP), R7 // e7336578 LDORLB R5, (R6), R7 // c7306538 LDORLB R5, (RSP), R7 // e7336538 + CASD R1, (R2), ZR // 5f7ca1c8 + CASW R1, (RSP), ZR // ff7fa188 + CASB ZR, (R5), R3 // a37cbf08 + CASH R3, (RSP), ZR // ff7fa348 + CASW R5, (R7), R6 // e67ca588 + CASLD ZR, (RSP), R8 // e8ffbfc8 + CASLW R9, (R10), ZR // 5ffda988 + CASAD R7, (R11), R15 // 6f7de7c8 + CASAW R10, (RSP), R19 // f37fea88 + CASALD R5, (R6), R7 // c7fce5c8 + CASALD R5, (RSP), R7 // e7ffe5c8 + CASALW R5, (R6), R7 // c7fce588 + CASALW R5, (RSP), R7 // e7ffe588 + CASALH ZR, (R5), R8 // a8fcff48 + CASALB R8, (R9), ZR // 3ffde808 + CASPD (R30, ZR), (RSP), (R8, R9) // e87f3e48 + CASPW (R6, R7), (R8), (R4, R5) // 047d2608 + CASPD (R2, R3), (R2), (R8, R9) // 487c2248 + // RET -// -// LTYPEA comma -// { -// outcode($1, &nullgen, NREG, &nullgen); -// } - BEQ 2(PC) RET RET foo(SB) -// More B/BL cases, and canonical names JMP, CALL. - - BEQ 2(PC) - B foo(SB) // JMP foo(SB) - BL foo(SB) // CALL foo(SB) +// B/BL/B.cond cases, and canonical names JMP, CALL. + BL 1(PC) // CALL 1(PC) + BL (R2) // CALL (R2) + BL foo(SB) // CALL foo(SB) + BL bar<>(SB) // CALL bar<>(SB) + B foo(SB) // JMP foo(SB) + BEQ 1(PC) BEQ 2(PC) TBZ $1, R1, 2(PC) TBNZ $2, R2, 2(PC) @@ -1049,8 +981,6 @@ again: FSTPS (F3, F4), 1024(RSP) // fb0310916313002d FSTPS (F3, F4), x(SB) FSTPS (F3, F4), x+8(SB) - NOOP // 1f2003d5 - HINT $0 // 1f2003d5 // System Register MSR $1, SPSel // bf4100d5 @@ -1612,11 +1542,4 @@ again: MSR R13, ZCR_EL1 // 0d1218d5 MRS ZCR_EL1, R23 // 171238d5 MSR R17, ZCR_EL1 // 111218d5 - -// END -// -// LTYPEE comma -// { -// outcode($1, &nullgen, NREG, &nullgen); -// } END diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 9f377817a9..e579f20836 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -87,13 +87,13 @@ TEXT errors(SB),$0 VLD1.P 32(R1), [V8.S4, V9.S4, V10.S4] // ERROR "invalid post-increment offset" VLD1.P 48(R1), [V7.S4, V8.S4, V9.S4, V10.S4] // ERROR "invalid post-increment offset" VPMULL V1.D1, V2.H4, V3.Q1 // ERROR "invalid arrangement" - VPMULL V1.H4, V2.H4, V3.Q1 // ERROR "invalid arrangement" - VPMULL V1.D2, V2.D2, V3.Q1 // ERROR "invalid arrangement" - VPMULL V1.B16, V2.B16, V3.H8 // ERROR "invalid arrangement" + VPMULL V1.H4, V2.H4, V3.Q1 // ERROR "operand mismatch" + VPMULL V1.D2, V2.D2, V3.Q1 // ERROR "operand mismatch" + VPMULL V1.B16, V2.B16, V3.H8 // ERROR "operand mismatch" VPMULL2 V1.D2, V2.H4, V3.Q1 // ERROR "invalid arrangement" - VPMULL2 V1.H4, V2.H4, V3.Q1 // ERROR "invalid arrangement" - VPMULL2 V1.D1, V2.D1, V3.Q1 // ERROR "invalid arrangement" - VPMULL2 V1.B8, V2.B8, V3.H8 // ERROR "invalid arrangement" + VPMULL2 V1.H4, V2.H4, V3.Q1 // ERROR "operand mismatch" + VPMULL2 V1.D1, V2.D1, V3.Q1 // ERROR "operand mismatch" + VPMULL2 V1.B8, V2.B8, V3.H8 // ERROR "operand mismatch" VEXT $8, V1.B16, V2.B8, V2.B16 // ERROR "invalid arrangement" VEXT $8, V1.H8, V2.H8, V2.H8 // ERROR "invalid arrangement" VRBIT V1.B16, V2.B8 // ERROR "invalid arrangement" @@ -123,14 +123,14 @@ TEXT errors(SB),$0 LDADDLW R5, (R6), ZR // ERROR "illegal destination register" LDADDLH R5, (R6), ZR // ERROR "illegal destination register" LDADDLB R5, (R6), ZR // ERROR "illegal destination register" - LDANDD R5, (R6), ZR // ERROR "illegal destination register" - LDANDW R5, (R6), ZR // ERROR "illegal destination register" - LDANDH R5, (R6), ZR // ERROR "illegal destination register" - LDANDB R5, (R6), ZR // ERROR "illegal destination register" - LDANDLD R5, (R6), ZR // ERROR "illegal destination register" - LDANDLW R5, (R6), ZR // ERROR "illegal destination register" - LDANDLH R5, (R6), ZR // ERROR "illegal destination register" - LDANDLB R5, (R6), ZR // ERROR "illegal destination register" + LDCLRD R5, (R6), ZR // ERROR "illegal destination register" + LDCLRW R5, (R6), ZR // ERROR "illegal destination register" + LDCLRH R5, (R6), ZR // ERROR "illegal destination register" + LDCLRB R5, (R6), ZR // ERROR "illegal destination register" + LDCLRLD R5, (R6), ZR // ERROR "illegal destination register" + LDCLRLW R5, (R6), ZR // ERROR "illegal destination register" + LDCLRLH R5, (R6), ZR // ERROR "illegal destination register" + LDCLRLB R5, (R6), ZR // ERROR "illegal destination register" LDEORD R5, (R6), ZR // ERROR "illegal destination register" LDEORW R5, (R6), ZR // ERROR "illegal destination register" LDEORH R5, (R6), ZR // ERROR "illegal destination register" @@ -163,22 +163,22 @@ TEXT errors(SB),$0 LDADDLW R5, (R6), RSP // ERROR "illegal destination register" LDADDLH R5, (R6), RSP // ERROR "illegal destination register" LDADDLB R5, (R6), RSP // ERROR "illegal destination register" - LDANDAD R5, (R6), RSP // ERROR "illegal destination register" - LDANDAW R5, (R6), RSP // ERROR "illegal destination register" - LDANDAH R5, (R6), RSP // ERROR "illegal destination register" - LDANDAB R5, (R6), RSP // ERROR "illegal destination register" - LDANDALD R5, (R6), RSP // ERROR "illegal destination register" - LDANDALW R5, (R6), RSP // ERROR "illegal destination register" - LDANDALH R5, (R6), RSP // ERROR "illegal destination register" - LDANDALB R5, (R6), RSP // ERROR "illegal destination register" - LDANDD R5, (R6), RSP // ERROR "illegal destination register" - LDANDW R5, (R6), RSP // ERROR "illegal destination register" - LDANDH R5, (R6), RSP // ERROR "illegal destination register" - LDANDB R5, (R6), RSP // ERROR "illegal destination register" - LDANDLD R5, (R6), RSP // ERROR "illegal destination register" - LDANDLW R5, (R6), RSP // ERROR "illegal destination register" - LDANDLH R5, (R6), RSP // ERROR "illegal destination register" - LDANDLB R5, (R6), RSP // ERROR "illegal destination register" + LDCLRAD R5, (R6), RSP // ERROR "illegal destination register" + LDCLRAW R5, (R6), RSP // ERROR "illegal destination register" + LDCLRAH R5, (R6), RSP // ERROR "illegal destination register" + LDCLRAB R5, (R6), RSP // ERROR "illegal destination register" + LDCLRALD R5, (R6), RSP // ERROR "illegal destination register" + LDCLRALW R5, (R6), RSP // ERROR "illegal destination register" + LDCLRALH R5, (R6), RSP // ERROR "illegal destination register" + LDCLRALB R5, (R6), RSP // ERROR "illegal destination register" + LDCLRD R5, (R6), RSP // ERROR "illegal destination register" + LDCLRW R5, (R6), RSP // ERROR "illegal destination register" + LDCLRH R5, (R6), RSP // ERROR "illegal destination register" + LDCLRB R5, (R6), RSP // ERROR "illegal destination register" + LDCLRLD R5, (R6), RSP // ERROR "illegal destination register" + LDCLRLW R5, (R6), RSP // ERROR "illegal destination register" + LDCLRLH R5, (R6), RSP // ERROR "illegal destination register" + LDCLRLB R5, (R6), RSP // ERROR "illegal destination register" LDEORAD R5, (R6), RSP // ERROR "illegal destination register" LDEORAW R5, (R6), RSP // ERROR "illegal destination register" LDEORAH R5, (R6), RSP // ERROR "illegal destination register" @@ -340,4 +340,25 @@ TEXT errors(SB),$0 MRS PMSWINC_EL0, R3 // ERROR "system register is not readable" MRS OSLAR_EL1, R3 // ERROR "system register is not readable" VLD3R.P 24(R15), [V15.H4,V16.H4,V17.H4] // ERROR "invalid post-increment offset" + VBIT V1.H4, V12.H4, V3.H4 // ERROR "invalid arrangement" + VBSL V1.D2, V12.D2, V3.D2 // ERROR "invalid arrangement" + VUXTL V30.D2, V30.H8 // ERROR "operand mismatch" + VUXTL2 V20.B8, V21.H8 // ERROR "operand mismatch" + VUXTL V3.D2, V4.B8 // ERROR "operand mismatch" + VUZP1 V0.B8, V30.B8, V1.B16 // ERROR "operand mismatch" + VUZP2 V0.Q1, V30.Q1, V1.Q1 // ERROR "invalid arrangement" + VUSHLL $0, V30.D2, V30.H8 // ERROR "operand mismatch" + VUSHLL2 $0, V20.B8, V21.H8 // ERROR "operand mismatch" + VUSHLL $8, V30.B8, V30.H8 // ERROR "shift amount out of range" + VUSHLL2 $32, V30.S4, V2.D2 // ERROR "shift amount out of range" + VBIF V0.B8, V1.B8, V2.B16 // ERROR "operand mismatch" + 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" + VSLI $64, 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" + CASPD (R2, R3), (R2), (R8, R10) // ERROR "destination register pair must be contiguous" RET diff --git a/src/cmd/asm/internal/asm/testdata/buildtagerror.s b/src/cmd/asm/internal/asm/testdata/buildtagerror.s new file mode 100644 index 0000000000..5a2d65b978 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/buildtagerror.s @@ -0,0 +1,8 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#define X 1 + +//go:build x // ERROR "misplaced //go:build comment" + diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index ba64d84a35..8f6eb14f73 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -2,1311 +2,719 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This input was created by taking the instruction productions in -// the old assembler's (9a's) grammar and hand-writing complete -// instructions for each rule, to guarantee we cover the same space. +// This contains the majority of valid opcode combinations +// available in cmd/internal/obj/ppc64/asm9.go with +// their valid instruction encodings. #include "../../../../../runtime/textflag.h" -TEXT foo(SB),DUPOK|NOSPLIT,$0 +TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + // move constants + MOVD $1, R3 // 38600001 + MOVD $-1, R4 // 3880ffff + MOVD $65535, R5 // 6005ffff + MOVD $65536, R6 // 64060001 + MOVD $-32767, R5 // 38a08001 + MOVD $-32768, R6 // 38c08000 + MOVD $1234567, R5 // 6405001260a5d687 + MOVW $1, R3 // 38600001 + MOVW $-1, R4 // 3880ffff + MOVW $65535, R5 // 6005ffff + MOVW $65536, R6 // 64060001 + MOVW $-32767, R5 // 38a08001 + MOVW $-32768, R6 // 38c08000 + MOVW $1234567, R5 // 6405001260a5d687 + MOVD 8(R3), R4 // e8830008 + MOVD (R3)(R4), R5 // 7ca4182a + MOVW 4(R3), R4 // e8830006 + MOVW (R3)(R4), R5 // 7ca41aaa + MOVWZ 4(R3), R4 // 80830004 + MOVWZ (R3)(R4), R5 // 7ca4182e + MOVH 4(R3), R4 // a8830004 + MOVH (R3)(R4), R5 // 7ca41aae + MOVHZ 2(R3), R4 // a0830002 + MOVHZ (R3)(R4), R5 // 7ca41a2e + MOVB 1(R3), R4 // 888300017c840774 + MOVB (R3)(R4), R5 // 7ca418ae7ca50774 + MOVBZ 1(R3), R4 // 88830001 + MOVBZ (R3)(R4), R5 // 7ca418ae + MOVDBR (R3)(R4), R5 // 7ca41c28 + MOVWBR (R3)(R4), R5 // 7ca41c2c + MOVHBR (R3)(R4), R5 // 7ca41e2c -//inst: -// -// load ints and bytes -// -// LMOVW rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, R2 + MOVDU 8(R3), R4 // e8830009 + MOVDU (R3)(R4), R5 // 7ca4186a + MOVWU (R3)(R4), R5 // 7ca41aea + MOVWZU 4(R3), R4 // 84830004 + MOVWZU (R3)(R4), R5 // 7ca4186e + MOVHU 2(R3), R4 // ac830002 + MOVHU (R3)(R4), R5 // 7ca41aee + MOVHZU 2(R3), R4 // a4830002 + MOVHZU (R3)(R4), R5 // 7ca41a6e + MOVBU 1(R3), R4 // 8c8300017c840774 + MOVBU (R3)(R4), R5 // 7ca418ee7ca50774 + MOVBZU 1(R3), R4 // 8c830001 + MOVBZU (R3)(R4), R5 // 7ca418ee -// LMOVW addr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW foo<>+4(SB), R2 - MOVW 16(R1), R2 + MOVD R4, 8(R3) // f8830008 + MOVD R5, (R3)(R4) // 7ca4192a + MOVW R4, 4(R3) // 90830004 + MOVW R5, (R3)(R4) // 7ca4192e + MOVH R4, 2(R3) // b0830002 + MOVH R5, (R3)(R4) // 7ca41b2e + MOVB R4, 1(R3) // 98830001 + MOVB R5, (R3)(R4) // 7ca419ae + MOVDBR R5, (R3)(R4) // 7ca41d28 + MOVWBR R5, (R3)(R4) // 7ca41d2c + MOVHBR R5, (R3)(R4) // 7ca41f2c -// LMOVW regaddr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW (R1), R2 - MOVW (R1+R2), R3 // MOVW (R1)(R2*1), R3 + MOVDU R4, 8(R3) // f8830009 + MOVDU R5, (R3)(R4) // 7ca4196a + MOVWU R4, 4(R3) // 94830004 + MOVWU R5, (R3)(R4) // 7ca4196e + MOVHU R4, 2(R3) // b4830002 + MOVHU R5, (R3)(R4) // 7ca41b6e + MOVBU R4, 1(R3) // 9c830001 + MOVBU R5, (R3)(R4) // 7ca419ee -// LMOVB rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, R2 + ADD $1, R3 // 38630001 + ADD $1, R3, R4 // 38830001 + ADD $-1, R4 // 3884ffff + ADD $-1, R4, R5 // 38a4ffff + ADD $65535, R5 // 601fffff7cbf2a14 + ADD $65535, R5, R6 // 601fffff7cdf2a14 + ADD $65536, R6 // 3cc60001 + ADD $65536, R6, R7 // 3ce60001 + ADD $-32767, R5 // 38a58001 + ADD $-32767, R5, R4 // 38858001 + ADD $-32768, R6 // 38c68000 + ADD $-32768, R6, R5 // 38a68000 + ADD $1234567, R5 // 641f001263ffd6877cbf2a14 + ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14 + ADDEX R3, R5, $3, R6 // 7cc32f54 + ADDIS $8, R3 // 3c630008 + ADDIS $1000, R3, R4 // 3c8303e8 -// LMOVB addr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVB foo<>+3(SB), R2 - MOVB 16(R1), R2 + ANDCC $1, R3 // 70630001 + ANDCC $1, R3, R4 // 70640001 + ANDCC $-1, R4 // 3be0ffff7fe42039 + ANDCC $-1, R4, R5 // 3be0ffff7fe52039 + ANDCC $65535, R5 // 70a5ffff + ANDCC $65535, R5, R6 // 70a6ffff + ANDCC $65536, R6 // 74c60001 + ANDCC $65536, R6, R7 // 74c70001 + ANDCC $-32767, R5 // 3be080017fe52839 + ANDCC $-32767, R5, R4 // 3be080017fe42839 + ANDCC $-32768, R6 // 3be080007fe63039 + ANDCC $-32768, R5, R6 // 3be080007fe62839 + ANDCC $1234567, R5 // 641f001263ffd6877fe52839 + ANDCC $1234567, R5, R6 // 641f001263ffd6877fe62839 + ANDISCC $1, R3 // 74630001 + ANDISCC $1000, R3, R4 // 746403e8 -// LMOVB regaddr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVB (R1), R2 - MOVB (R1+R2), R3 // MOVB (R1)(R2*1), R3 + OR $1, R3 // 60630001 + OR $1, R3, R4 // 60640001 + OR $-1, R4 // 3be0ffff7fe42378 + OR $-1, R4, R5 // 3be0ffff7fe52378 + OR $65535, R5 // 60a5ffff + OR $65535, R5, R6 // 60a6ffff + OR $65536, R6 // 64c60001 + OR $65536, R6, R7 // 64c70001 + OR $-32767, R5 // 3be080017fe52b78 + OR $-32767, R5, R6 // 3be080017fe62b78 + OR $-32768, R6 // 3be080007fe63378 + OR $-32768, R6, R7 // 3be080007fe73378 + OR $1234567, R5 // 641f001263ffd6877fe52b78 + OR $1234567, R5, R3 // 641f001263ffd6877fe32b78 + ORIS $255, R3, R4 -// -// load floats -// -// LFMOV addr ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD foo<>+4(SB), F2 - FMOVD 16(R1), F2 + XOR $1, R3 // 68630001 + XOR $1, R3, R4 // 68640001 + XOR $-1, R4 // 3be0ffff7fe42278 + XOR $-1, R4, R5 // 3be0ffff7fe52278 + XOR $65535, R5 // 68a5ffff + XOR $65535, R5, R6 // 68a6ffff + XOR $65536, R6 // 6cc60001 + XOR $65536, R6, R7 // 6cc70001 + XOR $-32767, R5 // 3be080017fe52a78 + XOR $-32767, R5, R6 // 3be080017fe62a78 + XOR $-32768, R6 // 3be080007fe63278 + XOR $-32768, R6, R7 // 3be080007fe73278 + XOR $1234567, R5 // 641f001263ffd6877fe52a78 + XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78 + XORIS $15, R3, R4 -// LFMOV regaddr ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD (R1), F2 + // TODO: the order of CR operands don't match + CMP R3, R4 // 7c232000 + CMPU R3, R4 // 7c232040 + CMPW R3, R4 // 7c032000 + CMPWU R3, R4 // 7c032040 + CMPB R3,R4,R4 // 7c6423f8 + CMPEQB R3,R4,CR6 // 7f0321c0 -// LFMOV fimm ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD $0.1, F2 // FMOVD $(0.10000000000000001), F2 + // TODO: constants for ADDC? + ADD R3, R4 // 7c841a14 + ADD R3, R4, R5 // 7ca41a14 + ADDC R3, R4 // 7c841814 + ADDC R3, R4, R5 // 7ca41814 + ADDE R3, R4 // 7c841914 + ADDECC R3, R4 // 7c841915 + ADDEV R3, R4 // 7c841d14 + ADDEVCC R3, R4 // 7c841d15 + ADDV R3, R4 // 7c841e14 + ADDVCC R3, R4 // 7c841e15 + ADDCCC R3, R4, R5 // 7ca41815 + ADDME R3, R4 // 7c8301d4 + ADDMECC R3, R4 // 7c8301d5 + ADDMEV R3, R4 // 7c8305d4 + ADDMEVCC R3, R4 // 7c8305d5 + ADDCV R3, R4 // 7c841c14 + ADDCVCC R3, R4 // 7c841c15 + ADDZE R3, R4 // 7c830194 + ADDZECC R3, R4 // 7c830195 + ADDZEV R3, R4 // 7c830594 + ADDZEVCC R3, R4 // 7c830595 + SUBME R3, R4 // 7c8301d0 + SUBMECC R3, R4 // 7c8301d1 + SUBMEV R3, R4 // 7c8305d0 + SUBZE R3, R4 // 7c830190 + SUBZECC R3, R4 // 7c830191 + SUBZEV R3, R4 // 7c830590 + SUBZEVCC R3, R4 // 7c830591 -// LFMOV freg ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD F1, F2 + AND R3, R4 // 7c841838 + AND R3, R4, R5 // 7c851838 + ANDN R3, R4, R5 // 7c851878 + ANDCC R3, R4, R5 // 7c851839 + OR R3, R4 // 7c841b78 + OR R3, R4, R5 // 7c851b78 + ORN R3, R4, R5 // 7c851b38 + ORCC R3, R4, R5 // 7c851b79 + XOR R3, R4 // 7c841a78 + XOR R3, R4, R5 // 7c851a78 + XORCC R3, R4, R5 // 7c851a79 + NAND R3, R4, R5 // 7c851bb8 + NANDCC R3, R4, R5 // 7c851bb9 + EQV R3, R4, R5 // 7c851a38 + EQVCC R3, R4, R5 // 7c851a39 + NOR R3, R4, R5 // 7c8518f8 + NORCC R3, R4, R5 // 7c8518f9 -// LFMOV freg ',' addr -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD F2, foo<>+4(SB) - FMOVD F2, 16(R1) + SUB R3, R4 // 7c832050 + SUB R3, R4, R5 // 7ca32050 + SUBC R3, R4 // 7c832010 + SUBC R3, R4, R5 // 7ca32010 -// LFMOV freg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD F2, (R1) + MULLW R3, R4 // 7c8419d6 + MULLW R3, R4, R5 // 7ca419d6 + MULLW $10, R3 // 1c63000a + MULLW $10000000, R3 // 641f009863ff96807c7f19d6 -// -// store ints and bytes -// -// LMOVW rreg ',' addr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, foo<>+3(SB) - MOVW R1, 16(R2) + MULLWCC R3, R4, R5 // 7ca419d7 + MULHW R3, R4, R5 // 7ca41896 -// LMOVW rreg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, (R1) - MOVW R1, (R2+R3) // MOVW R1, (R2)(R3*1) + MULHWU R3, R4, R5 // 7ca41816 + MULLD R3, R4 // 7c8419d2 + MULLD R4, R4, R5 // 7ca421d2 + MULLD $20, R4 // 1c840014 + MULLD $200000000, R4 // 641f0beb63ffc2007c9f21d2 -// LMOVB rreg ',' addr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVB R1, foo<>+3(SB) - MOVB R1, 16(R2) + MULLDCC R3, R4, R5 // 7ca419d3 + MULHD R3, R4, R5 // 7ca41892 + MULHDCC R3, R4, R5 // 7ca41893 -// LMOVB rreg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVB R1, (R1) - MOVB R1, (R2+R3) // MOVB R1, (R2)(R3*1) -// -// store floats -// -// LMOVW freg ',' addr -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD F1, foo<>+4(SB) - FMOVD F1, 16(R2) + MULLWV R3, R4 // 7c841dd6 + MULLWV R3, R4, R5 // 7ca41dd6 + MULLWVCC R3, R4, R5 // 7ca41dd7 + MULHWUCC R3, R4, R5 // 7ca41817 + MULLDV R3, R4, R5 // 7ca41dd2 + MULLDVCC R3, R4, R5 // 7ca41dd3 -// LMOVW freg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - FMOVD F1, (R1) + DIVD R3,R4 // 7c841bd2 + DIVD R3, R4, R5 // 7ca41bd2 + DIVDCC R3,R4, R5 // 7ca41bd3 + DIVDU R3, R4, R5 // 7ca41b92 + DIVDV R3, R4, R5 // 7ca41fd2 + DIVDUCC R3, R4, R5 // 7ca41b93 + DIVDVCC R3, R4, R5 // 7ca41fd3 + DIVDUV R3, R4, R5 // 7ca41f92 + DIVDUVCC R3, R4, R5 // 7ca41f93 + DIVDE R3, R4, R5 // 7ca41b52 + DIVDECC R3, R4, R5 // 7ca41b53 + DIVDEU R3, R4, R5 // 7ca41b12 + DIVDEUCC R3, R4, R5 // 7ca41b13 -// -// floating point status -// -// LMOVW fpscr ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVFL FPSCR, F1 + REM R3, R4, R5 // 7fe41bd67fff19d67cbf2050 + REMU R3, R4, R5 // 7fe41b967fff19d67bff00287cbf2050 + REMD R3, R4, R5 // 7fe41bd27fff19d27cbf2050 + REMDU R3, R4, R5 // 7fe41b927fff19d27cbf2050 -// LMOVW freg ',' fpscr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVFL F1, FPSCR + MADDHD R3,R4,R5,R6 // 10c32170 + MADDHDU R3,R4,R5,R6 // 10c32171 -// LMOVW freg ',' imm ',' fpscr -// { -// outgcode(int($1), &$2, 0, &$4, &$6); -// } - MOVFL F1, $4, FPSCR + MODUD R3, R4, R5 // 7ca41a12 + MODUW R3, R4, R5 // 7ca41a16 + MODSD R3, R4, R5 // 7ca41e12 + MODSW R3, R4, R5 // 7ca41e16 -// LMOVW fpscr ',' creg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVFL FPSCR, CR0 + SLW $8, R3, R4 // 5464402e + SLW R3, R4, R5 // 7c851830 + SLWCC R3, R4 // 7c841831 + SLD $16, R3, R4 // 786483e4 + SLD R3, R4, R5 // 7c851836 + SLDCC R3, R4 // 7c841837 -// LMTFSB imm ',' con -// { -// outcode(int($1), &$2, int($4), &nullgen); -// } -//TODO 9a doesn't work MTFSB0 $4, 4 + SRW $8, R3, R4 // 5464c23e + SRW R3, R4, R5 // 7c851c30 + SRWCC R3, R4 // 7c841c31 + SRAW $8, R3, R4 // 7c644670 + SRAW R3, R4, R5 // 7c851e30 + SRAWCC R3, R4 // 7c841e31 + SRD $16, R3, R4 // 78648402 + SRD R3, R4, R5 // 7c851c36 + SRDCC R3, R4 // 7c841c37 + SRAD $16, R3, R4 // 7c648674 + SRAD R3, R4, R5 // 7c851e34 + SRDCC R3, R4 // 7c841c37 + ROTLW $16, R3, R4 // 5464803e + ROTLW R3, R4, R5 // 5c85183e + EXTSWSLI $3, R4, R5 // 7c851ef4 + RLWMI $7, R3, $65535, R6 // 50663c3e + RLWMICC $7, R3, $65535, R6 // 50663c3f + RLWNM $3, R4, $7, R6 // 54861f7e + RLWNM R3, R4, $7, R6 // 5c861f7e + RLWNMCC $3, R4, $7, R6 // 54861f7f + RLWNMCC R3, R4, $7, R6 // 5c861f7f + RLDMI $0, R4, $7, R6 // 7886076c + RLDMICC $0, R4, $7, R6 // 7886076d + RLDIMI $0, R4, $7, R6 // 788601cc + RLDIMICC $0, R4, $7, R6 // 788601cd + RLDC $0, R4, $15, R6 // 78860728 + RLDCCC $0, R4, $15, R6 // 78860729 + RLDCL $0, R4, $7, R6 // 78860770 + RLDCLCC $0, R4, $15, R6 // 78860721 + RLDCR $0, R4, $-16, R6 // 788606f2 + RLDCRCC $0, R4, $-16, R6 // 788606f3 + RLDICL $0, R4, $15, R6 // 788603c0 + RLDICLCC $0, R4, $15, R6 // 788603c1 + RLDICR $0, R4, $15, R6 // 788603c4 + RLDICRCC $0, R4, $15, R6 // 788603c5 + RLDIC $0, R4, $15, R6 // 788603c8 + RLDICCC $0, R4, $15, R6 // 788603c9 + CLRLSLWI $16, R5, $8, R4 // 54a4422e + CLRLSLDI $24, R4, $2, R3 // 78831588 -// -// field moves (mtcrf) -// -// LMOVW rreg ',' imm ',' lcr -// { -// outgcode(int($1), &$2, 0, &$4, &$6); -// } -// TODO 9a doesn't work MOVFL R1,$4,CR + BEQ 0(PC) // 41820000 + BEQ CR1,0(PC) // 41860000 + BGE 0(PC) // 40800000 + BGE CR2,0(PC) // 40880000 + BGT 4(PC) // 41810010 + BGT CR3,4(PC) // 418d0010 + BLE 0(PC) // 40810000 + BLE CR4,0(PC) // 40910000 + BLT 0(PC) // 41800000 + BLT CR5,0(PC) // 41940000 + BNE 0(PC) // 40820000 + BLT CR6,0(PC) // 41980000 + JMP 8(PC) // 48000010 -// LMOVW rreg ',' creg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, CR1 - -// LMOVW rreg ',' lcr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, CR - -// -// integer operations -// logical instructions -// shift instructions -// unary instructions -// -// LADDW rreg ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } - ADD R1, R2, R3 - -// LADDW imm ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } - ADD $1, R2, R3 - -// LADDW rreg ',' imm ',' rreg -// { -// outgcode(int($1), &$2, 0, &$4, &$6); -// } -//TODO 9a trouble ADD R1, $2, R3 maybe swap rreg and imm - -// LADDW rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - ADD R1, R2 - -// LADDW imm ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - ADD $4, R1 - -// LLOGW rreg ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } - ADDE R1, R2, R3 - -// LLOGW rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - ADDE R1, R2 - -// LSHW rreg ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } - SLW R1, R2, R3 - -// LSHW rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - SLW R1, R2 - -// LSHW imm ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } - SLW $4, R1, R2 - -// LSHW imm ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - SLW $4, R1 - -// LABS rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - SLW $4, R1 - -// LABS rreg -// { -// outcode(int($1), &$2, 0, &$2); -// } - SUBME R1 // SUBME R1, R1 - -// -// multiply-accumulate -// -// LMA rreg ',' sreg ',' rreg -// { -// outcode(int($1), &$2, int($4), &$6); -// } -//TODO this instruction is undefined in lex.go LMA R1, R2, R3 NOT SUPPORTED (called MAC) - -// -// move immediate: macro for cau+or, addi, addis, and other combinations -// -// LMOVW imm ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW $1, R1 - -// LMOVW ximm ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW $1, R1 - MOVW $foo(SB), R1 - -// condition register operations -// -// LCROP cbit ',' cbit -// { -// outcode(int($1), &$2, int($4.Reg), &$4); -// } -//TODO 9a trouble CREQV 1, 2 delete? liblink encodes like a divide (maybe wrong too) - -// LCROP cbit ',' con ',' cbit -// { -// outcode(int($1), &$2, int($4), &$6); -// } -//TODO 9a trouble CREQV 1, 2, 3 - -// -// condition register moves -// move from machine state register -// -// LMOVW creg ',' creg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVFL CR0, CR1 - -// LMOVW psr ',' creg // TODO: should psr should be fpscr -// { -// outcode(int($1), &$2, 0, &$4); -// } -//TODO 9a trouble MOVW FPSCR, CR1 - -// LMOVW lcr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW CR, R1 - -// LMOVW psr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW SPR(0), R1 - MOVW SPR(7), R1 - -// LMOVW xlreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW LR, R1 - MOVW CTR, R1 - -// LMOVW rreg ',' xlreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, LR - MOVW R1, CTR - -// LMOVW creg ',' psr // TODO doesn't exist -// { -// outcode(int($1), &$2, 0, &$4); -// } -//TODO 9a trouble MOVW CR1, SPR(7) - -// LMOVW rreg ',' psr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVW R1, SPR(7) - -// -// branch, branch conditional -// branch conditional register -// branch conditional to count register -// -// LBRA rel -// { -// outcode(int($1), &nullgen, 0, &$2); -// } - BEQ CR1, 2(PC) -label0: - BR 1(PC) // JMP 1(PC) - BEQ CR1, 2(PC) - BR label0+0 // JMP 62 - -// LBRA addr -// { -// outcode(int($1), &nullgen, 0, &$2); -// } - BEQ CR1, 2(PC) - BR LR // JMP LR - BEQ CR1, 2(PC) -// BR 0(R1) // TODO should work - BEQ CR1, 2(PC) - BR foo+0(SB) // JMP foo(SB) - -// LBRA '(' xlreg ')' -// { -// outcode(int($1), &nullgen, 0, &$3); -// } - BEQ CR1, 2(PC) - BR (CTR) // JMP CTR - -// LBRA ',' rel // asm doesn't support the leading comma -// { -// outcode(int($1), &nullgen, 0, &$3); -// } -// LBRA ',' addr // asm doesn't support the leading comma -// { -// outcode(int($1), &nullgen, 0, &$3); -// } -// LBRA ',' '(' xlreg ')' // asm doesn't support the leading comma -// { -// outcode(int($1), &nullgen, 0, &$4); -// } -// LBRA creg ',' rel -// { -// outcode(int($1), &$2, 0, &$4); -// } -label1: - BEQ CR1, 1(PC) - BEQ CR1, label1 // BEQ CR1, 72 - -// LBRA creg ',' addr // TODO DOES NOT WORK in 9a -// { -// outcode(int($1), &$2, 0, &$4); -// } - -// LBRA creg ',' '(' xlreg ')' // TODO DOES NOT WORK in 9a -// { -// outcode(int($1), &$2, 0, &$5); -// } - -// LBRA con ',' rel // TODO DOES NOT WORK in 9a -// { -// outcode(int($1), &nullgen, int($2), &$4); -// } - -// LBRA con ',' addr // TODO DOES NOT WORK in 9a -// { -// outcode(int($1), &nullgen, int($2), &$4); -// } - -// LBRA con ',' '(' xlreg ')' -// { -// outcode(int($1), &nullgen, int($2), &$5); -// } -// BC 4, (CTR) // TODO - should work - -// LBRA con ',' con ',' rel -// { -// var g obj.Addr -// g = nullgen; -// g.Type = obj.TYPE_CONST; -// g.Offset = $2; -// outcode(int($1), &g, int(REG_R0+$4), &$6); -// } -// BC 3, 4, label1 // TODO - should work - -// LBRA con ',' con ',' addr // TODO mystery -// { -// var g obj.Addr -// g = nullgen; -// g.Type = obj.TYPE_CONST; -// g.Offset = $2; -// outcode(int($1), &g, int(REG_R0+$4), &$6); -// } -//TODO 9a trouble BC 3, 3, 4(R1) - -// LBRA con ',' con ',' '(' xlreg ')' -// { -// var g obj.Addr -// g = nullgen; -// g.Type = obj.TYPE_CONST; -// g.Offset = $2; -// outcode(int($1), &g, int(REG_R0+$4), &$7); -// } - BC 3, 3, (LR) // BC $3, R3, LR - -// -// conditional trap // TODO NOT DEFINED -// TODO these instructions are not in lex.go -// -// LTRAP rreg ',' sreg -// { -// outcode(int($1), &$2, int($4), &nullgen); -// } -// LTRAP imm ',' sreg -// { -// outcode(int($1), &$2, int($4), &nullgen); -// } -// LTRAP rreg comma -// { -// outcode(int($1), &$2, 0, &nullgen); -// } -// LTRAP comma -// { -// outcode(int($1), &nullgen, 0, &nullgen); -// } - -// -// floating point operate -// -// LFCONV freg ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FABS F1, F2 - -// LFADD freg ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FADD F1, F2 - -// LFADD freg ',' freg ',' freg -// { -// outcode(int($1), &$2, int($4.Reg), &$6); -// } - FADD F1, F2, F3 - -// LFMA freg ',' freg ',' freg ',' freg -// { -// outgcode(int($1), &$2, int($4.Reg), &$6, &$8); -// } - FMADD F1, F2, F3, F4 - -// LFCMP freg ',' freg -// { -// outcode(int($1), &$2, 0, &$4); -// } - FCMPU F1, F2 - -// LFCMP freg ',' freg ',' creg -// { -// outcode(int($1), &$2, int($6.Reg), &$4); -// } -// FCMPU F1, F2, CR0 - -// FTDIV FRA, FRB, BF produces -// ftdiv BF, FRA, FRB - FTDIV F1,F2,$7 - -// FTSQRT FRB, BF produces -// ftsqrt BF, FRB - FTSQRT F2,$7 - -// FCFID -// FCFIDS - - FCFID F2,F3 - FCFIDCC F3,F3 - FCFIDS F2,F3 - FCFIDSCC F2,F3 - -// -// CMP -// -// LCMP rreg ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - CMP R1, R2 - -// LCMP rreg ',' imm -// { -// outcode(int($1), &$2, 0, &$4); -// } - CMP R1, $4 - -// LCMP rreg ',' rreg ',' creg -// { -// outcode(int($1), &$2, int($6.Reg), &$4); -// } - CMP R1, R2, CR0 // CMP R1, CR0, R2 - -// LCMP rreg ',' imm ',' creg -// { -// outcode(int($1), &$2, int($6.Reg), &$4); -// } - CMP R1, $4, CR0 // CMP R1, CR0, $4 - -// CMPB RS,RB,RA produces -// cmpb RA,RS,RB - CMPB R2,R2,R1 - -// CMPEQB RA,RB,BF produces -// cmpeqb BF,RA,RB - CMPEQB R1, R2, CR0 - -// -// rotate extended mnemonics map onto other shift instructions -// - - ROTL $12,R2,R3 - ROTL R2,R3,R4 - ROTLW $9,R2,R3 - ROTLW R2,R3,R4 - -// -// rotate and mask -// -// LRLWM imm ',' rreg ',' imm ',' rreg -// { -// outgcode(int($1), &$2, int($4.Reg), &$6, &$8); -// } - RLDC $4, R1, $16, R2 - -// LRLWM imm ',' rreg ',' mask ',' rreg -// { -// outgcode(int($1), &$2, int($4.Reg), &$6, &$8); -// } - RLDC $26, R1, 4, 5, R2 // RLDC $26, R1, $201326592, R2 - -// LRLWM rreg ',' rreg ',' imm ',' rreg -// { -// outgcode(int($1), &$2, int($4.Reg), &$6, &$8); -// } - RLDCL R1, R2, $7, R3 - -// LRLWM rreg ',' rreg ',' mask ',' rreg -// { -// outgcode(int($1), &$2, int($4.Reg), &$6, &$8); -// } - RLWMI R1, R2, 4, 5, R3 // RLWMI R1, R2, $201326592, R3 - - -// opcodes added with constant shift counts, not masks - - RLDICR $3, R2, $24, R4 - - RLDICL $1, R2, $61, R6 - - RLDIMI $7, R2, $52, R7 - -// opcodes for right and left shifts, const and reg shift counts - - SLD $4, R3, R4 - SLD R2, R3, R4 - SLW $4, R3, R4 - SLW R2, R3, R4 - SRD $8, R3, R4 - SRD R2, R3, R4 - SRW $8, R3, R4 - SRW R2, R3, R4 - -// -// load/store multiple -// -// LMOVMW addr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } -// MOVMW foo+0(SB), R2 // TODO TLS broke this! - MOVMW 4(R1), R2 - -// LMOVMW rreg ',' addr -// { -// outcode(int($1), &$2, 0, &$4); -// } -// MOVMW R1, foo+0(SB) // TODO TLS broke this! - MOVMW R1, 4(R2) - -// -// various indexed load/store -// indexed unary (eg, cache clear) -// -// LXLD regaddr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - LSW (R1), R2 - LSW (R1+R2), R3 // LSW (R1)(R2*1), R3 - -// LXLD regaddr ',' imm ',' rreg -// { -// outgcode(int($1), &$2, 0, &$4, &$6); -// } - LSW (R1), $1, R2 - LSW (R1+R2), $1, R3 // LSW (R1)(R2*1), $1, R3 - -// LXST rreg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - STSW R1, (R2) - STSW R1, (R2+R3) // STSW R1, (R2)(R3*1) - -// LXST rreg ',' imm ',' regaddr -// { -// outgcode(int($1), &$2, 0, &$4, &$6); -// } - STSW R1, $1, (R2) - STSW R1, $1, (R2+R3) // STSW R1, $1, (R2)(R3*1) - -// LXMV regaddr ',' rreg -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVHBR (R1), R2 - MOVHBR (R1+R2), R3 // MOVHBR (R1)(R2*1), R3 - -// LXMV rreg ',' regaddr -// { -// outcode(int($1), &$2, 0, &$4); -// } - MOVHBR R1, (R2) - MOVHBR R1, (R2+R3) // MOVHBR R1, (R2)(R3*1) - -// LXOP regaddr -// { -// outcode(int($1), &$2, 0, &nullgen); -// } - DCBF (R1) - DCBF (R1+R2) // DCBF (R1)(R2*1) - DCBF (R1), $1 - DCBF (R1)(R2*1), $1 - DCBT (R1), $1 - DCBT (R1)(R2*1), $1 - -// LDMX (RB)(RA*1),RT produces -// ldmx RT,RA,RB - LDMX (R2)(R1*1), R3 - -// Population count, X-form -// <MNEMONIC> RS,RA produces -// <mnemonic> RA,RS - POPCNTD R1,R2 - POPCNTW R1,R2 - POPCNTB R1,R2 - -// Copysign - FCPSGN F1,F2,F3 - -// Random number generator, X-form -// DARN L,RT produces -// darn RT,L - DARN $1, R1 - -// Copy/Paste facility -// <MNEMONIC> RB,RA produces -// <mnemonic> RA,RB - COPY R2,R1 - PASTECC R2,R1 - -// Modulo signed/unsigned double/word X-form -// <MNEMONIC> RA,RB,RT produces -// <mnemonic> RT,RA,RB - MODUD R3,R4,R5 - MODUW R3,R4,R5 - MODSD R3,R4,R5 - MODSW R3,R4,R5 - -// VMX instructions - -// Described as: -// <instruction type>, <instruction format> -// <go asm operand order> produces -// <Power ISA operand order> - -// Vector load, VX-form -// <MNEMONIC> (RB)(RA*1),VRT produces -// <mnemonic> VRT,RA,RB - LVEBX (R1)(R2*1), V0 - LVEHX (R3)(R4*1), V1 - LVEWX (R5)(R6*1), V2 - LVX (R7)(R8*1), V3 - LVXL (R9)(R10*1), V4 - LVSL (R11)(R12*1), V5 - LVSR (R14)(R15*1), V6 - -// Vector store, VX-form -// <MNEMONIC> VRT,(RB)(RA*1) produces -// <mnemonic> VRT,RA,RB - STVEBX V31, (R1)(R2*1) - STVEHX V30, (R2)(R3*1) - STVEWX V29, (R4)(R5*1) - STVX V28, (R6)(R7*1) - STVXL V27, (R9)(R9*1) - -// Vector AND, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VAND V10, V9, V8 - VANDC V15, V14, V13 - VNAND V19, V18, V17 - -// Vector OR, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VOR V26, V25, V24 - VORC V23, V22, V21 - VNOR V20, V19, V18 - VXOR V17, V16, V15 - VEQV V14, V13, V12 - -// Vector ADD, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VADDUBM V3, V2, V1 - VADDUHM V3, V2, V1 - VADDUWM V3, V2, V1 - VADDUDM V3, V2, V1 - VADDUQM V3, V2, V1 - VADDCUQ V3, V2, V1 - VADDCUW V3, V2, V1 - VADDUBS V3, V2, V1 - VADDUHS V3, V2, V1 - VADDUWS V3, V2, V1 - VADDSBS V3, V2, V1 - VADDSHS V3, V2, V1 - VADDSWS V3, V2, V1 - -// Vector ADD extended, VA-form -// <MNEMONIC> VRA,VRB,VRC,VRT produces -// <mnemonic> VRT,VRA,VRB,VRC - VADDEUQM V4, V3, V2, V1 - VADDECUQ V4, V3, V2, V1 - -// Vector multiply, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VMULESB V2, V3, V1 - VMULOSB V2, V3, V1 - VMULEUB V2, V3, V1 - VMULOUB V2, V3, V1 - VMULESH V2, V3, V1 - VMULOSH V2, V3, V1 - VMULEUH V2, V3, V1 - VMULOUH V2, V3, V1 - VMULESW V2, V3, V1 - VMULOSW V2, V3, V1 - VMULEUW V2, V3, V1 - VMULOUW V2, V3, V1 - VMULUWM V2, V3, V1 - -// Vector polynomial multiply-sum, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VPMSUMB V2, V3, V1 - VPMSUMH V2, V3, V1 - VPMSUMW V2, V3, V1 - VPMSUMD V2, V3, V1 - -// Vector multiply-sum, VA-form -// <MNEMONIC> VRA, VRB, VRC, VRT produces -// <mnemonic> VRT, VRA, VRB, VRC - VMSUMUDM V4, V3, V2, V1 - -// Vector SUB, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VSUBUBM V3, V2, V1 - VSUBUHM V3, V2, V1 - VSUBUWM V3, V2, V1 - VSUBUDM V3, V2, V1 - VSUBUQM V3, V2, V1 - VSUBCUQ V3, V2, V1 - VSUBCUW V3, V2, V1 - VSUBUBS V3, V2, V1 - VSUBUHS V3, V2, V1 - VSUBUWS V3, V2, V1 - VSUBSBS V3, V2, V1 - VSUBSHS V3, V2, V1 - VSUBSWS V3, V2, V1 - -// Vector SUB extended, VA-form -// <MNEMONIC> VRA,VRB,VRC,VRT produces -// <mnemonic> VRT,VRA,VRB,VRC - VSUBEUQM V4, V3, V2, V1 - VSUBECUQ V4, V3, V2, V1 - -// Vector rotate, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VRLB V2, V1, V0 - VRLH V2, V1, V0 - VRLW V2, V1, V0 - VRLD V2, V1, V0 - -// Vector shift, VX-form -// <MNEMONIC> VRA,VRB,VRT -// <mnemonic> VRT,VRA,VRB - VSLB V2, V1, V0 - VSLH V2, V1, V0 - VSLW V2, V1, V0 - VSL V2, V1, V0 - VSLO V2, V1, V0 - VSRB V2, V1, V0 - VSRH V2, V1, V0 - VSRW V2, V1, V0 - VSR V2, V1, V0 - VSRO V2, V1, V0 - VSLD V2, V1, V0 - VSRD V2, V1, V0 - VSRAB V2, V1, V0 - VSRAH V2, V1, V0 - VSRAW V2, V1, V0 - VSRAD V2, V1, V0 - -// Vector shift by octect immediate, VA-form with SHB 4-bit field -// <MNEMONIC> SHB,VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB,SHB - VSLDOI $4, V2, V1, V0 - -// Vector merge odd and even word -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - - VMRGOW V4,V5,V6 - VMRGEW V4,V5,V6 - -// Vector count, VX-form -// <MNEMONIC> VRB,VRT produces -// <mnemonic> VRT,VRB - VCLZB V4, V5 - VCLZH V4, V5 - VCLZW V4, V5 - VCLZD V4, V5 - VPOPCNTB V4, V5 - VPOPCNTH V4, V5 - VPOPCNTW V4, V5 - VPOPCNTD V4, V5 - -// Vector compare, VC-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB -// * Note: 'CC' suffix denotes Rc=1 -// i.e. vcmpequb. v3,v1,v2 equals VCMPEQUBCC V1,V2,V3 - VCMPEQUB V3, V2, V1 - VCMPEQUBCC V3, V2, V1 - VCMPEQUH V3, V2, V1 - VCMPEQUHCC V3, V2, V1 - VCMPEQUW V3, V2, V1 - VCMPEQUWCC V3, V2, V1 - VCMPEQUD V3, V2, V1 - VCMPEQUDCC V3, V2, V1 - VCMPGTUB V3, V2, V1 - VCMPGTUBCC V3, V2, V1 - VCMPGTUH V3, V2, V1 - VCMPGTUHCC V3, V2, V1 - VCMPGTUW V3, V2, V1 - VCMPGTUWCC V3, V2, V1 - VCMPGTUD V3, V2, V1 - VCMPGTUDCC V3, V2, V1 - VCMPGTSB V3, V2, V1 - VCMPGTSBCC V3, V2, V1 - VCMPGTSH V3, V2, V1 - VCMPGTSHCC V3, V2, V1 - VCMPGTSW V3, V2, V1 - VCMPGTSWCC V3, V2, V1 - VCMPGTSD V3, V2, V1 - VCMPGTSDCC V3, V2, V1 - VCMPNEZB V3, V2, V1 - VCMPNEZBCC V3, V2, V1 - VCMPNEB V3, V2, V1 - VCMPNEBCC V3, V2, V1 - VCMPNEH V3, V2, V1 - VCMPNEHCC V3, V2, V1 - VCMPNEW V3, V2, V1 - VCMPNEWCC V3, V2, V1 - -// Vector permute, VA-form -// <MNEMONIC> VRA,VRB,VRC,VRT produces -// <mnemonic> VRT,VRA,VRB,VRC - VPERM V3, V2, V1, V0 - VPERMXOR V3, V2, V1, V0 - VPERMR V3, V2, V1, V0 - -// Vector bit permute, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VBPERMQ V3,V1,V2 - VBPERMD V3,V1,V2 - -// Vector select, VA-form -// <MNEMONIC> VRA,VRB,VRC,VRT produces -// <mnemonic> VRT,VRA,VRB,VRC - VSEL V3, V2, V1, V0 - -// Vector splat, VX-form with 4-bit UIM field -// <MNEMONIC> UIM,VRB,VRT produces -// <mnemonic> VRT,VRB,UIM - VSPLTB $15, V1, V0 - VSPLTH $7, V1, V0 - VSPLTW $3, V1, V0 - -// Vector splat immediate signed, VX-form with 5-bit SIM field -// <MNEMONIC> SIM,VRT produces -// <mnemonic> VRT,SIM - VSPLTISB $31, V4 - VSPLTISH $31, V4 - VSPLTISW $31, V4 - -// Vector AES cipher, VX-form -// <MNEMONIC> VRA,VRB,VRT produces -// <mnemonic> VRT,VRA,VRB - VCIPHER V3, V2, V1 - VCIPHERLAST V3, V2, V1 - VNCIPHER V3, V2, V1 - VNCIPHERLAST V3, V2, V1 - -// Vector AES subbytes, VX-form -// <MNEMONIC> VRA,VRT produces -// <mnemonic> VRT,VRA - VSBOX V2, V1 - -// Vector SHA, VX-form with ST bit field and 4-bit SIX field -// <MNEMONIC> SIX,VRA,ST,VRT produces -// <mnemonic> VRT,VRA,ST,SIX - VSHASIGMAW $15, V1, $1, V0 - VSHASIGMAD $15, V1, $1, V0 - -// VSX instructions -// Described as: -// <instruction type>, <instruction format> -// <go asm operand order> produces -// <Power ISA operand order> - -// VSX load, XX1-form -// <MNEMONIC> (RB)(RA*1),XT produces -// <mnemonic> XT,RA,RB - LXVD2X (R1)(R2*1), VS0 - LXVW4X (R1)(R2*1), VS0 - LXVH8X (R1)(R2*1), VS0 - LXVB16X (R1)(R2*1), VS0 - LXVDSX (R1)(R2*1), VS0 - LXSDX (R1)(R2*1), VS0 - LXSIWAX (R1)(R2*1), VS0 - LXSIWZX (R1)(R2*1), VS0 - -// VSX load with length X-form (also left-justified) - LXVL R3,R4, VS0 - LXVLL R3,R4, VS0 - LXVX R3,R4, VS0 -// VSX load, DQ-form -// <MNEMONIC> DQ(RA), XS produces -// <mnemonic> XS, DQ(RA) - LXV 32752(R1), VS0 - -// VSX store, XX1-form -// <MNEMONIC> XS,(RB)(RA*1) produces -// <mnemonic> XS,RA,RB - STXVD2X VS63, (R1)(R2*1) - STXVW4X VS63, (R1)(R2*1) - STXVH8X VS63, (R1)(R2*1) - STXVB16X VS63, (R1)(R2*1) - STXSDX VS63, (R1)(R2*1) - STXSIWX VS63, (R1)(R2*1) - -// VSX store, DQ-form -// <MNEMONIC> DQ(RA), XS produces -// <mnemonic> XS, DQ(RA) - STXV VS63, -32752(R1) - -// VSX store with length, X-form (also left-justified) - STXVL VS0, R3,R4 - STXVLL VS0, R3,R4 - STXVX VS0, R3,R4 - -// VSX move from VSR, XX1-form -// <MNEMONIC> XS,RA produces -// <mnemonic> RA,XS -// Extended mnemonics accept VMX and FP registers as sources - MFVSRD VS0, R1 - MFVSRWZ VS33, R1 - MFVSRLD VS63, R1 - MFVRD V0, R1 - MFFPRD F0, R1 - -// VSX move to VSR, XX1-form -// <MNEMONIC> RA,XT produces -// <mnemonic> XT,RA -// Extended mnemonics accept VMX and FP registers as targets - MTVSRD R1, VS0 - MTVSRWA R1, VS31 - MTVSRWZ R1, VS63 - MTVSRDD R1, R2, VS0 - MTVSRWS R1, VS32 - MTVRD R1, V13 - MTFPRD R1, F24 - -// VSX AND, XX3-form -// <MNEMONIC> XA,XB,XT produces -// <mnemonic> XT,XA,XB - XXLAND VS0,VS1,VS32 - XXLANDC VS0,VS1,VS32 - XXLEQV VS0,VS1,VS32 - XXLNAND VS0,VS1,VS32 - -// VSX OR, XX3-form -// <MNEMONIC> XA,XB,XT produces -// <mnemonic> XT,XA,XB - XXLORC VS0,VS1,VS32 - XXLNOR VS0,VS1,VS32 - XXLORQ VS0,VS1,VS32 - XXLXOR VS0,VS1,VS32 - XXLOR VS0,VS1,VS32 - -// VSX select, XX4-form -// <MNEMONIC> XA,XB,XC,XT produces -// <mnemonic> XT,XA,XB,XC - XXSEL VS0,VS1,VS3,VS32 - -// VSX merge, XX3-form -// <MNEMONIC> XA,XB,XT produces -// <mnemonic> XT,XA,XB - XXMRGHW VS0,VS1,VS32 - XXMRGLW VS0,VS1,VS32 - -// VSX splat, XX2-form -// <MNEMONIC> XB,UIM,XT produces -// <mnemonic> XT,XB,UIM - XXSPLTW VS0,$3,VS32 - XXSPLTIB $26,VS0 - -// VSX permute, XX3-form -// <MNEMONIC> XA,XB,XT produces -// <mnemonic> XT,XA,XB - XXPERM VS0,VS1,VS32 - -// VSX permute, XX3-form -// <MNEMONIC> XA,XB,DM,XT produces -// <mnemonic> XT,XA,XB,DM - XXPERMDI VS0,VS1,$3,VS32 - -// VSX shift, XX3-form -// <MNEMONIC> XA,XB,SHW,XT produces -// <mnemonic> XT,XA,XB,SHW - XXSLDWI VS0,VS1,$3,VS32 - -// VSX byte-reverse XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XXBRQ VS0,VS1 - XXBRD VS0,VS1 - XXBRW VS0,VS1 - XXBRH VS0,VS1 - -// VSX scalar FP-FP conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XSCVDPSP VS0,VS32 - XSCVSPDP VS0,VS32 - XSCVDPSPN VS0,VS32 - XSCVSPDPN VS0,VS32 - -// VSX vector FP-FP conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XVCVDPSP VS0,VS32 - XVCVSPDP VS0,VS32 - -// VSX scalar FP-integer conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XSCVDPSXDS VS0,VS32 - XSCVDPSXWS VS0,VS32 - XSCVDPUXDS VS0,VS32 - XSCVDPUXWS VS0,VS32 + NOP + NOP R2 + NOP F2 + NOP $4 -// VSX scalar integer-FP conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XSCVSXDDP VS0,VS32 - XSCVUXDDP VS0,VS32 - XSCVSXDSP VS0,VS32 - XSCVUXDSP VS0,VS32 + CRAND CR1, CR2, CR3 // 4c620a02 + CRANDN CR1, CR2, CR3 // 4c620902 + CREQV CR1, CR2, CR3 // 4c620a42 + CRNAND CR1, CR2, CR3 // 4c6209c2 + CRNOR CR1, CR2, CR3 // 4c620842 + CROR CR1, CR2, CR3 // 4c620b82 + CRORN CR1, CR2, CR3 // 4c620b42 + CRXOR CR1, CR2, CR3 // 4c620982 -// VSX vector FP-integer conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XVCVDPSXDS VS0,VS32 - XVCVDPSXWS VS0,VS32 - XVCVDPUXDS VS0,VS32 - XVCVDPUXWS VS0,VS32 - XVCVSPSXDS VS0,VS32 - XVCVSPSXWS VS0,VS32 - XVCVSPUXDS VS0,VS32 - XVCVSPUXWS VS0,VS32 + ISEL $1, R3, R4, R5 // 7ca3205e + ISEL $0, R3, R4, R5 // 7ca3201e + ISEL $2, R3, R4, R5 // 7ca3209e + ISEL $3, R3, R4, R5 // 7ca320de + ISEL $4, R3, R4, R5 // 7ca3211e + POPCNTB R3, R4 // 7c6400f4 + POPCNTW R3, R4 // 7c6402f4 + POPCNTD R3, R4 // 7c6403f4 -// VSX scalar integer-FP conversion, XX2-form -// <MNEMONIC> XB,XT produces -// <mnemonic> XT,XB - XVCVSXDDP VS0,VS32 - XVCVSXWDP VS0,VS32 - XVCVUXDDP VS0,VS32 - XVCVUXWDP VS0,VS32 - XVCVSXDSP VS0,VS32 - XVCVSXWSP VS0,VS32 - XVCVUXDSP VS0,VS32 - XVCVUXWSP VS0,VS32 + PASTECC R3, R4 // 7c23270d + COPY R3, R4 // 7c23260c -// Multiply-Add High Doubleword -// <MNEMONIC> RA,RB,RC,RT produces -// <mnemonic> RT,RA,RB,RC - MADDHD R1,R2,R3,R4 - MADDHDU R1,R2,R3,R4 + // load-and-reserve + LBAR (R4)(R3*1),$1,R5 // 7ca32069 + LBAR (R4),$0,R5 // 7ca02068 + LBAR (R3),R5 // 7ca01868 + LHAR (R4)(R3*1),$1,R5 // 7ca320e9 + LHAR (R4),$0,R5 // 7ca020e8 + LHAR (R3),R5 // 7ca018e8 + LWAR (R4)(R3*1),$1,R5 // 7ca32029 + LWAR (R4),$0,R5 // 7ca02028 + LWAR (R3),R5 // 7ca01828 + LDAR (R4)(R3*1),$1,R5 // 7ca320a9 + LDAR (R4),$0,R5 // 7ca020a8 + LDAR (R3),R5 // 7ca018a8 -// Add Extended using alternate carry bit -// ADDEX RA,RB,CY,RT produces -// addex RT, RA, RB, CY - ADDEX R1, R2, $0, R3 + STBCCC R3, (R4)(R5) // 7c65256d + STWCCC R3, (R4)(R5) // 7c65212d + STDCCC R3, (R4)(R5) // 7c6521ad + STHCCC R3, (R4)(R5) + STSW R3, (R4)(R5) -// Immediate-shifted operations -// ADDIS SI, RA, RT produces -// addis RT, RA, SI - ADDIS $8, R3, R4 - ADDIS $-1, R3, R4 + SYNC // 7c0004ac + ISYNC // 4c00012c + LWSYNC // 7c2004ac -// ANDISCC UI, RS, RA produces -// andis. RA, RS, UI - ANDISCC $7, R4, R5 + DARN $1, R5 // 7ca105e6 -// ORIS UI, RS, RA produces -// oris RA, RS, UI - ORIS $4, R2, R3 + DCBF (R3)(R4) // 7c0418ac + DCBI (R3)(R4) // 7c041bac + DCBST (R3)(R4) // 7c04186c + DCBZ (R3)(R4) // 7c041fec + DCBT (R3)(R4) // 7c041a2c + ICBI (R3)(R4) // 7c041fac -// XORIS UI, RS, RA produces -// xoris RA, RS, UI - XORIS $1, R1, R2 + // float constants + FMOVD $(0.0), F1 // f0210cd0 + FMOVD $(-0.0), F1 // f0210cd0fc200850 -// -// NOP -// -// LNOP comma // asm doesn't support the trailing comma. -// { -// outcode(int($1), &nullgen, 0, &nullgen); -// } - NOP + FMOVD 8(R3), F1 // c8230008 + FMOVD (R3)(R4), F1 // 7c241cae + FMOVDU 8(R3), F1 // cc230008 + FMOVDU (R3)(R4), F1 // 7c241cee + FMOVS 4(R3), F1 // c0230004 + FMOVS (R3)(R4), F1 // 7c241c2e + FMOVSU 4(R3), F1 // c4230004 + FMOVSU (R3)(R4), F1 // 7c241c6e -// LNOP rreg comma // asm doesn't support the trailing comma. -// { -// outcode(int($1), &$2, 0, &nullgen); -// } - NOP R2 + FMOVD F1, 8(R3) // d8230008 + FMOVD F1, (R3)(R4) // 7c241dae + FMOVDU F1, 8(R3) // dc230008 + FMOVDU F1, (R3)(R4) // 7c241dee + FMOVS F1, 4(R3) // d0230004 + FMOVS F1, (R3)(R4) // 7c241d2e + FMOVSU F1, 4(R3) // d4230004 + FMOVSU F1, (R3)(R4) // 7c241d6e + FADD F1, F2 // fc42082a + FADD F1, F2, F3 // fc62082a + FADDCC F1, F2, F3 // fc62082b + FADDS F1, F2 // ec42082a + FADDS F1, F2, F3 // ec62082a + FADDSCC F1, F2, F3 // ec62082b + FSUB F1, F2 // fc420828 + FSUB F1, F2, F3 // fc620828 + FSUBCC F1, F2, F3 // fc620829 + FSUBS F1, F2 // ec420828 + FSUBS F1, F2, F3 // ec620828 + FSUBCC F1, F2, F3 // fc620829 + FMUL F1, F2 // fc420072 + FMUL F1, F2, F3 // fc620072 + FMULCC F1, F2, F3 // fc620073 + FMULS F1, F2 // ec420072 + FMULS F1, F2, F3 // ec620072 + FMULSCC F1, F2, F3 // ec620073 + FDIV F1, F2 // fc420824 + FDIV F1, F2, F3 // fc620824 + FDIVCC F1, F2, F3 // fc620825 + FDIVS F1, F2 // ec420824 + FDIVS F1, F2, F3 // ec620824 + FDIVSCC F1, F2, F3 // ec620825 + FMADD F1, F2, F3, F4 // fc8110fa + FMADDCC F1, F2, F3, F4 // fc8110fb + FMADDS F1, F2, F3, F4 // ec8110fa + FMADDSCC F1, F2, F3, F4 // ec8110fb + FMSUB F1, F2, F3, F4 // fc8110f8 + FMSUBCC F1, F2, F3, F4 // fc8110f9 + FMSUBS F1, F2, F3, F4 // ec8110f8 + FMSUBSCC F1, F2, F3, F4 // ec8110f9 + FNMADD F1, F2, F3, F4 // fc8110fe + FNMADDCC F1, F2, F3, F4 // fc8110ff + FNMADDS F1, F2, F3, F4 // ec8110fe + FNMADDSCC F1, F2, F3, F4 // ec8110ff + FNMSUB F1, F2, F3, F4 // fc8110fc + FNMSUBCC F1, F2, F3, F4 // fc8110fd + FNMSUBS F1, F2, F3, F4 // ec8110fc + FNMSUBSCC F1, F2, F3, F4 // ec8110fd + FSEL F1, F2, F3, F4 // fc8110ee + FSELCC F1, F2, F3, F4 // fc8110ef + FABS F1, F2 // fc400a10 + FABSCC F1, F2 // fc400a11 + FNEG F1, F2 // fc400850 + FABSCC F1, F2 // fc400a11 + FRSP F1, F2 // fc400818 + FRSPCC F1, F2 // fc400819 + FCTIW F1, F2 // fc40081c + FCTIWCC F1, F2 // fc40081d + FCTIWZ F1, F2 // fc40081e + FCTIWZCC F1, F2 // fc40081f + FCTID F1, F2 // fc400e5c + FCTIDCC F1, F2 // fc400e5d + FCTIDZ F1, F2 // fc400e5e + FCTIDZCC F1, F2 // fc400e5f + FCFID F1, F2 // fc400e9c + FCFIDCC F1, F2 // fc400e9d + FCFIDU F1, F2 // fc400f9c + FCFIDUCC F1, F2 // fc400f9d + FCFIDS F1, F2 // ec400e9c + FCFIDSCC F1, F2 // ec400e9d + FRES F1, F2 // ec400830 + FRESCC F1, F2 // ec400831 + FRIM F1, F2 // fc400bd0 + FRIMCC F1, F2 // fc400bd1 + FRIP F1, F2 // fc400b90 + FRIPCC F1, F2 // fc400b91 + FRIZ F1, F2 // fc400b50 + FRIZCC F1, F2 // fc400b51 + FRIN F1, F2 // fc400b10 + FRINCC F1, F2 // fc400b11 + FRSQRTE F1, F2 // fc400834 + FRSQRTECC F1, F2 // fc400835 + FSQRT F1, F2 // fc40082c + FSQRTCC F1, F2 // fc40082d + FSQRTS F1, F2 // ec40082c + FSQRTSCC F1, F2 // ec40082d + FCPSGN F1, F2 // fc420810 + FCPSGNCC F1, F2 // fc420811 + FCMPO F1, F2 // fc011040 + FCMPU F1, F2 // fc011000 + LVX (R3)(R4), V1 // 7c2418ce + LVXL (R3)(R4), V1 // 7c241ace + LVSL (R3)(R4), V1 // 7c24180c + LVSR (R3)(R4), V1 // 7c24184c + LVEBX (R3)(R4), V1 // 7c24180e + LVEHX (R3)(R4), V1 // 7c24184e + LVEWX (R3)(R4), V1 // 7c24188e + STVX V1, (R3)(R4) // 7c2419ce + STVXL V1, (R3)(R4) // 7c241bce + STVEBX V1, (R3)(R4) // 7c24190e + STVEHX V1, (R3)(R4) // 7c24194e + STVEWX V1, (R3)(R4) // 7c24198e -// LNOP freg comma // asm doesn't support the trailing comma. -// { -// outcode(int($1), &$2, 0, &nullgen); -// } - NOP F2 + VAND V1, V2, V3 // 10611404 + VANDC V1, V2, V3 // 10611444 + VNAND V1, V2, V3 // 10611584 + VOR V1, V2, V3 // 10611484 + VORC V1, V2, V3 // 10611544 + VXOR V1, V2, V3 // 106114c4 + VNOR V1, V2, V3 // 10611504 + VEQV V1, V2, V3 // 10611684 + VADDUBM V1, V2, V3 // 10611000 + VADDUHM V1, V2, V3 // 10611040 + VADDUWM V1, V2, V3 // 10611080 + VADDUDM V1, V2, V3 // 106110c0 + VADDUQM V1, V2, V3 // 10611100 + VADDCUQ V1, V2, V3 // 10611140 + VADDCUW V1, V2, V3 // 10611180 + VADDUBS V1, V2, V3 // 10611200 + VADDUHS V1, V2, V3 // 10611240 + VADDUWS V1, V2, V3 // 10611280 + VSUBUBM V1, V2, V3 // 10611400 + VSUBUHM V1, V2, V3 // 10611440 + VSUBUWM V1, V2, V3 // 10611480 + VSUBUDM V1, V2, V3 // 106114c0 + VSUBUQM V1, V2, V3 // 10611500 + VSUBCUQ V1, V2, V3 // 10611540 + VSUBCUW V1, V2, V3 // 10611580 + VSUBUBS V1, V2, V3 // 10611600 + VSUBUHS V1, V2, V3 // 10611640 + VSUBUWS V1, V2, V3 // 10611680 + VSUBSBS V1, V2, V3 // 10611700 + VSUBSHS V1, V2, V3 // 10611740 + VSUBSWS V1, V2, V3 // 10611780 + VSUBEUQM V1, V2, V3, V4 // 108110fe + VSUBECUQ V1, V2, V3, V4 // 108110ff + VMULESB V1, V2, V3 // 10611308 + VMULOSB V1, V2, V3 // 10611108 + VMULEUB V1, V2, V3 // 10611208 + VMULOUB V1, V2, V3 // 10611008 + VMULESH V1, V2, V3 // 10611348 + VMULOSH V1, V2, V3 // 10611148 + VMULEUH V1, V2, V3 // 10611248 + VMULOUH V1, V2, V3 // 10611048 + VMULESH V1, V2, V3 // 10611348 + VMULOSW V1, V2, V3 // 10611188 + VMULEUW V1, V2, V3 // 10611288 + VMULOUW V1, V2, V3 // 10611088 + VMULUWM V1, V2, V3 // 10611089 + VPMSUMB V1, V2, V3 // 10611408 + VPMSUMH V1, V2, V3 // 10611448 + VPMSUMW V1, V2, V3 // 10611488 + VPMSUMD V1, V2, V3 // 106114c8 + VMSUMUDM V1, V2, V3, V4 // 108110e3 + VRLB V1, V2, V3 // 10611004 + VRLH V1, V2, V3 // 10611044 + VRLW V1, V2, V3 // 10611084 + VRLD V1, V2, V3 // 106110c4 + VSLB V1, V2, V3 // 10611104 + VSLH V1, V2, V3 // 10611144 + VSLW V1, V2, V3 // 10611184 + VSL V1, V2, V3 // 106111c4 + VSLO V1, V2, V3 // 1061140c + VSRB V1, V2, V3 // 10611204 + VSRH V1, V2, V3 // 10611244 + VSRW V1, V2, V3 // 10611284 + VSR V1, V2, V3 // 106112c4 + VSRO V1, V2, V3 // 1061144c + VSLD V1, V2, V3 // 106115c4 + VSRAB V1, V2, V3 // 10611304 + VSRAH V1, V2, V3 // 10611344 + VSRAW V1, V2, V3 // 10611384 + VSRAD V1, V2, V3 // 106113c4 + VSLDOI $3, V1, V2, V3 // 106110ec + VCLZB V1, V2 // 10400f02 + VCLZH V1, V2 // 10400f42 + VCLZW V1, V2 // 10400f82 + VCLZD V1, V2 // 10400fc2 + VPOPCNTB V1, V2 // 10400f03 + VPOPCNTH V1, V2 // 10400f43 + VPOPCNTW V1, V2 // 10400f83 + VPOPCNTD V1, V2 // 10400fc3 + VCMPEQUB V1, V2, V3 // 10611006 + VCMPEQUBCC V1, V2, V3 // 10611406 + VCMPEQUH V1, V2, V3 // 10611046 + VCMPEQUHCC V1, V2, V3 // 10611446 + VCMPEQUW V1, V2, V3 // 10611086 + VCMPEQUWCC V1, V2, V3 // 10611486 + VCMPEQUD V1, V2, V3 // 106110c7 + VCMPEQUDCC V1, V2, V3 // 106114c7 + VCMPGTUB V1, V2, V3 // 10611206 + VCMPGTUBCC V1, V2, V3 // 10611606 + VCMPGTUH V1, V2, V3 // 10611246 + VCMPGTUHCC V1, V2, V3 // 10611646 + VCMPGTUW V1, V2, V3 // 10611286 + VCMPGTUWCC V1, V2, V3 // 10611686 + VCMPGTUD V1, V2, V3 // 106112c7 + VCMPGTUDCC V1, V2, V3 // 106116c7 + VCMPGTSB V1, V2, V3 // 10611306 + VCMPGTSBCC V1, V2, V3 // 10611706 + VCMPGTSH V1, V2, V3 // 10611346 + VCMPGTSHCC V1, V2, V3 // 10611746 + VCMPGTSW V1, V2, V3 // 10611386 + VCMPGTSWCC V1, V2, V3 // 10611786 + VCMPGTSD V1, V2, V3 // 106113c7 + VCMPGTSDCC V1, V2, V3 // 106117c7 + VCMPNEZB V1, V2, V3 // 10611107 + VCMPNEZBCC V1, V2, V3 // 10611507 + VCMPNEB V1, V2, V3 // 10611007 + VCMPNEBCC V1, V2, V3 // 10611407 + VCMPNEH V1, V2, V3 // 10611047 + VCMPNEHCC V1, V2, V3 // 10611447 + VCMPNEW V1, V2, V3 // 10611087 + VCMPNEWCC V1, V2, V3 // 10611487 + VPERM V1, V2, V3, V4 // 108110eb + VPERMR V1, V2, V3, V4 // 108110fb + VPERMXOR V1, V2, V3, V4 // 108110ed + VBPERMQ V1, V2, V3 // 1061154c + VBPERMD V1, V2, V3 // 106115cc + VSEL V1, V2, V3, V4 // 108110ea + VSPLTB $1, V1, V2 // 10410a0c + VSPLTH $1, V1, V2 // 10410a4c + VSPLTW $1, V1, V2 // 10410a8c + VSPLTISB $1, V1 // 1021030c + VSPLTISW $1, V1 // 1021038c + VSPLTISH $1, V1 // 1021034c + VCIPHER V1, V2, V3 // 10611508 + VCIPHERLAST V1, V2, V3 // 10611509 + VNCIPHER V1, V2, V3 // 10611548 + VNCIPHERLAST V1, V2, V3 // 10611549 + VSBOX V1, V2 // 104105c8 + VSHASIGMAW $1, V1, $15, V2 // 10418e82 + VSHASIGMAD $2, V1, $15, V2 // 104196c2 -// LNOP ',' rreg // asm doesn't support the leading comma. -// { -// outcode(int($1), &nullgen, 0, &$3); -// } - NOP R2 + LXVD2X (R3)(R4), VS1 // 7c241e98 + LXVDSX (R3)(R4), VS1 // 7c241a98 + LXVH8X (R3)(R4), VS1 // 7c241e58 + LXVB16X (R3)(R4), VS1 // 7c241ed8 + LXVW4X (R3)(R4), VS1 // 7c241e18 + LXV 16(R3), VS1 // f4230011 + LXVL R3, R4, VS1 // 7c23221a + LXVLL R3, R4, VS1 // 7c23225a + LXVX R3, R4, VS1 // 7c232218 + LXSDX (R3)(R4), VS1 // 7c241c98 + STXVD2X VS1, (R3)(R4) // 7c241f98 + STXV VS1,16(R3) // f4230015 + STXVL VS1, R3, R4 // 7c23231a + STXVLL VS1, R3, R4 // 7c23235a + STXVX VS1, R3, R4 // 7c232318 + STXVB16X VS1, (R4)(R5) // 7c2527d8 + STXVH8X VS1, (R4)(R5) // 7c252758 -// LNOP ',' freg // asm doesn't support the leading comma. -// { -// outcode(int($1), &nullgen, 0, &$3); -// } - NOP F2 + STXSDX VS1, (R3)(R4) // 7c241d98 + LXSIWAX (R3)(R4), VS1 // 7c241898 + STXSIWX VS1, (R3)(R4) // 7c241918 + MFVSRD VS1, R3 // 7c230066 + MTFPRD R3, F0 // 7c030166 + MFVRD V0, R3 // 7c030067 + MFVSRLD VS63,R4 // 7fe40267 + MFVSRWZ VS33,R4 // 7c2400e7 + MTVSRD R3, VS1 // 7c230166 + MTVRD R3, V13 // 7da30167 + MTVSRWA R4, VS31 // 7fe401a6 + MTVSRWS R4, VS32 // 7c040327 + MTVSRWZ R4, VS63 // 7fe401e7 + XXBRD VS0, VS1 // f037076c + XXBRW VS1, VS2 // f04f0f6c + XXBRH VS2, VS3 // f067176c + XXLAND VS1, VS2, VS3 // f0611410 + XXLANDC VS1, VS2, VS3 // f0611450 + XXLEQV VS0, VS1, VS2 // f0400dd0 + XXLNAND VS0, VS1, VS2 // f0400d90 + XXLNOR VS0, VS1, VS32 // f0000d11 + XXLOR VS1, VS2, VS3 // f0611490 + XXLORC VS1, VS2, VS3 // f0611550 + XXLORQ VS1, VS2, VS3 // f0611490 + XXLXOR VS1, VS2, VS3 // f06114d0 + XXSEL VS1, VS2, VS3, VS4 // f08110f0 + XXMRGHW VS1, VS2, VS3 // f0611090 + XXMRGLW VS1, VS2, VS3 // f0611190 + XXSPLTW VS1, $1, VS2 // f0410a90 + XXPERM VS1, VS2, VS3 // f06110d0 + XXSLDWI VS1, VS2, $1, VS3 // f0611110 + XSCVDPSP VS1, VS2 // f0400c24 + XVCVDPSP VS1, VS2 // f0400e24 + XSCVSXDDP VS1, VS2 // f0400de0 + XVCVDPSXDS VS1, VS2 // f0400f60 + XVCVSXDDP VS1, VS2 // f0400fe0 + XSCVDPSPN VS1,VS32 // f0000c2d + XSCVDPSP VS1,VS32 // f0000c25 + XSCVDPSXDS VS1,VS32 // f0000d61 + XSCVDPSXWS VS1,VS32 // f0000961 + XSCVDPUXDS VS1,VS32 // f0000d21 + XSCVDPUXWS VS1,VS32 // f0000921 + XSCVSPDPN VS1,VS32 // f0000d2d + XSCVSPDP VS1,VS32 // f0000d25 + XSCVSXDDP VS1,VS32 // f0000de1 + XSCVSXDSP VS1,VS32 // f0000ce1 + XSCVUXDDP VS1,VS32 // f0000da1 + XSCVUXDSP VS1,VS32 // f0000ca1 + XVCVDPSP VS1,VS32 // f0000e25 + XVCVDPSXDS VS1,VS32 // f0000f61 + XVCVDPSXWS VS1,VS32 // f0000b61 + XVCVDPUXDS VS1,VS32 // f0000f21 + XVCVDPUXWS VS1,VS32 // f0000b21 + XVCVSPDP VS1,VS32 // f0000f25 + XVCVSPSXDS VS1,VS32 // f0000e61 + XVCVSPSXWS VS1,VS32 // f0000a61 + XVCVSPUXDS VS1,VS32 // f0000e21 + XVCVSPUXWS VS1,VS32 // f0000a21 + XVCVSXDDP VS1,VS32 // f0000fe1 + XVCVSXDSP VS1,VS32 // f0000ee1 + XVCVSXWDP VS1,VS32 // f0000be1 + XVCVSXWSP VS1,VS32 // f0000ae1 + XVCVUXDDP VS1,VS32 // f0000fa1 + XVCVUXDSP VS1,VS32 // f0000ea1 + XVCVUXWDP VS1,VS32 // f0000ba1 + XVCVUXWSP VS1,VS32 // f0000aa1 -// LNOP imm // SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. -// { -// outcode(int($1), &$2, 0, &nullgen); -// } - NOP $4 + MOVD R3, LR // 7c6803a6 + MOVD R3, CTR // 7c6903a6 + MOVD R3, XER // 7c6103a6 + MOVD LR, R3 // 7c6802a6 + MOVD CTR, R3 // 7c6902a6 + MOVD XER, R3 // 7c6102a6 + MOVFL CR3, CR1 // 4c8c0000 -// RET -// -// LRETRN comma // asm doesn't support the trailing comma. -// { -// outcode(int($1), &nullgen, 0, &nullgen); -// } - BEQ 2(PC) RET - -// More BR/BL cases, and canonical names JMP, CALL. - - BEQ 2(PC) - BR foo(SB) // JMP foo(SB) - BL foo(SB) // CALL foo(SB) - BEQ 2(PC) - JMP foo(SB) - CALL foo(SB) - RET foo(SB) - -// load-and-reserve -// L*AR (RB)(RA*1),EH,RT produces -// l*arx RT,RA,RB,EH -// -// Extended forms also accepted. Assumes RA=0, EH=0: -// L*AR (RB),RT -// L*AR (RB),EH,RT - LBAR (R4)(R3*1), $1, R5 - LBAR (R4), $0, R5 - LBAR (R3), R5 - LHAR (R4)(R3*1), $1, R5 - LHAR (R4), $0, R5 - LHAR (R3), R5 - LWAR (R4)(R3*1), $1, R5 - LWAR (R4), $0, R5 - LWAR (R3), R5 - LDAR (R4)(R3*1), $1, R5 - LDAR (R4), $0, R5 - LDAR (R3), R5 - -// END -// -// LEND comma // asm doesn't support the trailing comma. -// { -// outcode(int($1), &nullgen, 0, &nullgen); -// } - END diff --git a/src/cmd/asm/internal/asm/testdata/ppc64enc.s b/src/cmd/asm/internal/asm/testdata/ppc64enc.s deleted file mode 100644 index 10a05ec402..0000000000 --- a/src/cmd/asm/internal/asm/testdata/ppc64enc.s +++ /dev/null @@ -1,633 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Initial set of opcode combinations based on -// improvements to processing of constant -// operands. - -// Full set will be added at a later date. - -#include "../../../../../runtime/textflag.h" - -TEXT asmtest(SB),DUPOK|NOSPLIT,$0 - // move constants - MOVD $1, R3 // 38600001 - MOVD $-1, R4 // 3880ffff - MOVD $65535, R5 // 6005ffff - MOVD $65536, R6 // 64060001 - MOVD $-32767, R5 // 38a08001 - MOVD $-32768, R6 // 38c08000 - MOVD $1234567, R5 // 6405001260a5d687 - MOVW $1, R3 // 38600001 - MOVW $-1, R4 // 3880ffff - MOVW $65535, R5 // 6005ffff - MOVW $65536, R6 // 64060001 - MOVW $-32767, R5 // 38a08001 - MOVW $-32768, R6 // 38c08000 - MOVW $1234567, R5 // 6405001260a5d687 - MOVD 8(R3), R4 // e8830008 - MOVD (R3)(R4), R5 // 7ca4182a - MOVW 4(R3), R4 // e8830006 - MOVW (R3)(R4), R5 // 7ca41aaa - MOVWZ 4(R3), R4 // 80830004 - MOVWZ (R3)(R4), R5 // 7ca4182e - MOVH 4(R3), R4 // a8830004 - MOVH (R3)(R4), R5 // 7ca41aae - MOVHZ 2(R3), R4 // a0830002 - MOVHZ (R3)(R4), R5 // 7ca41a2e - MOVB 1(R3), R4 // 888300017c840774 - MOVB (R3)(R4), R5 // 7ca418ae7ca50774 - MOVBZ 1(R3), R4 // 88830001 - MOVBZ (R3)(R4), R5 // 7ca418ae - MOVDBR (R3)(R4), R5 // 7ca41c28 - MOVWBR (R3)(R4), R5 // 7ca41c2c - MOVHBR (R3)(R4), R5 // 7ca41e2c - - MOVDU 8(R3), R4 // e8830009 - MOVDU (R3)(R4), R5 // 7ca4186a - MOVWU (R3)(R4), R5 // 7ca41aea - MOVWZU 4(R3), R4 // 84830004 - MOVWZU (R3)(R4), R5 // 7ca4186e - MOVHU 2(R3), R4 // ac830002 - MOVHU (R3)(R4), R5 // 7ca41aee - MOVHZU 2(R3), R4 // a4830002 - MOVHZU (R3)(R4), R5 // 7ca41a6e - MOVBU 1(R3), R4 // 8c8300017c840774 - MOVBU (R3)(R4), R5 // 7ca418ee7ca50774 - MOVBZU 1(R3), R4 // 8c830001 - MOVBZU (R3)(R4), R5 // 7ca418ee - - MOVD R4, 8(R3) // f8830008 - MOVD R5, (R3)(R4) // 7ca4192a - MOVW R4, 4(R3) // 90830004 - MOVW R5, (R3)(R4) // 7ca4192e - MOVH R4, 2(R3) // b0830002 - MOVH R5, (R3)(R4) // 7ca41b2e - MOVB R4, 1(R3) // 98830001 - MOVB R5, (R3)(R4) // 7ca419ae - MOVDBR R5, (R3)(R4) // 7ca41d28 - MOVWBR R5, (R3)(R4) // 7ca41d2c - MOVHBR R5, (R3)(R4) // 7ca41f2c - - MOVDU R4, 8(R3) // f8830009 - MOVDU R5, (R3)(R4) // 7ca4196a - MOVWU R4, 4(R3) // 94830004 - MOVWU R5, (R3)(R4) // 7ca4196e - MOVHU R4, 2(R3) // b4830002 - MOVHU R5, (R3)(R4) // 7ca41b6e - MOVBU R4, 1(R3) // 9c830001 - MOVBU R5, (R3)(R4) // 7ca419ee - - ADD $1, R3 // 38630001 - ADD $1, R3, R4 // 38830001 - ADD $-1, R4 // 3884ffff - ADD $-1, R4, R5 // 38a4ffff - ADD $65535, R5 // 601fffff7cbf2a14 - ADD $65535, R5, R6 // 601fffff7cdf2a14 - ADD $65536, R6 // 3cc60001 - ADD $65536, R6, R7 // 3ce60001 - ADD $-32767, R5 // 38a58001 - ADD $-32767, R5, R4 // 38858001 - ADD $-32768, R6 // 38c68000 - ADD $-32768, R6, R5 // 38a68000 - ADD $1234567, R5 // 641f001263ffd6877cbf2a14 - ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14 - ADDIS $8, R3 // 3c630008 - ADDIS $1000, R3, R4 // 3c8303e8 - - ANDCC $1, R3 // 70630001 - ANDCC $1, R3, R4 // 70640001 - ANDCC $-1, R4 // 3be0ffff7fe42039 - ANDCC $-1, R4, R5 // 3be0ffff7fe52039 - ANDCC $65535, R5 // 70a5ffff - ANDCC $65535, R5, R6 // 70a6ffff - ANDCC $65536, R6 // 74c60001 - ANDCC $65536, R6, R7 // 74c70001 - ANDCC $-32767, R5 // 3be080017fe52839 - ANDCC $-32767, R5, R4 // 3be080017fe42839 - ANDCC $-32768, R6 // 3be080007fe63039 - ANDCC $-32768, R5, R6 // 3be080007fe62839 - ANDCC $1234567, R5 // 641f001263ffd6877fe52839 - ANDCC $1234567, R5, R6 // 641f001263ffd6877fe62839 - ANDISCC $1, R3 // 74630001 - ANDISCC $1000, R3, R4 // 746403e8 - - OR $1, R3 // 60630001 - OR $1, R3, R4 // 60640001 - OR $-1, R4 // 3be0ffff7fe42378 - OR $-1, R4, R5 // 3be0ffff7fe52378 - OR $65535, R5 // 60a5ffff - OR $65535, R5, R6 // 60a6ffff - OR $65536, R6 // 64c60001 - OR $65536, R6, R7 // 64c70001 - OR $-32767, R5 // 3be080017fe52b78 - OR $-32767, R5, R6 // 3be080017fe62b78 - OR $-32768, R6 // 3be080007fe63378 - OR $-32768, R6, R7 // 3be080007fe73378 - OR $1234567, R5 // 641f001263ffd6877fe52b78 - OR $1234567, R5, R3 // 641f001263ffd6877fe32b78 - - XOR $1, R3 // 68630001 - XOR $1, R3, R4 // 68640001 - XOR $-1, R4 // 3be0ffff7fe42278 - XOR $-1, R4, R5 // 3be0ffff7fe52278 - XOR $65535, R5 // 68a5ffff - XOR $65535, R5, R6 // 68a6ffff - XOR $65536, R6 // 6cc60001 - XOR $65536, R6, R7 // 6cc70001 - XOR $-32767, R5 // 3be080017fe52a78 - XOR $-32767, R5, R6 // 3be080017fe62a78 - XOR $-32768, R6 // 3be080007fe63278 - XOR $-32768, R6, R7 // 3be080007fe73278 - XOR $1234567, R5 // 641f001263ffd6877fe52a78 - XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78 - - // TODO: the order of CR operands don't match - CMP R3, R4 // 7c232000 - CMPU R3, R4 // 7c232040 - CMPW R3, R4 // 7c032000 - CMPWU R3, R4 // 7c032040 - - // TODO: constants for ADDC? - ADD R3, R4 // 7c841a14 - ADD R3, R4, R5 // 7ca41a14 - ADDC R3, R4 // 7c841814 - ADDC R3, R4, R5 // 7ca41814 - ADDE R3, R4 // 7c841914 - ADDECC R3, R4 // 7c841915 - ADDEV R3, R4 // 7c841d14 - ADDEVCC R3, R4 // 7c841d15 - ADDV R3, R4 // 7c841e14 - ADDVCC R3, R4 // 7c841e15 - ADDCCC R3, R4, R5 // 7ca41815 - ADDME R3, R4 // 7c8301d4 - ADDMECC R3, R4 // 7c8301d5 - ADDMEV R3, R4 // 7c8305d4 - ADDMEVCC R3, R4 // 7c8305d5 - ADDCV R3, R4 // 7c841c14 - ADDCVCC R3, R4 // 7c841c15 - ADDZE R3, R4 // 7c830194 - ADDZECC R3, R4 // 7c830195 - ADDZEV R3, R4 // 7c830594 - ADDZEVCC R3, R4 // 7c830595 - SUBME R3, R4 // 7c8301d0 - SUBMECC R3, R4 // 7c8301d1 - SUBMEV R3, R4 // 7c8305d0 - SUBZE R3, R4 // 7c830190 - SUBZECC R3, R4 // 7c830191 - SUBZEV R3, R4 // 7c830590 - SUBZEVCC R3, R4 // 7c830591 - - AND R3, R4 // 7c841838 - AND R3, R4, R5 // 7c851838 - ANDN R3, R4, R5 // 7c851878 - ANDCC R3, R4, R5 // 7c851839 - OR R3, R4 // 7c841b78 - OR R3, R4, R5 // 7c851b78 - ORN R3, R4, R5 // 7c851b38 - ORCC R3, R4, R5 // 7c851b79 - XOR R3, R4 // 7c841a78 - XOR R3, R4, R5 // 7c851a78 - XORCC R3, R4, R5 // 7c851a79 - NAND R3, R4, R5 // 7c851bb8 - NANDCC R3, R4, R5 // 7c851bb9 - EQV R3, R4, R5 // 7c851a38 - EQVCC R3, R4, R5 // 7c851a39 - NOR R3, R4, R5 // 7c8518f8 - NORCC R3, R4, R5 // 7c8518f9 - - SUB R3, R4 // 7c832050 - SUB R3, R4, R5 // 7ca32050 - SUBC R3, R4 // 7c832010 - SUBC R3, R4, R5 // 7ca32010 - - MULLW R3, R4 // 7c8419d6 - MULLW R3, R4, R5 // 7ca419d6 - MULLWCC R3, R4, R5 // 7ca419d7 - MULHW R3, R4, R5 // 7ca41896 - - MULHWU R3, R4, R5 // 7ca41816 - MULLD R3, R4 // 7c8419d2 - MULLD R4, R4, R5 // 7ca421d2 - MULLDCC R3, R4, R5 // 7ca419d3 - MULHD R3, R4, R5 // 7ca41892 - MULHDCC R3, R4, R5 // 7ca41893 - - MULLWV R3, R4 // 7c841dd6 - MULLWV R3, R4, R5 // 7ca41dd6 - MULLWVCC R3, R4, R5 // 7ca41dd7 - MULHWUCC R3, R4, R5 // 7ca41817 - MULLDV R3, R4, R5 // 7ca41dd2 - MULLDVCC R3, R4, R5 // 7ca41dd3 - - DIVD R3,R4 // 7c841bd2 - DIVD R3, R4, R5 // 7ca41bd2 - DIVDCC R3,R4, R5 // 7ca41bd3 - DIVDU R3, R4, R5 // 7ca41b92 - DIVDV R3, R4, R5 // 7ca41fd2 - DIVDUCC R3, R4, R5 // 7ca41b93 - DIVDVCC R3, R4, R5 // 7ca41fd3 - DIVDUV R3, R4, R5 // 7ca41f92 - DIVDUVCC R3, R4, R5 // 7ca41f93 - DIVDE R3, R4, R5 // 7ca41b52 - DIVDECC R3, R4, R5 // 7ca41b53 - DIVDEU R3, R4, R5 // 7ca41b12 - DIVDEUCC R3, R4, R5 // 7ca41b13 - - REM R3, R4, R5 // 7fe41bd67fff19d67cbf2050 - REMU R3, R4, R5 // 7fe41b967fff19d67bff00287cbf2050 - REMD R3, R4, R5 // 7fe41bd27fff19d27cbf2050 - REMDU R3, R4, R5 // 7fe41b927fff19d27cbf2050 - - MODUD R3, R4, R5 // 7ca41a12 - MODUW R3, R4, R5 // 7ca41a16 - MODSD R3, R4, R5 // 7ca41e12 - MODSW R3, R4, R5 // 7ca41e16 - - SLW $8, R3, R4 // 5464402e - SLW R3, R4, R5 // 7c851830 - SLWCC R3, R4 // 7c841831 - SLD $16, R3, R4 // 786483e4 - SLD R3, R4, R5 // 7c851836 - SLDCC R3, R4 // 7c841837 - - SRW $8, R3, R4 // 5464c23e - SRW R3, R4, R5 // 7c851c30 - SRWCC R3, R4 // 7c841c31 - SRAW $8, R3, R4 // 7c644670 - SRAW R3, R4, R5 // 7c851e30 - SRAWCC R3, R4 // 7c841e31 - SRD $16, R3, R4 // 78648402 - SRD R3, R4, R5 // 7c851c36 - SRDCC R3, R4 // 7c841c37 - SRAD $16, R3, R4 // 7c648674 - SRAD R3, R4, R5 // 7c851e34 - SRDCC R3, R4 // 7c841c37 - ROTLW $16, R3, R4 // 5464803e - ROTLW R3, R4, R5 // 5c85183e - RLWMI $7, R3, $65535, R6 // 50663c3e - RLWMICC $7, R3, $65535, R6 // 50663c3f - RLWNM $3, R4, $7, R6 // 54861f7e - RLWNMCC $3, R4, $7, R6 // 54861f7f - RLDMI $0, R4, $7, R6 // 7886076c - RLDMICC $0, R4, $7, R6 // 7886076d - RLDIMI $0, R4, $7, R6 // 788601cc - RLDIMICC $0, R4, $7, R6 // 788601cd - RLDC $0, R4, $15, R6 // 78860728 - RLDCCC $0, R4, $15, R6 // 78860729 - RLDCL $0, R4, $7, R6 // 78860770 - RLDCLCC $0, R4, $15, R6 // 78860721 - RLDCR $0, R4, $-16, R6 // 788606f2 - RLDCRCC $0, R4, $-16, R6 // 788606f3 - RLDICL $0, R4, $15, R6 // 788603c0 - RLDICLCC $0, R4, $15, R6 // 788603c1 - RLDICR $0, R4, $15, R6 // 788603c4 - RLDICRCC $0, R4, $15, R6 // 788603c5 - - BEQ 0(PC) // 41820000 - BGE 0(PC) // 40800000 - BGT 4(PC) // 41810030 - BLE 0(PC) // 40810000 - BLT 0(PC) // 41800000 - BNE 0(PC) // 40820000 - JMP 8(PC) // 48000020 - - CRAND CR1, CR2, CR3 // 4c620a02 - CRANDN CR1, CR2, CR3 // 4c620902 - CREQV CR1, CR2, CR3 // 4c620a42 - CRNAND CR1, CR2, CR3 // 4c6209c2 - CRNOR CR1, CR2, CR3 // 4c620842 - CROR CR1, CR2, CR3 // 4c620b82 - CRORN CR1, CR2, CR3 // 4c620b42 - CRXOR CR1, CR2, CR3 // 4c620982 - - ISEL $1, R3, R4, R5 // 7ca3205e - ISEL $0, R3, R4, R5 // 7ca3201e - ISEL $2, R3, R4, R5 // 7ca3209e - ISEL $3, R3, R4, R5 // 7ca320de - ISEL $4, R3, R4, R5 // 7ca3211e - POPCNTB R3, R4 // 7c6400f4 - POPCNTW R3, R4 // 7c6402f4 - POPCNTD R3, R4 // 7c6403f4 - - PASTECC R3, R4 // 7c23270d - COPY R3, R4 // 7c23260c - - // load-and-reserve - LBAR (R4)(R3*1),$1,R5 // 7ca32069 - LBAR (R4),$0,R5 // 7ca02068 - LBAR (R3),R5 // 7ca01868 - LHAR (R4)(R3*1),$1,R5 // 7ca320e9 - LHAR (R4),$0,R5 // 7ca020e8 - LHAR (R3),R5 // 7ca018e8 - LWAR (R4)(R3*1),$1,R5 // 7ca32029 - LWAR (R4),$0,R5 // 7ca02028 - LWAR (R3),R5 // 7ca01828 - LDAR (R4)(R3*1),$1,R5 // 7ca320a9 - LDAR (R4),$0,R5 // 7ca020a8 - LDAR (R3),R5 // 7ca018a8 - - STBCCC R3, (R4)(R5) // 7c65256d - STWCCC R3, (R4)(R5) // 7c65212d - STDCCC R3, (R4)(R5) // 7c6521ad - STHCCC R3, (R4)(R5) - - SYNC // 7c0004ac - ISYNC // 4c00012c - LWSYNC // 7c2004ac - - DCBF (R3)(R4) // 7c0418ac - DCBI (R3)(R4) // 7c041bac - DCBST (R3)(R4) // 7c04186c - DCBZ (R3)(R4) // 7c041fec - DCBT (R3)(R4) // 7c041a2c - ICBI (R3)(R4) // 7c041fac - - // float constants - FMOVD $(0.0), F1 // f0210cd0 - FMOVD $(-0.0), F1 // f0210cd0fc200850 - - FMOVD 8(R3), F1 // c8230008 - FMOVD (R3)(R4), F1 // 7c241cae - FMOVDU 8(R3), F1 // cc230008 - FMOVDU (R3)(R4), F1 // 7c241cee - FMOVS 4(R3), F1 // c0230004 - FMOVS (R3)(R4), F1 // 7c241c2e - FMOVSU 4(R3), F1 // c4230004 - FMOVSU (R3)(R4), F1 // 7c241c6e - - FMOVD F1, 8(R3) // d8230008 - FMOVD F1, (R3)(R4) // 7c241dae - FMOVDU F1, 8(R3) // dc230008 - FMOVDU F1, (R3)(R4) // 7c241dee - FMOVS F1, 4(R3) // d0230004 - FMOVS F1, (R3)(R4) // 7c241d2e - FMOVSU F1, 4(R3) // d4230004 - FMOVSU F1, (R3)(R4) // 7c241d6e - FADD F1, F2 // fc42082a - FADD F1, F2, F3 // fc62082a - FADDCC F1, F2, F3 // fc62082b - FADDS F1, F2 // ec42082a - FADDS F1, F2, F3 // ec62082a - FADDSCC F1, F2, F3 // ec62082b - FSUB F1, F2 // fc420828 - FSUB F1, F2, F3 // fc620828 - FSUBCC F1, F2, F3 // fc620829 - FSUBS F1, F2 // ec420828 - FSUBS F1, F2, F3 // ec620828 - FSUBCC F1, F2, F3 // fc620829 - FMUL F1, F2 // fc420072 - FMUL F1, F2, F3 // fc620072 - FMULCC F1, F2, F3 // fc620073 - FMULS F1, F2 // ec420072 - FMULS F1, F2, F3 // ec620072 - FMULSCC F1, F2, F3 // ec620073 - FDIV F1, F2 // fc420824 - FDIV F1, F2, F3 // fc620824 - FDIVCC F1, F2, F3 // fc620825 - FDIVS F1, F2 // ec420824 - FDIVS F1, F2, F3 // ec620824 - FDIVSCC F1, F2, F3 // ec620825 - FMADD F1, F2, F3, F4 // fc8110fa - FMADDCC F1, F2, F3, F4 // fc8110fb - FMADDS F1, F2, F3, F4 // ec8110fa - FMADDSCC F1, F2, F3, F4 // ec8110fb - FMSUB F1, F2, F3, F4 // fc8110f8 - FMSUBCC F1, F2, F3, F4 // fc8110f9 - FMSUBS F1, F2, F3, F4 // ec8110f8 - FMSUBSCC F1, F2, F3, F4 // ec8110f9 - FNMADD F1, F2, F3, F4 // fc8110fe - FNMADDCC F1, F2, F3, F4 // fc8110ff - FNMADDS F1, F2, F3, F4 // ec8110fe - FNMADDSCC F1, F2, F3, F4 // ec8110ff - FNMSUB F1, F2, F3, F4 // fc8110fc - FNMSUBCC F1, F2, F3, F4 // fc8110fd - FNMSUBS F1, F2, F3, F4 // ec8110fc - FNMSUBSCC F1, F2, F3, F4 // ec8110fd - FSEL F1, F2, F3, F4 // fc8110ee - FSELCC F1, F2, F3, F4 // fc8110ef - FABS F1, F2 // fc400a10 - FABSCC F1, F2 // fc400a11 - FNEG F1, F2 // fc400850 - FABSCC F1, F2 // fc400a11 - FRSP F1, F2 // fc400818 - FRSPCC F1, F2 // fc400819 - FCTIW F1, F2 // fc40081c - FCTIWCC F1, F2 // fc40081d - FCTIWZ F1, F2 // fc40081e - FCTIWZCC F1, F2 // fc40081f - FCTID F1, F2 // fc400e5c - FCTIDCC F1, F2 // fc400e5d - FCTIDZ F1, F2 // fc400e5e - FCTIDZCC F1, F2 // fc400e5f - FCFID F1, F2 // fc400e9c - FCFIDCC F1, F2 // fc400e9d - FCFIDU F1, F2 // fc400f9c - FCFIDUCC F1, F2 // fc400f9d - FCFIDS F1, F2 // ec400e9c - FCFIDSCC F1, F2 // ec400e9d - FRES F1, F2 // ec400830 - FRESCC F1, F2 // ec400831 - FRIM F1, F2 // fc400bd0 - FRIMCC F1, F2 // fc400bd1 - FRIP F1, F2 // fc400b90 - FRIPCC F1, F2 // fc400b91 - FRIZ F1, F2 // fc400b50 - FRIZCC F1, F2 // fc400b51 - FRIN F1, F2 // fc400b10 - FRINCC F1, F2 // fc400b11 - FRSQRTE F1, F2 // fc400834 - FRSQRTECC F1, F2 // fc400835 - FSQRT F1, F2 // fc40082c - FSQRTCC F1, F2 // fc40082d - FSQRTS F1, F2 // ec40082c - FSQRTSCC F1, F2 // ec40082d - FCPSGN F1, F2 // fc420810 - FCPSGNCC F1, F2 // fc420811 - FCMPO F1, F2 // fc011040 - FCMPU F1, F2 // fc011000 - LVX (R3)(R4), V1 // 7c2418ce - LVXL (R3)(R4), V1 // 7c241ace - LVSL (R3)(R4), V1 // 7c24180c - LVSR (R3)(R4), V1 // 7c24184c - LVEBX (R3)(R4), V1 // 7c24180e - LVEHX (R3)(R4), V1 // 7c24184e - LVEWX (R3)(R4), V1 // 7c24188e - STVX V1, (R3)(R4) // 7c2419ce - STVXL V1, (R3)(R4) // 7c241bce - STVEBX V1, (R3)(R4) // 7c24190e - STVEHX V1, (R3)(R4) // 7c24194e - STVEWX V1, (R3)(R4) // 7c24198e - - VAND V1, V2, V3 // 10611404 - VANDC V1, V2, V3 // 10611444 - VNAND V1, V2, V3 // 10611584 - VOR V1, V2, V3 // 10611484 - VORC V1, V2, V3 // 10611544 - VXOR V1, V2, V3 // 106114c4 - VNOR V1, V2, V3 // 10611504 - VEQV V1, V2, V3 // 10611684 - VADDUBM V1, V2, V3 // 10611000 - VADDUHM V1, V2, V3 // 10611040 - VADDUWM V1, V2, V3 // 10611080 - VADDUDM V1, V2, V3 // 106110c0 - VADDUQM V1, V2, V3 // 10611100 - VADDCUQ V1, V2, V3 // 10611140 - VADDCUW V1, V2, V3 // 10611180 - VADDUBS V1, V2, V3 // 10611200 - VADDUHS V1, V2, V3 // 10611240 - VADDUWS V1, V2, V3 // 10611280 - VSUBUBM V1, V2, V3 // 10611400 - VSUBUHM V1, V2, V3 // 10611440 - VSUBUWM V1, V2, V3 // 10611480 - VSUBUDM V1, V2, V3 // 106114c0 - VSUBUQM V1, V2, V3 // 10611500 - VSUBCUQ V1, V2, V3 // 10611540 - VSUBCUW V1, V2, V3 // 10611580 - VSUBUBS V1, V2, V3 // 10611600 - VSUBUHS V1, V2, V3 // 10611640 - VSUBUWS V1, V2, V3 // 10611680 - VSUBSBS V1, V2, V3 // 10611700 - VSUBSHS V1, V2, V3 // 10611740 - VSUBSWS V1, V2, V3 // 10611780 - VSUBEUQM V1, V2, V3, V4 // 108110fe - VSUBECUQ V1, V2, V3, V4 // 108110ff - VMULESB V1, V2, V3 // 10611308 - VMULOSB V1, V2, V3 // 10611108 - VMULEUB V1, V2, V3 // 10611208 - VMULOUB V1, V2, V3 // 10611008 - VMULESH V1, V2, V3 // 10611348 - VMULOSH V1, V2, V3 // 10611148 - VMULEUH V1, V2, V3 // 10611248 - VMULOUH V1, V2, V3 // 10611048 - VMULESH V1, V2, V3 // 10611348 - VMULOSW V1, V2, V3 // 10611188 - VMULEUW V1, V2, V3 // 10611288 - VMULOUW V1, V2, V3 // 10611088 - VMULUWM V1, V2, V3 // 10611089 - VPMSUMB V1, V2, V3 // 10611408 - VPMSUMH V1, V2, V3 // 10611448 - VPMSUMW V1, V2, V3 // 10611488 - VPMSUMD V1, V2, V3 // 106114c8 - VMSUMUDM V1, V2, V3, V4 // 108110e3 - VRLB V1, V2, V3 // 10611004 - VRLH V1, V2, V3 // 10611044 - VRLW V1, V2, V3 // 10611084 - VRLD V1, V2, V3 // 106110c4 - VSLB V1, V2, V3 // 10611104 - VSLH V1, V2, V3 // 10611144 - VSLW V1, V2, V3 // 10611184 - VSL V1, V2, V3 // 106111c4 - VSLO V1, V2, V3 // 1061140c - VSRB V1, V2, V3 // 10611204 - VSRH V1, V2, V3 // 10611244 - VSRW V1, V2, V3 // 10611284 - VSR V1, V2, V3 // 106112c4 - VSRO V1, V2, V3 // 1061144c - VSLD V1, V2, V3 // 106115c4 - VSRAB V1, V2, V3 // 10611304 - VSRAH V1, V2, V3 // 10611344 - VSRAW V1, V2, V3 // 10611384 - VSRAD V1, V2, V3 // 106113c4 - VSLDOI $3, V1, V2, V3 // 106110ec - VCLZB V1, V2 // 10400f02 - VCLZH V1, V2 // 10400f42 - VCLZW V1, V2 // 10400f82 - VCLZD V1, V2 // 10400fc2 - VPOPCNTB V1, V2 // 10400f03 - VPOPCNTH V1, V2 // 10400f43 - VPOPCNTW V1, V2 // 10400f83 - VPOPCNTD V1, V2 // 10400fc3 - VCMPEQUB V1, V2, V3 // 10611006 - VCMPEQUBCC V1, V2, V3 // 10611406 - VCMPEQUH V1, V2, V3 // 10611046 - VCMPEQUHCC V1, V2, V3 // 10611446 - VCMPEQUW V1, V2, V3 // 10611086 - VCMPEQUWCC V1, V2, V3 // 10611486 - VCMPEQUD V1, V2, V3 // 106110c7 - VCMPEQUDCC V1, V2, V3 // 106114c7 - VCMPGTUB V1, V2, V3 // 10611206 - VCMPGTUBCC V1, V2, V3 // 10611606 - VCMPGTUH V1, V2, V3 // 10611246 - VCMPGTUHCC V1, V2, V3 // 10611646 - VCMPGTUW V1, V2, V3 // 10611286 - VCMPGTUWCC V1, V2, V3 // 10611686 - VCMPGTUD V1, V2, V3 // 106112c7 - VCMPGTUDCC V1, V2, V3 // 106116c7 - VCMPGTSB V1, V2, V3 // 10611306 - VCMPGTSBCC V1, V2, V3 // 10611706 - VCMPGTSH V1, V2, V3 // 10611346 - VCMPGTSHCC V1, V2, V3 // 10611746 - VCMPGTSW V1, V2, V3 // 10611386 - VCMPGTSWCC V1, V2, V3 // 10611786 - VCMPGTSD V1, V2, V3 // 106113c7 - VCMPGTSDCC V1, V2, V3 // 106117c7 - VCMPNEZB V1, V2, V3 // 10611107 - VCMPNEZBCC V1, V2, V3 // 10611507 - VCMPNEB V1, V2, V3 // 10611007 - VCMPNEBCC V1, V2, V3 // 10611407 - VCMPNEH V1, V2, V3 // 10611047 - VCMPNEHCC V1, V2, V3 // 10611447 - VCMPNEW V1, V2, V3 // 10611087 - VCMPNEWCC V1, V2, V3 // 10611487 - VPERM V1, V2, V3, V4 // 108110eb - VPERMR V1, V2, V3, V4 // 108110fb - VPERMXOR V1, V2, V3, V4 // 108110ed - VBPERMQ V1, V2, V3 // 1061154c - VBPERMD V1, V2, V3 // 106115cc - VSEL V1, V2, V3, V4 // 108110ea - VSPLTB $1, V1, V2 // 10410a0c - VSPLTH $1, V1, V2 // 10410a4c - VSPLTW $1, V1, V2 // 10410a8c - VSPLTISB $1, V1 // 1021030c - VSPLTISW $1, V1 // 1021038c - VSPLTISH $1, V1 // 1021034c - VCIPHER V1, V2, V3 // 10611508 - VCIPHERLAST V1, V2, V3 // 10611509 - VNCIPHER V1, V2, V3 // 10611548 - VNCIPHERLAST V1, V2, V3 // 10611549 - VSBOX V1, V2 // 104105c8 - VSHASIGMAW $1, V1, $15, V2 // 10418e82 - VSHASIGMAD $2, V1, $15, V2 // 104196c2 - - LXVD2X (R3)(R4), VS1 // 7c241e98 - LXV 16(R3), VS1 // f4230011 - LXVL R3, R4, VS1 // 7c23221a - LXVLL R3, R4, VS1 // 7c23225a - LXVX R3, R4, VS1 // 7c232218 - LXSDX (R3)(R4), VS1 // 7c241c98 - STXVD2X VS1, (R3)(R4) // 7c241f98 - STXV VS1,16(R3) // f4230015 - STXVL VS1, R3, R4 // 7c23231a - STXVLL VS1, R3, R4 // 7c23235a - STXVX VS1, R3, R4 // 7c232318 - STXSDX VS1, (R3)(R4) // 7c241d98 - LXSIWAX (R3)(R4), VS1 // 7c241898 - STXSIWX VS1, (R3)(R4) // 7c241918 - MFVSRD VS1, R3 // 7c230066 - MTVSRD R3, VS1 // 7c230166 - XXLAND VS1, VS2, VS3 // f0611410 - XXLOR VS1, VS2, VS3 // f0611490 - XXLORC VS1, VS2, VS3 // f0611550 - XXLXOR VS1, VS2, VS3 // f06114d0 - XXSEL VS1, VS2, VS3, VS4 // f08110f0 - XXMRGHW VS1, VS2, VS3 // f0611090 - XXSPLTW VS1, $1, VS2 // f0410a90 - XXPERM VS1, VS2, VS3 // f06110d0 - XXSLDWI VS1, VS2, $1, VS3 // f0611110 - XSCVDPSP VS1, VS2 // f0400c24 - XVCVDPSP VS1, VS2 // f0400e24 - XSCVSXDDP VS1, VS2 // f0400de0 - XVCVDPSXDS VS1, VS2 // f0400f60 - XVCVSXDDP VS1, VS2 // f0400fe0 - - MOVD R3, LR // 7c6803a6 - MOVD R3, CTR // 7c6903a6 - MOVD R3, XER // 7c6103a6 - MOVD LR, R3 // 7c6802a6 - MOVD CTR, R3 // 7c6902a6 - MOVD XER, R3 // 7c6102a6 - MOVFL CR3, CR1 // 4c8c0000 - - RET diff --git a/src/cmd/asm/internal/asm/testdata/riscvenc.s b/src/cmd/asm/internal/asm/testdata/riscvenc.s index 8d301f2dd5..9a49d96ca0 100644 --- a/src/cmd/asm/internal/asm/testdata/riscvenc.s +++ b/src/cmd/asm/internal/asm/testdata/riscvenc.s @@ -297,6 +297,13 @@ start: MOVW X5, (X6) // 23205300 MOVW X5, 4(X6) // 23225300 + MOVB X5, X6 // 1393820313538343 + MOVH X5, X6 // 1393020313530343 + MOVW X5, X6 // 1b830200 + MOVBU X5, X6 // 13f3f20f + MOVHU X5, X6 // 1393020313530303 + MOVWU X5, X6 // 1393020213530302 + MOVF 4(X5), F0 // 07a04200 MOVF F0, 4(X5) // 27a20200 MOVF F0, F1 // d3000020 @@ -318,7 +325,7 @@ start: // These jumps can get printed as jumps to 2 because they go to the // second instruction in the function (the first instruction is an // invisible stack pointer adjustment). - JMP start // JMP 2 // 6ff01fc5 + JMP start // JMP 2 // 6ff09fc2 JMP (X5) // 67800200 JMP 4(X5) // 67804200 @@ -331,16 +338,16 @@ start: JMP asmtest(SB) // 970f0000 // Branch pseudo-instructions - BEQZ X5, start // BEQZ X5, 2 // e38a02c2 - BGEZ X5, start // BGEZ X5, 2 // e3d802c2 - BGT X5, X6, start // BGT X5, X6, 2 // e3c662c2 - BGTU X5, X6, start // BGTU X5, X6, 2 // e3e462c2 - BGTZ X5, start // BGTZ X5, 2 // e34250c2 - BLE X5, X6, start // BLE X5, X6, 2 // e3d062c2 - BLEU X5, X6, start // BLEU X5, X6, 2 // e3fe62c0 - BLEZ X5, start // BLEZ X5, 2 // e35c50c0 - BLTZ X5, start // BLTZ X5, 2 // e3ca02c0 - BNEZ X5, start // BNEZ X5, 2 // e39802c0 + BEQZ X5, start // BEQZ X5, 2 // e38602c0 + BGEZ X5, start // BGEZ X5, 2 // e3d402c0 + BGT X5, X6, start // BGT X5, X6, 2 // e34253c0 + BGTU X5, X6, start // BGTU X5, X6, 2 // e36053c0 + BGTZ X5, start // BGTZ X5, 2 // e34e50be + BLE X5, X6, start // BLE X5, X6, 2 // e35c53be + BLEU X5, X6, start // BLEU X5, X6, 2 // e37a53be + BLEZ X5, start // BLEZ X5, 2 // e35850be + BLTZ X5, start // BLTZ X5, 2 // e3c602be + BNEZ X5, start // BNEZ X5, 2 // e39402be // Set pseudo-instructions SEQZ X15, X15 // 93b71700 diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 03b84cfa62..7c5d26be33 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -412,6 +412,8 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- UNDEF // 00000000 NOPH // 0700 + SYNC // 07e0 + // vector add and sub instructions VAB V3, V4, V4 // e743400000f3 VAH V3, V4, V4 // e743400010f3 diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go index 1df9df9563..1335860315 100644 --- a/src/cmd/asm/internal/flags/flags.go +++ b/src/cmd/asm/internal/flags/flags.go @@ -15,27 +15,30 @@ import ( ) var ( - Debug = flag.Bool("debug", false, "dump instructions as they are parsed") - OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument") - PrintOut = flag.Bool("S", false, "print assembly and machine code") - TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths") - Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library") - Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries") - AllErrors = flag.Bool("e", false, "no limit on number of errors reported") - SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble") - Importpath = flag.String("p", "", "set expected package import to path") - Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)") + Debug = flag.Bool("debug", false, "dump instructions as they are parsed") + OutputFile = flag.String("o", "", "output file; default foo.o for /a/b/c/foo.s as first argument") + TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths") + Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library") + Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries") + Linkshared = flag.Bool("linkshared", false, "generate code that will be linked against Go shared libraries") + AllErrors = flag.Bool("e", false, "no limit on number of errors reported") + SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble") + Importpath = flag.String("p", "", "set expected package import to path") + Spectre = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)") + CompilingRuntime = flag.Bool("compiling-runtime", false, "source to be compiled is part of the Go runtime") ) var ( - D MultiFlag - I MultiFlag + D MultiFlag + I MultiFlag + PrintOut int ) func init() { flag.Var(&D, "D", "predefined symbol with optional simple value -D=identifier=value; can be set multiple times") flag.Var(&I, "I", "include directory; can be set multiple times") objabi.AddVersionFlag() // -V + objabi.Flagcount("S", "print assembly and machine code", &PrintOut) } // MultiFlag allows setting a value multiple times to collect a list, as in -I=dir1 -I=dir2. diff --git a/src/cmd/asm/internal/lex/input.go b/src/cmd/asm/internal/lex/input.go index a43953b515..da4ebe6d6e 100644 --- a/src/cmd/asm/internal/lex/input.go +++ b/src/cmd/asm/internal/lex/input.go @@ -109,6 +109,9 @@ func (in *Input) Next() ScanToken { in.Error("'#' must be first item on line") } in.beginningOfLine = in.hash() + in.text = "#" + return '#' + case scanner.Ident: // Is it a macro name? name := in.Stack.Text() diff --git a/src/cmd/asm/internal/lex/lex.go b/src/cmd/asm/internal/lex/lex.go index f1f7da7911..7cd41a55a9 100644 --- a/src/cmd/asm/internal/lex/lex.go +++ b/src/cmd/asm/internal/lex/lex.go @@ -22,11 +22,13 @@ type ScanToken rune const ( // Asm defines some two-character lexemes. We make up // a rune/ScanToken value for them - ugly but simple. - LSH ScanToken = -1000 - iota // << Left shift. - RSH // >> Logical right shift. - ARR // -> Used on ARM for shift type 3, arithmetic right shift. - ROT // @> Used on ARM for shift type 4, rotate right. - macroName // name of macro that should not be expanded + LSH ScanToken = -1000 - iota // << Left shift. + RSH // >> Logical right shift. + ARR // -> Used on ARM for shift type 3, arithmetic right shift. + ROT // @> Used on ARM for shift type 4, rotate right. + Include // included file started here + BuildComment // //go:build or +build comment + macroName // name of macro that should not be expanded ) // IsRegisterShift reports whether the token is one of the ARM register shift operators. diff --git a/src/cmd/asm/internal/lex/lex_test.go b/src/cmd/asm/internal/lex/lex_test.go index f606ffe07b..51679d2fbc 100644 --- a/src/cmd/asm/internal/lex/lex_test.go +++ b/src/cmd/asm/internal/lex/lex_test.go @@ -281,6 +281,9 @@ func drain(input *Input) string { if tok == scanner.EOF { return buf.String() } + if tok == '#' { + continue + } if buf.Len() > 0 { buf.WriteByte('.') } diff --git a/src/cmd/asm/internal/lex/tokenizer.go b/src/cmd/asm/internal/lex/tokenizer.go index aef9ea8636..861a2d421d 100644 --- a/src/cmd/asm/internal/lex/tokenizer.go +++ b/src/cmd/asm/internal/lex/tokenizer.go @@ -107,10 +107,13 @@ func (t *Tokenizer) Next() ScanToken { if t.tok != scanner.Comment { break } - length := strings.Count(s.TokenText(), "\n") - t.line += length - // TODO: If we ever have //go: comments in assembly, will need to keep them here. - // For now, just discard all comments. + text := s.TokenText() + t.line += strings.Count(text, "\n") + // TODO: Use constraint.IsGoBuild once it exists. + if strings.HasPrefix(text, "//go:build") { + t.tok = BuildComment + break + } } switch t.tok { case '\n': diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go index a6eb44de73..31636e3045 100644 --- a/src/cmd/asm/main.go +++ b/src/cmd/asm/main.go @@ -35,10 +35,9 @@ func main() { flags.Parse() ctxt := obj.Linknew(architecture.LinkArch) - if *flags.PrintOut { - ctxt.Debugasm = 1 - } + ctxt.Debugasm = flags.PrintOut ctxt.Flag_dynlink = *flags.Dynlink + ctxt.Flag_linkshared = *flags.Linkshared ctxt.Flag_shared = *flags.Shared || *flags.Dynlink ctxt.IsAsm = true ctxt.Pkgpath = *flags.Importpath @@ -76,7 +75,8 @@ func main() { var failedFile string for _, f := range flag.Args() { lexer := lex.NewLexer(f) - parser := asm.NewParser(ctxt, architecture, lexer) + parser := asm.NewParser(ctxt, architecture, lexer, + *flags.CompilingRuntime) ctxt.DiagFunc = func(format string, args ...interface{}) { diag = true log.Printf(format, args...) diff --git a/src/cmd/buildid/buildid.go b/src/cmd/buildid/buildid.go index 1c7b228c98..8e02a7ae10 100644 --- a/src/cmd/buildid/buildid.go +++ b/src/cmd/buildid/buildid.go @@ -22,21 +22,6 @@ func usage() { var wflag = flag.Bool("w", false, "write build ID") -// taken from cmd/go/internal/work/buildid.go -func hashToString(h [32]byte) string { - const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" - const chunks = 5 - var dst [chunks * 4]byte - for i := 0; i < chunks; i++ { - v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) - dst[4*i+0] = b64[(v>>18)&0x3F] - dst[4*i+1] = b64[(v>>12)&0x3F] - dst[4*i+2] = b64[(v>>6)&0x3F] - dst[4*i+3] = b64[v&0x3F] - } - return string(dst[:]) -} - func main() { log.SetPrefix("buildid: ") log.SetFlags(0) @@ -63,12 +48,12 @@ func main() { log.Fatal(err) } matches, hash, err := buildid.FindAndHash(f, id, 0) + f.Close() if err != nil { log.Fatal(err) } - f.Close() - newID := id[:strings.LastIndex(id, "/")] + "/" + hashToString(hash) + newID := id[:strings.LastIndex(id, "/")] + "/" + buildid.HashToString(hash) if len(newID) != len(id) { log.Fatalf("%s: build ID length mismatch %q vs %q", file, id, newID) } @@ -77,7 +62,7 @@ func main() { return } - f, err = os.OpenFile(file, os.O_WRONLY, 0) + f, err = os.OpenFile(file, os.O_RDWR, 0) if err != nil { log.Fatal(err) } diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go index 54d6bc2559..a073407a96 100644 --- a/src/cmd/cgo/ast.go +++ b/src/cmd/cgo/ast.go @@ -13,7 +13,6 @@ import ( "go/scanner" "go/token" "os" - "path/filepath" "strings" ) @@ -44,14 +43,7 @@ func sourceLine(n ast.Node) int { // attached to the import "C" comment, a list of references to C.xxx, // a list of exported functions, and the actual AST, to be rewritten and // printed. -func (f *File) ParseGo(name string, src []byte) { - // Create absolute path for file, so that it will be used in error - // messages and recorded in debug line number information. - // This matches the rest of the toolchain. See golang.org/issue/5122. - if aname, err := filepath.Abs(name); err == nil { - name = aname - } - +func (f *File) ParseGo(abspath string, src []byte) { // Two different parses: once with comments, once without. // The printer is not good enough at printing comments in the // right place when we start editing the AST behind its back, @@ -60,8 +52,8 @@ func (f *File) ParseGo(name string, src []byte) { // and reprinting. // In cgo mode, we ignore ast2 and just apply edits directly // the text behind ast1. In godefs mode we modify and print ast2. - ast1 := parse(name, src, parser.ParseComments) - ast2 := parse(name, src, 0) + ast1 := parse(abspath, src, parser.ParseComments) + ast2 := parse(abspath, src, 0) f.Package = ast1.Name.Name f.Name = make(map[string]*Name) @@ -88,7 +80,7 @@ func (f *File) ParseGo(name string, src []byte) { cg = d.Doc } if cg != nil { - f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), name) + f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath) f.Preamble += commentText(cg) + "\n" f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n" } diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go index b3f371b08c..e782c866ac 100644 --- a/src/cmd/cgo/doc.go +++ b/src/cmd/cgo/doc.go @@ -721,7 +721,7 @@ linkage to the desired libraries. The main function is provided by _cgo_main.c: int main() { return 0; } - void crosscall2(void(*fn)(void*, int, uintptr_t), void *a, int c, uintptr_t ctxt) { } + void crosscall2(void(*fn)(void*), void *a, int c, uintptr_t ctxt) { } uintptr_t _cgo_wait_runtime_init_done(void) { return 0; } void _cgo_release_context(uintptr_t ctxt) { } char* _cgo_topofstack(void) { return (char*)0; } diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index 9179b5490e..111a309eb5 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -298,7 +298,7 @@ func (p *Package) guessKinds(f *File) []*Name { continue } - if goos == "darwin" && strings.HasSuffix(n.C, "Ref") { + if (goos == "darwin" || goos == "ios") && strings.HasSuffix(n.C, "Ref") { // For FooRef, find out if FooGetTypeID exists. s := n.C[:len(n.C)-3] + "GetTypeID" n := &Name{Go: s, C: s} @@ -2448,6 +2448,18 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ tt := *t tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} tt.Go = c.Ident("struct{}") + if dt.Kind == "struct" { + // We don't know what the representation of this struct is, so don't let + // anyone allocate one on the Go side. As a side effect of this annotation, + // pointers to this type will not be considered pointers in Go. They won't + // get writebarrier-ed or adjusted during a stack copy. This should handle + // all the cases badPointerTypedef used to handle, but hopefully will + // continue to work going forward without any more need for cgo changes. + tt.NotInHeap = true + // TODO: we should probably do the same for unions. Unions can't live + // on the Go heap, right? It currently doesn't work for unions because + // they are defined as a type alias for struct{}, not a defined type. + } typedef[name.Name] = &tt break } @@ -2518,6 +2530,7 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ } t.Go = name t.BadPointer = sub.BadPointer + t.NotInHeap = sub.NotInHeap if unionWithPointer[sub.Go] { unionWithPointer[t.Go] = true } @@ -2528,6 +2541,7 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ tt := *t tt.Go = sub.Go tt.BadPointer = sub.BadPointer + tt.NotInHeap = sub.NotInHeap typedef[name.Name] = &tt } @@ -2831,21 +2845,11 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct tgo := t.Go size := t.Size talign := t.Align - if f.BitSize > 0 { - switch f.BitSize { - case 8, 16, 32, 64: - default: - continue - } - size = f.BitSize / 8 - name := tgo.(*ast.Ident).String() - if strings.HasPrefix(name, "int") { - name = "int" - } else { - name = "uint" - } - tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) - talign = size + if f.BitOffset > 0 || f.BitSize > 0 { + // The layout of bitfields is implementation defined, + // so we don't know how they correspond to Go fields + // even if they are aligned at byte boundaries. + continue } if talign > 0 && f.ByteOffset%talign != 0 { @@ -3036,6 +3040,7 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool { // non-pointers in this type. // TODO: Currently our best solution is to find these manually and list them as // they come up. A better solution is desired. +// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file. func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { if c.badCFType(dt) { return true @@ -3070,7 +3075,7 @@ func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool { // We identify the correct set of types as those ending in Ref and for which // there exists a corresponding GetTypeID function. // See comment below for details about the bad pointers. - if goos != "darwin" { + if goos != "darwin" && goos != "ios" { return false } s := dt.Name diff --git a/src/cmd/cgo/godefs.go b/src/cmd/cgo/godefs.go index b4fd9c5a6e..c0d59aee01 100644 --- a/src/cmd/cgo/godefs.go +++ b/src/cmd/cgo/godefs.go @@ -16,7 +16,7 @@ import ( ) // godefs returns the output for -godefs mode. -func (p *Package) godefs(f *File, srcfile string) string { +func (p *Package) godefs(f *File) string { var buf bytes.Buffer fmt.Fprintf(&buf, "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n") diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 5a7bb3f87b..c1116e28ec 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -151,7 +151,8 @@ type Type struct { Go ast.Expr EnumValues map[string]int64 Typedef string - BadPointer bool + BadPointer bool // this pointer type should be represented as a uintptr (deprecated) + NotInHeap bool // this type should have a go:notinheap annotation } // A FuncType collects information about a function type in both the C and Go worlds. @@ -169,35 +170,51 @@ func usage() { var ptrSizeMap = map[string]int64{ "386": 4, + "alpha": 8, "amd64": 8, "arm": 4, "arm64": 8, + "m68k": 4, "mips": 4, "mipsle": 4, "mips64": 8, "mips64le": 8, + "nios2": 4, + "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv": 4, "riscv64": 8, "s390": 4, "s390x": 8, + "sh": 4, + "shbe": 4, + "sparc": 4, "sparc64": 8, } var intSizeMap = map[string]int64{ "386": 4, + "alpha": 8, "amd64": 8, "arm": 4, "arm64": 8, + "m68k": 4, "mips": 4, "mipsle": 4, "mips64": 8, "mips64le": 8, + "nios2": 4, + "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv": 4, "riscv64": 8, "s390": 4, "s390x": 8, + "sh": 4, + "shbe": 4, + "sparc": 4, "sparc64": 8, } @@ -223,10 +240,11 @@ var exportHeader = flag.String("exportheader", "", "where to write export header var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo") var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo") var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo") -var gccgoMangleCheckDone bool -var gccgoNewmanglingInEffect bool +var gccgoMangler func(string) string var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code") var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code") +var trimpath = flag.String("trimpath", "", "applies supplied rewrites or trims prefixes to recorded source file paths") + var goarch, goos string func main() { @@ -306,6 +324,13 @@ func main() { input = filepath.Join(*srcDir, input) } + // Create absolute path for file, so that it will be used in error + // messages and recorded in debug line number information. + // This matches the rest of the toolchain. See golang.org/issue/5122. + if aname, err := filepath.Abs(input); err == nil { + input = aname + } + b, err := ioutil.ReadFile(input) if err != nil { fatalf("%s", err) @@ -314,6 +339,10 @@ func main() { fatalf("%s", err) } + // Apply trimpath to the file path. The path won't be read from after this point. + input, _ = objabi.ApplyRewrites(input, *trimpath) + goFiles[i] = input + f := new(File) f.Edit = edit.NewBuffer(b) f.ParseGo(input, b) @@ -351,7 +380,7 @@ func main() { p.PackagePath = f.Package p.Record(f) if *godefs { - os.Stdout.WriteString(p.godefs(f, input)) + os.Stdout.WriteString(p.godefs(f)) } else { p.writeOutput(f, input) } diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 50d2811f1b..11c53facf8 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -6,6 +6,7 @@ package main import ( "bytes" + "cmd/internal/pkgpath" "debug/elf" "debug/macho" "debug/pe" @@ -15,7 +16,6 @@ import ( "go/token" "internal/xcoff" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -59,14 +59,14 @@ func (p *Package) writeDefs() { // Write C main file for using gcc to resolve imports. fmt.Fprintf(fm, "int main() { return 0; }\n") if *importRuntimeCgo { - fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt) { }\n") + fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt) { }\n") fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void) { return 0; }\n") fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__ ctxt) { }\n") fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n") } else { // If we're not importing runtime/cgo, we *are* runtime/cgo, // which provides these functions. We just need a prototype. - fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt);\n") + fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt);\n") fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n") fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__);\n") } @@ -108,6 +108,9 @@ func (p *Package) writeDefs() { sort.Strings(typedefNames) for _, name := range typedefNames { def := typedef[name] + if def.NotInHeap { + fmt.Fprintf(fgo2, "//go:notinheap\n") + } fmt.Fprintf(fgo2, "type %s ", name) // We don't have source info for these types, so write them out without source info. // Otherwise types would look like: @@ -183,7 +186,7 @@ func (p *Package) writeDefs() { panic(fmt.Errorf("invalid var kind %q", n.Kind)) } if *gccgo { - fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle) + fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, gccgoToSymbol(n.Mangle)) fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C) fmt.Fprintf(fc, "\n") } @@ -334,6 +337,8 @@ func dynimport(obj string) { if s.Version != "" { targ += "#" + s.Version } + checkImportSymName(s.Name) + checkImportSymName(targ) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library) } lib, _ := f.ImportedLibraries() @@ -349,6 +354,7 @@ func dynimport(obj string) { if len(s) > 0 && s[0] == '_' { s = s[1:] } + checkImportSymName(s) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "") } lib, _ := f.ImportedLibraries() @@ -363,6 +369,8 @@ func dynimport(obj string) { for _, s := range sym { ss := strings.Split(s, ":") name := strings.Split(ss[0], "@")[0] + checkImportSymName(name) + checkImportSymName(ss[0]) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1])) } return @@ -380,6 +388,7 @@ func dynimport(obj string) { // Go symbols. continue } + checkImportSymName(s.Name) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, s.Name, s.Library) } lib, err := f.ImportedLibraries() @@ -395,6 +404,23 @@ func dynimport(obj string) { fatalf("cannot parse %s as ELF, Mach-O, PE or XCOFF", obj) } +// checkImportSymName checks a symbol name we are going to emit as part +// of a //go:cgo_import_dynamic pragma. These names come from object +// files, so they may be corrupt. We are going to emit them unquoted, +// so while they don't need to be valid symbol names (and in some cases, +// involving symbol versions, they won't be) they must contain only +// graphic characters and must not contain Go comments. +func checkImportSymName(s string) { + for _, c := range s { + if !unicode.IsGraphic(c) || unicode.IsSpace(c) { + fatalf("dynamic symbol %q contains unsupported character", s) + } + } + if strings.Index(s, "//") >= 0 || strings.Index(s, "/*") >= 0 { + fatalf("dynamic symbol %q contains Go comment") + } +} + // Construct a gcc struct matching the gc argument frame. // Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes. // These assumptions are checked by the gccProlog. @@ -849,7 +875,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Wpragmas\"\n") fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Waddress-of-packed-member\"\n") - fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);\n") + fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *), void *, int, __SIZE_TYPE__);\n") fmt.Fprintf(fgcc, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n") fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n") fmt.Fprintf(fgcc, "extern char* _cgo_topofstack(void);") @@ -859,59 +885,48 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { for _, exp := range p.ExpFunc { fn := exp.Func - // Construct a gcc struct matching the gc argument and - // result frame. The gcc struct will be compiled with - // __attribute__((packed)) so all padding must be accounted - // for explicitly. + // Construct a struct that will be used to communicate + // arguments from C to Go. The C and Go definitions + // just have to agree. The gcc struct will be compiled + // with __attribute__((packed)) so all padding must be + // accounted for explicitly. ctype := "struct {\n" + gotype := new(bytes.Buffer) + fmt.Fprintf(gotype, "struct {\n") off := int64(0) npad := 0 - if fn.Recv != nil { - t := p.cgoType(fn.Recv.List[0].Type) - ctype += fmt.Sprintf("\t\t%s recv;\n", t.C) + argField := func(typ ast.Expr, namePat string, args ...interface{}) { + name := fmt.Sprintf(namePat, args...) + t := p.cgoType(typ) + if off%t.Align != 0 { + pad := t.Align - off%t.Align + ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) + off += pad + npad++ + } + ctype += fmt.Sprintf("\t\t%s %s;\n", t.C, name) + fmt.Fprintf(gotype, "\t\t%s ", name) + noSourceConf.Fprint(gotype, fset, typ) + fmt.Fprintf(gotype, "\n") off += t.Size } + if fn.Recv != nil { + argField(fn.Recv.List[0].Type, "recv") + } fntype := fn.Type forFieldList(fntype.Params, func(i int, aname string, atype ast.Expr) { - t := p.cgoType(atype) - if off%t.Align != 0 { - pad := t.Align - off%t.Align - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } - ctype += fmt.Sprintf("\t\t%s p%d;\n", t.C, i) - off += t.Size + argField(atype, "p%d", i) }) - if off%p.PtrSize != 0 { - pad := p.PtrSize - off%p.PtrSize - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } forFieldList(fntype.Results, func(i int, aname string, atype ast.Expr) { - t := p.cgoType(atype) - if off%t.Align != 0 { - pad := t.Align - off%t.Align - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } - ctype += fmt.Sprintf("\t\t%s r%d;\n", t.C, i) - off += t.Size + argField(atype, "r%d", i) }) - if off%p.PtrSize != 0 { - pad := p.PtrSize - off%p.PtrSize - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } if ctype == "struct {\n" { ctype += "\t\tchar unused;\n" // avoid empty struct } ctype += "\t}" + fmt.Fprintf(gotype, "\t}") // Get the return type of the wrapper function // compiled by gcc. @@ -936,7 +951,11 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { } // Build the wrapper function compiled by gcc. - s := fmt.Sprintf("%s %s(", gccResult, exp.ExpName) + gccExport := "" + if goos == "windows" { + gccExport = "__declspec(dllexport)" + } + s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName) if fn.Recv != nil { s += p.cgoType(fn.Recv.List[0].Type).C.String() s += " recv" @@ -958,12 +977,23 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { } fmt.Fprintf(fgcch, "extern %s;\n", s) - fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int, __SIZE_TYPE__);\n", cPrefix, exp.ExpName) + fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *);\n", cPrefix, exp.ExpName) fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD") fmt.Fprintf(fgcc, "\n%s\n", s) fmt.Fprintf(fgcc, "{\n") fmt.Fprintf(fgcc, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n") - fmt.Fprintf(fgcc, "\t%s %v _cgo_a;\n", ctype, p.packedAttribute()) + // The results part of the argument structure must be + // initialized to 0 so the write barriers generated by + // the assignments to these fields in Go are safe. + // + // We use a local static variable to get the zeroed + // value of the argument type. This avoids including + // string.h for memset, and is also robust to C++ + // types with constructors. Both GCC and LLVM optimize + // this into just zeroing _cgo_a. + fmt.Fprintf(fgcc, "\ttypedef %s %v _cgo_argtype;\n", ctype, p.packedAttribute()) + fmt.Fprintf(fgcc, "\tstatic _cgo_argtype _cgo_zero;\n") + fmt.Fprintf(fgcc, "\t_cgo_argtype _cgo_a = _cgo_zero;\n") if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) { fmt.Fprintf(fgcc, "\t%s r;\n", gccResult) } @@ -992,82 +1022,28 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprintf(fgcc, "}\n") // Build the wrapper function compiled by cmd/compile. - goname := "_cgoexpwrap" + cPrefix + "_" - if fn.Recv != nil { - goname += fn.Recv.List[0].Names[0].Name + "_" - } - goname += exp.Func.Name.Name + // This unpacks the argument struct above and calls the Go function. fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", exp.ExpName) fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName) fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName) - fmt.Fprintf(fgo2, "//go:nosplit\n") // no split stack, so no use of m or g - fmt.Fprintf(fgo2, "//go:norace\n") // must not have race detector calls inserted - fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a unsafe.Pointer, n int32, ctxt uintptr) {\n", cPrefix, exp.ExpName) - fmt.Fprintf(fgo2, "\tfn := %s\n", goname) - // The indirect here is converting from a Go function pointer to a C function pointer. - fmt.Fprintf(fgo2, "\t_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);\n") - fmt.Fprintf(fgo2, "}\n") + fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype) fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName) - // This code uses printer.Fprint, not conf.Fprint, - // because we don't want //line comments in the middle - // of the function types. - fmt.Fprintf(fgo2, "\n") - fmt.Fprintf(fgo2, "func %s(", goname) - comma := false - if fn.Recv != nil { - fmt.Fprintf(fgo2, "recv ") - printer.Fprint(fgo2, fset, fn.Recv.List[0].Type) - comma = true - } - forFieldList(fntype.Params, - func(i int, aname string, atype ast.Expr) { - if comma { - fmt.Fprintf(fgo2, ", ") - } - fmt.Fprintf(fgo2, "p%d ", i) - printer.Fprint(fgo2, fset, atype) - comma = true - }) - fmt.Fprintf(fgo2, ")") if gccResult != "void" { - fmt.Fprint(fgo2, " (") + // Write results back to frame. + fmt.Fprintf(fgo2, "\t") forFieldList(fntype.Results, func(i int, aname string, atype ast.Expr) { if i > 0 { - fmt.Fprint(fgo2, ", ") + fmt.Fprintf(fgo2, ", ") } - fmt.Fprintf(fgo2, "r%d ", i) - printer.Fprint(fgo2, fset, atype) + fmt.Fprintf(fgo2, "a.r%d", i) }) - fmt.Fprint(fgo2, ")") - } - fmt.Fprint(fgo2, " {\n") - if gccResult == "void" { - fmt.Fprint(fgo2, "\t") - } else { - // Verify that any results don't contain any - // Go pointers. - addedDefer := false - forFieldList(fntype.Results, - func(i int, aname string, atype ast.Expr) { - if !p.hasPointer(nil, atype, false) { - return - } - if !addedDefer { - fmt.Fprint(fgo2, "\tdefer func() {\n") - addedDefer = true - } - fmt.Fprintf(fgo2, "\t\t_cgoCheckResult(r%d)\n", i) - }) - if addedDefer { - fmt.Fprint(fgo2, "\t}()\n") - } - fmt.Fprint(fgo2, "\treturn ") + fmt.Fprintf(fgo2, " = ") } if fn.Recv != nil { - fmt.Fprintf(fgo2, "recv.") + fmt.Fprintf(fgo2, "a.recv.") } fmt.Fprintf(fgo2, "%s(", exp.Func.Name) forFieldList(fntype.Params, @@ -1075,9 +1051,20 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { if i > 0 { fmt.Fprint(fgo2, ", ") } - fmt.Fprintf(fgo2, "p%d", i) + fmt.Fprintf(fgo2, "a.p%d", i) }) fmt.Fprint(fgo2, ")\n") + if gccResult != "void" { + // Verify that any results don't contain any + // Go pointers. + forFieldList(fntype.Results, + func(i int, aname string, atype ast.Expr) { + if !p.hasPointer(nil, atype, false) { + return + } + fmt.Fprintf(fgo2, "\t_cgoCheckResult(a.r%d)\n", i) + }) + } fmt.Fprint(fgo2, "}\n") } @@ -1161,7 +1148,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) { // will not be able to link against it from the C // code. goName := "Cgoexp_" + exp.ExpName - fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName) + fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, gccgoToSymbol(goName)) fmt.Fprint(fgcc, "\n") fmt.Fprint(fgcc, "\nCGO_NO_SANITIZE_THREAD\n") @@ -1195,7 +1182,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprint(fgcc, "}\n") // Dummy declaration for _cgo_main.c - fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName) + fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, gccgoToSymbol(goName)) fmt.Fprint(fm, "\n") // For gccgo we use a wrapper function in Go, in order @@ -1279,112 +1266,23 @@ func (p *Package) writeExportHeader(fgcch io.Writer) { fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog()) } -// gccgoUsesNewMangling reports whether gccgo uses the new collision-free -// packagepath mangling scheme (see determineGccgoManglingScheme for more -// info). -func gccgoUsesNewMangling() bool { - if !gccgoMangleCheckDone { - gccgoNewmanglingInEffect = determineGccgoManglingScheme() - gccgoMangleCheckDone = true - } - return gccgoNewmanglingInEffect -} - -const mangleCheckCode = ` -package läufer -func Run(x int) int { - return 1 -} -` - -// determineGccgoManglingScheme performs a runtime test to see which -// flavor of packagepath mangling gccgo is using. Older versions of -// gccgo use a simple mangling scheme where there can be collisions -// between packages whose paths are different but mangle to the same -// string. More recent versions of gccgo use a new mangler that avoids -// these collisions. Return value is whether gccgo uses the new mangling. -func determineGccgoManglingScheme() bool { - - // Emit a small Go file for gccgo to compile. - filepat := "*_gccgo_manglecheck.go" - var f *os.File - var err error - if f, err = ioutil.TempFile(*objDir, filepat); err != nil { - fatalf("%v", err) - } - gofilename := f.Name() - defer os.Remove(gofilename) - - if err = ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0666); err != nil { - fatalf("%v", err) - } - - // Compile with gccgo, capturing generated assembly. - gccgocmd := os.Getenv("GCCGO") - if gccgocmd == "" { - gpath, gerr := exec.LookPath("gccgo") - if gerr != nil { - fatalf("unable to locate gccgo: %v", gerr) - } - gccgocmd = gpath - } - cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename) - buf, cerr := cmd.CombinedOutput() - if cerr != nil { - fatalf("%s", cerr) - } - - // New mangling: expect go.l..u00e4ufer.Run - // Old mangling: expect go.l__ufer.Run - return regexp.MustCompile(`go\.l\.\.u00e4ufer\.Run`).Match(buf) -} - -// gccgoPkgpathToSymbolNew converts a package path to a gccgo-style -// package symbol. -func gccgoPkgpathToSymbolNew(ppath string) string { - bsl := []byte{} - changed := false - for _, c := range []byte(ppath) { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z', - '0' <= c && c <= '9', c == '_': - bsl = append(bsl, c) - case c == '.': - bsl = append(bsl, ".x2e"...) - default: - changed = true - encbytes := []byte(fmt.Sprintf("..z%02x", c)) - bsl = append(bsl, encbytes...) +// gccgoToSymbol converts a name to a mangled symbol for gccgo. +func gccgoToSymbol(ppath string) string { + if gccgoMangler == nil { + var err error + cmd := os.Getenv("GCCGO") + if cmd == "" { + cmd, err = exec.LookPath("gccgo") + if err != nil { + fatalf("unable to locate gccgo: %v", err) + } } - } - if !changed { - return ppath - } - return string(bsl) -} - -// gccgoPkgpathToSymbolOld converts a package path to a gccgo-style -// package symbol using the older mangling scheme. -func gccgoPkgpathToSymbolOld(ppath string) string { - clean := func(r rune) rune { - switch { - case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', - '0' <= r && r <= '9': - return r + gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, *objDir) + if err != nil { + fatalf("%v", err) } - return '_' - } - return strings.Map(clean, ppath) -} - -// gccgoPkgpathToSymbol converts a package path to a mangled packagepath -// symbol. -func gccgoPkgpathToSymbol(ppath string) string { - if gccgoUsesNewMangling() { - return gccgoPkgpathToSymbolNew(ppath) - } else { - return gccgoPkgpathToSymbolOld(ppath) } + return gccgoMangler(ppath) } // Return the package prefix when using gccgo. @@ -1394,12 +1292,12 @@ func (p *Package) gccgoSymbolPrefix() string { } if *gccgopkgpath != "" { - return gccgoPkgpathToSymbol(*gccgopkgpath) + return gccgoToSymbol(*gccgopkgpath) } if *gccgoprefix == "" && p.PackageName == "main" { return "main" } - prefix := gccgoPkgpathToSymbol(*gccgoprefix) + prefix := gccgoToSymbol(*gccgoprefix) if prefix == "" { prefix = "go" } @@ -1663,9 +1561,6 @@ const goProlog = ` //go:linkname _cgo_runtime_cgocall runtime.cgocall func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32 -//go:linkname _cgo_runtime_cgocallback runtime.cgocallback -func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr) - //go:linkname _cgoCheckPointer runtime.cgoCheckPointer func _cgoCheckPointer(interface{}, interface{}) @@ -1791,8 +1686,12 @@ void _cgoPREFIX_Cfunc__Cmalloc(void *v) { ` func (p *Package) cPrologGccgo() string { - return strings.Replace(strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1), - "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), -1) + r := strings.NewReplacer( + "PREFIX", cPrefix, + "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), + "_cgoCheckPointer", gccgoToSymbol("_cgoCheckPointer"), + "_cgoCheckResult", gccgoToSymbol("_cgoCheckResult")) + return r.Replace(cPrologGccgo) } const cPrologGccgo = ` diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go index e372259c78..6625ccf5e2 100644 --- a/src/cmd/compile/fmt_test.go +++ b/src/cmd/compile/fmt_test.go @@ -52,6 +52,7 @@ import ( "go/types" "internal/testenv" "io" + "io/fs" "io/ioutil" "log" "os" @@ -89,7 +90,7 @@ func TestFormats(t *testing.T) { testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok // process all directories - filepath.Walk(".", func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(".", func(path string, info fs.DirEntry, err error) error { if info.IsDir() { if info.Name() == "testdata" { return filepath.SkipDir diff --git a/src/cmd/compile/fmtmap_test.go b/src/cmd/compile/fmtmap_test.go index 179c60187f..0811df7f7b 100644 --- a/src/cmd/compile/fmtmap_test.go +++ b/src/cmd/compile/fmtmap_test.go @@ -105,10 +105,8 @@ var knownFormats = map[string]string{ "cmd/compile/internal/ssa.GCNode %v": "", "cmd/compile/internal/ssa.ID %d": "", "cmd/compile/internal/ssa.ID %v": "", - "cmd/compile/internal/ssa.LocPair %s": "", "cmd/compile/internal/ssa.LocalSlot %s": "", "cmd/compile/internal/ssa.LocalSlot %v": "", - "cmd/compile/internal/ssa.Location %T": "", "cmd/compile/internal/ssa.Location %s": "", "cmd/compile/internal/ssa.Op %s": "", "cmd/compile/internal/ssa.Op %v": "", diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go index 4ac877986c..5ff05a0edd 100644 --- a/src/cmd/compile/internal/amd64/ssa.go +++ b/src/cmd/compile/internal/amd64/ssa.go @@ -42,10 +42,11 @@ func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) { // loadByType returns the load instruction of the given type. func loadByType(t *types.Type) obj.As { // Avoid partial register write - if !t.IsFloat() && t.Size() <= 2 { - if t.Size() == 1 { + if !t.IsFloat() { + switch t.Size() { + case 1: return x86.AMOVBLZX - } else { + case 2: return x86.AMOVWLZX } } @@ -75,7 +76,7 @@ func storeByType(t *types.Type) obj.As { return x86.AMOVQ } } - panic("bad store type") + panic(fmt.Sprintf("bad store type %v", t)) } // moveByType returns the reg->reg move instruction of the given type. @@ -100,7 +101,7 @@ func moveByType(t *types.Type) obj.As { case 16: return x86.AMOVUPS // int128s are in SSE registers default: - panic(fmt.Sprintf("bad int register width %d:%s", t.Size(), t)) + panic(fmt.Sprintf("bad int register width %d:%v", t.Size(), t)) } } } @@ -1070,7 +1071,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p := s.Prog(v.Op.Asm()) val := v.AuxInt // 0 means math.RoundToEven, 1 Floor, 2 Ceil, 3 Trunc - if val != 0 && val != 1 && val != 2 && val != 3 { + if val < 0 || val > 3 { v.Fatalf("Invalid rounding mode") } p.From.Offset = val @@ -1210,7 +1211,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p = s.Prog(x86.ASETEQ) p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg0() - case ssa.OpAMD64ANDBlock, ssa.OpAMD64ORBlock: + case ssa.OpAMD64ANDBlock, ssa.OpAMD64ANDLlock, ssa.OpAMD64ORBlock, ssa.OpAMD64ORLlock: s.Prog(x86.ALOCK) p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go index f698919e9b..f3fec03854 100644 --- a/src/cmd/compile/internal/arm64/ggen.go +++ b/src/cmd/compile/internal/arm64/ggen.go @@ -11,7 +11,7 @@ import ( "cmd/internal/objabi" ) -var darwin = objabi.GOOS == "darwin" +var darwin = objabi.GOOS == "darwin" || objabi.GOOS == "ios" func padframe(frame int64) int64 { // arm64 requires that the frame size (not counting saved FP&LR) diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go index 1d6ea6b9d8..22b28a9308 100644 --- a/src/cmd/compile/internal/arm64/ssa.go +++ b/src/cmd/compile/internal/arm64/ssa.go @@ -581,6 +581,24 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p2.From.Reg = arm64.REGTMP p2.To.Type = obj.TYPE_BRANCH gc.Patch(p2, p) + case ssa.OpARM64LoweredAtomicExchange64Variant, + ssa.OpARM64LoweredAtomicExchange32Variant: + swap := arm64.ASWPALD + if v.Op == ssa.OpARM64LoweredAtomicExchange32Variant { + swap = arm64.ASWPALW + } + r0 := v.Args[0].Reg() + r1 := v.Args[1].Reg() + out := v.Reg0() + + // SWPALD Rarg1, (Rarg0), Rout + p := s.Prog(swap) + p.From.Type = obj.TYPE_REG + p.From.Reg = r1 + p.To.Type = obj.TYPE_MEM + p.To.Reg = r0 + p.RegTo2 = out + case ssa.OpARM64LoweredAtomicAdd64, ssa.OpARM64LoweredAtomicAdd32: // LDAXR (Rarg0), Rout @@ -687,16 +705,74 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p5.To.Type = obj.TYPE_REG p5.To.Reg = out gc.Patch(p2, p5) + case ssa.OpARM64LoweredAtomicCas64Variant, + ssa.OpARM64LoweredAtomicCas32Variant: + // Rarg0: ptr + // Rarg1: old + // Rarg2: new + // MOV Rarg1, Rtmp + // CASAL Rtmp, (Rarg0), Rarg2 + // CMP Rarg1, Rtmp + // CSET EQ, Rout + cas := arm64.ACASALD + cmp := arm64.ACMP + mov := arm64.AMOVD + if v.Op == ssa.OpARM64LoweredAtomicCas32Variant { + cas = arm64.ACASALW + cmp = arm64.ACMPW + mov = arm64.AMOVW + } + r0 := v.Args[0].Reg() + r1 := v.Args[1].Reg() + r2 := v.Args[2].Reg() + out := v.Reg0() + + // MOV Rarg1, Rtmp + p := s.Prog(mov) + p.From.Type = obj.TYPE_REG + p.From.Reg = r1 + p.To.Type = obj.TYPE_REG + p.To.Reg = arm64.REGTMP + + // CASAL Rtmp, (Rarg0), Rarg2 + p1 := s.Prog(cas) + p1.From.Type = obj.TYPE_REG + p1.From.Reg = arm64.REGTMP + p1.To.Type = obj.TYPE_MEM + p1.To.Reg = r0 + p1.RegTo2 = r2 + + // CMP Rarg1, Rtmp + p2 := s.Prog(cmp) + p2.From.Type = obj.TYPE_REG + p2.From.Reg = r1 + p2.Reg = arm64.REGTMP + + // CSET EQ, Rout + p3 := s.Prog(arm64.ACSET) + p3.From.Type = obj.TYPE_REG + p3.From.Reg = arm64.COND_EQ + p3.To.Type = obj.TYPE_REG + p3.To.Reg = out + case ssa.OpARM64LoweredAtomicAnd8, - ssa.OpARM64LoweredAtomicOr8: - // LDAXRB (Rarg0), Rout + ssa.OpARM64LoweredAtomicAnd32, + ssa.OpARM64LoweredAtomicOr8, + ssa.OpARM64LoweredAtomicOr32: + // LDAXRB/LDAXRW (Rarg0), Rout // AND/OR Rarg1, Rout - // STLXRB Rout, (Rarg0), Rtmp + // STLXRB/STLXRB Rout, (Rarg0), Rtmp // CBNZ Rtmp, -3(PC) + ld := arm64.ALDAXRB + st := arm64.ASTLXRB + if v.Op == ssa.OpARM64LoweredAtomicAnd32 || v.Op == ssa.OpARM64LoweredAtomicOr32 { + ld = arm64.ALDAXRW + st = arm64.ASTLXRW + } r0 := v.Args[0].Reg() r1 := v.Args[1].Reg() out := v.Reg0() - p := s.Prog(arm64.ALDAXRB) + p := s.Prog(ld) p.From.Type = obj.TYPE_MEM p.From.Reg = r0 p.To.Type = obj.TYPE_REG @@ -706,7 +782,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p1.From.Reg = r1 p1.To.Type = obj.TYPE_REG p1.To.Reg = out - p2 := s.Prog(arm64.ASTLXRB) + p2 := s.Prog(st) p2.From.Type = obj.TYPE_REG p2.From.Reg = out p2.To.Type = obj.TYPE_MEM @@ -717,6 +793,63 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p3.From.Reg = arm64.REGTMP p3.To.Type = obj.TYPE_BRANCH gc.Patch(p3, p) + case ssa.OpARM64LoweredAtomicAnd8Variant, + ssa.OpARM64LoweredAtomicAnd32Variant: + atomic_clear := arm64.ALDCLRALW + if v.Op == ssa.OpARM64LoweredAtomicAnd8Variant { + atomic_clear = arm64.ALDCLRALB + } + r0 := v.Args[0].Reg() + r1 := v.Args[1].Reg() + out := v.Reg0() + + // MNV Rarg1 Rtemp + p := s.Prog(arm64.AMVN) + p.From.Type = obj.TYPE_REG + p.From.Reg = r1 + p.To.Type = obj.TYPE_REG + p.To.Reg = arm64.REGTMP + + // LDCLRALW Rtemp, (Rarg0), Rout + p1 := s.Prog(atomic_clear) + p1.From.Type = obj.TYPE_REG + p1.From.Reg = arm64.REGTMP + p1.To.Type = obj.TYPE_MEM + p1.To.Reg = r0 + p1.RegTo2 = out + + // AND Rarg1, Rout + p2 := s.Prog(arm64.AAND) + p2.From.Type = obj.TYPE_REG + p2.From.Reg = r1 + p2.To.Type = obj.TYPE_REG + p2.To.Reg = out + + case ssa.OpARM64LoweredAtomicOr8Variant, + ssa.OpARM64LoweredAtomicOr32Variant: + atomic_or := arm64.ALDORALW + if v.Op == ssa.OpARM64LoweredAtomicOr8Variant { + atomic_or = arm64.ALDORALB + } + r0 := v.Args[0].Reg() + r1 := v.Args[1].Reg() + out := v.Reg0() + + // LDORALW Rarg1, (Rarg0), Rout + p := s.Prog(atomic_or) + p.From.Type = obj.TYPE_REG + p.From.Reg = r1 + p.To.Type = obj.TYPE_MEM + p.To.Reg = r0 + p.RegTo2 = out + + // ORR Rarg1, Rout + p2 := s.Prog(arm64.AORR) + p2.From.Type = obj.TYPE_REG + p2.From.Reg = r1 + p2.To.Type = obj.TYPE_REG + p2.To.Reg = out + case ssa.OpARM64MOVBreg, ssa.OpARM64MOVBUreg, ssa.OpARM64MOVHreg, diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index c9d71ea00b..2f7fa27bb9 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -282,7 +282,7 @@ func genhash(t *types.Type) *obj.LSym { } sym := typesymprefix(".hash", t) - if Debug['r'] != 0 { + if Debug.r != 0 { fmt.Printf("genhash %v %v %v\n", closure, sym, t) } @@ -374,7 +374,7 @@ func genhash(t *types.Type) *obj.LSym { r.List.Append(nh) fn.Nbody.Append(r) - if Debug['r'] != 0 { + if Debug.r != 0 { dumplist("genhash body", fn.Nbody) } @@ -392,7 +392,7 @@ func genhash(t *types.Type) *obj.LSym { } fn.Func.SetNilCheckDisabled(true) - funccompile(fn) + xtop = append(xtop, fn) // Build closure. It doesn't close over any variables, so // it contains just the function pointer. @@ -509,7 +509,7 @@ func geneq(t *types.Type) *obj.LSym { return closure } sym := typesymprefix(".eq", t) - if Debug['r'] != 0 { + if Debug.r != 0 { fmt.Printf("geneq %v\n", t) } @@ -529,6 +529,10 @@ func geneq(t *types.Type) *obj.LSym { fn := dclfunc(sym, tfn) np := asNode(tfn.Type.Params().Field(0).Nname) nq := asNode(tfn.Type.Params().Field(1).Nname) + nr := asNode(tfn.Type.Results().Field(0).Nname) + + // Label to jump to if an equality test fails. + neq := autolabel(".neq") // We reach here only for types that have equality but // cannot be handled by the standard algorithms, @@ -555,13 +559,13 @@ func geneq(t *types.Type) *obj.LSym { // for i := 0; i < nelem; i++ { // if eq(p[i], q[i]) { // } else { - // return + // goto neq // } // } // // TODO(josharian): consider doing some loop unrolling // for larger nelem as well, processing a few elements at a time in a loop. - checkAll := func(unroll int64, eq func(pi, qi *Node) *Node) { + checkAll := func(unroll int64, last bool, eq func(pi, qi *Node) *Node) { // checkIdx generates a node to check for equality at index i. checkIdx := func(i *Node) *Node { // pi := p[i] @@ -576,37 +580,38 @@ func geneq(t *types.Type) *obj.LSym { } if nelem <= unroll { + if last { + // Do last comparison in a different manner. + nelem-- + } // Generate a series of checks. - var cond *Node for i := int64(0); i < nelem; i++ { - c := nodintconst(i) - check := checkIdx(c) - if cond == nil { - cond = check - continue - } - cond = nod(OANDAND, cond, check) + // if check {} else { goto neq } + nif := nod(OIF, checkIdx(nodintconst(i)), nil) + nif.Rlist.Append(nodSym(OGOTO, nil, neq)) + fn.Nbody.Append(nif) + } + if last { + fn.Nbody.Append(nod(OAS, nr, checkIdx(nodintconst(nelem)))) + } + } else { + // Generate a for loop. + // for i := 0; i < nelem; i++ + i := temp(types.Types[TINT]) + init := nod(OAS, i, nodintconst(0)) + cond := nod(OLT, i, nodintconst(nelem)) + post := nod(OAS, i, nod(OADD, i, nodintconst(1))) + loop := nod(OFOR, cond, post) + loop.Ninit.Append(init) + // if eq(pi, qi) {} else { goto neq } + nif := nod(OIF, checkIdx(i), nil) + nif.Rlist.Append(nodSym(OGOTO, nil, neq)) + loop.Nbody.Append(nif) + fn.Nbody.Append(loop) + if last { + fn.Nbody.Append(nod(OAS, nr, nodbool(true))) } - nif := nod(OIF, cond, nil) - nif.Rlist.Append(nod(ORETURN, nil, nil)) - fn.Nbody.Append(nif) - return } - - // Generate a for loop. - // for i := 0; i < nelem; i++ - i := temp(types.Types[TINT]) - init := nod(OAS, i, nodintconst(0)) - cond := nod(OLT, i, nodintconst(nelem)) - post := nod(OAS, i, nod(OADD, i, nodintconst(1))) - loop := nod(OFOR, cond, post) - loop.Ninit.Append(init) - // if eq(pi, qi) {} else { return } - check := checkIdx(i) - nif := nod(OIF, check, nil) - nif.Rlist.Append(nod(ORETURN, nil, nil)) - loop.Nbody.Append(nif) - fn.Nbody.Append(loop) } switch t.Elem().Etype { @@ -614,32 +619,28 @@ func geneq(t *types.Type) *obj.LSym { // Do two loops. First, check that all the lengths match (cheap). // Second, check that all the contents match (expensive). // TODO: when the array size is small, unroll the length match checks. - checkAll(3, func(pi, qi *Node) *Node { + checkAll(3, false, func(pi, qi *Node) *Node { // Compare lengths. eqlen, _ := eqstring(pi, qi) return eqlen }) - checkAll(1, func(pi, qi *Node) *Node { + checkAll(1, true, func(pi, qi *Node) *Node { // Compare contents. _, eqmem := eqstring(pi, qi) return eqmem }) case TFLOAT32, TFLOAT64: - checkAll(2, func(pi, qi *Node) *Node { + checkAll(2, true, func(pi, qi *Node) *Node { // p[i] == q[i] return nod(OEQ, pi, qi) }) // TODO: pick apart structs, do them piecemeal too default: - checkAll(1, func(pi, qi *Node) *Node { + checkAll(1, true, func(pi, qi *Node) *Node { // p[i] == q[i] return nod(OEQ, pi, qi) }) } - // return true - ret := nod(ORETURN, nil, nil) - ret.List.Append(nodbool(true)) - fn.Nbody.Append(ret) case TSTRUCT: // Build a list of conditions to satisfy. @@ -717,22 +718,42 @@ func geneq(t *types.Type) *obj.LSym { flatConds = append(flatConds, c...) } - var cond *Node if len(flatConds) == 0 { - cond = nodbool(true) + fn.Nbody.Append(nod(OAS, nr, nodbool(true))) } else { - cond = flatConds[0] - for _, c := range flatConds[1:] { - cond = nod(OANDAND, cond, c) + for _, c := range flatConds[:len(flatConds)-1] { + // if cond {} else { goto neq } + n := nod(OIF, c, nil) + n.Rlist.Append(nodSym(OGOTO, nil, neq)) + fn.Nbody.Append(n) } + fn.Nbody.Append(nod(OAS, nr, flatConds[len(flatConds)-1])) } + } - ret := nod(ORETURN, nil, nil) - ret.List.Append(cond) - fn.Nbody.Append(ret) + // ret: + // return + ret := autolabel(".ret") + fn.Nbody.Append(nodSym(OLABEL, nil, ret)) + fn.Nbody.Append(nod(ORETURN, nil, nil)) + + // neq: + // r = false + // return (or goto ret) + fn.Nbody.Append(nodSym(OLABEL, nil, neq)) + fn.Nbody.Append(nod(OAS, nr, nodbool(false))) + if EqCanPanic(t) || hasCall(fn) { + // Epilogue is large, so share it with the equal case. + fn.Nbody.Append(nodSym(OGOTO, nil, ret)) + } else { + // Epilogue is small, so don't bother sharing. + fn.Nbody.Append(nod(ORETURN, nil, nil)) } + // TODO(khr): the epilogue size detection condition above isn't perfect. + // We should really do a generic CL that shares epilogues across + // the board. See #24936. - if Debug['r'] != 0 { + if Debug.r != 0 { dumplist("geneq body", fn.Nbody) } @@ -754,7 +775,7 @@ func geneq(t *types.Type) *obj.LSym { // neither of which can be nil, and our comparisons // are shallow. fn.Func.SetNilCheckDisabled(true) - funccompile(fn) + xtop = append(xtop, fn) // Generate a closure which points at the function we just generated. dsymptr(closure, 0, sym.Linksym(), 0) @@ -762,6 +783,39 @@ func geneq(t *types.Type) *obj.LSym { return closure } +func hasCall(n *Node) bool { + if n.Op == OCALL || n.Op == OCALLFUNC { + return true + } + if n.Left != nil && hasCall(n.Left) { + return true + } + if n.Right != nil && hasCall(n.Right) { + return true + } + for _, x := range n.Ninit.Slice() { + if hasCall(x) { + return true + } + } + for _, x := range n.Nbody.Slice() { + if hasCall(x) { + return true + } + } + for _, x := range n.List.Slice() { + if hasCall(x) { + return true + } + } + for _, x := range n.Rlist.Slice() { + if hasCall(x) { + return true + } + } + return false +} + // eqfield returns the node // p.field == q.field func eqfield(p *Node, q *Node, field *types.Sym) *Node { diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go index ab578ee8c7..a3a0c8fce8 100644 --- a/src/cmd/compile/internal/gc/align.go +++ b/src/cmd/compile/internal/gc/align.go @@ -5,7 +5,9 @@ package gc import ( + "bytes" "cmd/compile/internal/types" + "fmt" "sort" ) @@ -84,7 +86,7 @@ func expandiface(t *types.Type) { sort.Sort(methcmp(methods)) if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) { - yyerror("interface too large") + yyerrorl(typePos(t), "interface too large") } for i, m := range methods { m.Offset = int64(i) * int64(Widthptr) @@ -148,7 +150,7 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 { maxwidth = 1<<31 - 1 } if o >= maxwidth { - yyerror("type %L too large", errtype) + yyerrorl(typePos(errtype), "type %L too large", errtype) o = 8 // small but nonzero } } @@ -173,6 +175,91 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 { return o } +// findTypeLoop searches for an invalid type declaration loop involving +// type t and reports whether one is found. If so, path contains the +// loop. +// +// path points to a slice used for tracking the sequence of types +// visited. Using a pointer to a slice allows the slice capacity to +// grow and limit reallocations. +func findTypeLoop(t *types.Type, path *[]*types.Type) bool { + // We implement a simple DFS loop-finding algorithm. This + // could be faster, but type cycles are rare. + + if t.Sym != nil { + // Declared type. Check for loops and otherwise + // recurse on the type expression used in the type + // declaration. + + for i, x := range *path { + if x == t { + *path = (*path)[i:] + return true + } + } + + *path = append(*path, t) + if p := asNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) { + return true + } + *path = (*path)[:len(*path)-1] + } else { + // Anonymous type. Recurse on contained types. + + switch t.Etype { + case TARRAY: + if findTypeLoop(t.Elem(), path) { + return true + } + case TSTRUCT: + for _, f := range t.Fields().Slice() { + if findTypeLoop(f.Type, path) { + return true + } + } + case TINTER: + for _, m := range t.Methods().Slice() { + if m.Type.IsInterface() { // embedded interface + if findTypeLoop(m.Type, path) { + return true + } + } + } + } + } + + return false +} + +func reportTypeLoop(t *types.Type) { + if t.Broke() { + return + } + + var l []*types.Type + if !findTypeLoop(t, &l) { + Fatalf("failed to find type loop for: %v", t) + } + + // Rotate loop so that the earliest type declaration is first. + i := 0 + for j, t := range l[1:] { + if typePos(t).Before(typePos(l[i])) { + i = j + 1 + } + } + l = append(l[i:], l[:i]...) + + var msg bytes.Buffer + fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0]) + for _, t := range l { + fmt.Fprintf(&msg, "\t%v: %v refers to\n", linestr(typePos(t)), t) + t.SetBroke(true) + } + fmt.Fprintf(&msg, "\t%v: %v", linestr(typePos(l[0])), l[0]) + yyerrorl(typePos(l[0]), msg.String()) +} + // dowidth calculates and stores the size and alignment for t. // If sizeCalculationDisabled is set, and the size/alignment // have not already been calculated, it calls Fatal. @@ -192,11 +279,7 @@ func dowidth(t *types.Type) { } if t.Width == -2 { - if !t.Broke() { - t.SetBroke(true) - yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t) - } - + reportTypeLoop(t) t.Width = 0 t.Align = 1 return @@ -298,7 +381,7 @@ func dowidth(t *types.Type) { t1 := t.ChanArgs() dowidth(t1) // just in case if t1.Elem().Width >= 1<<16 { - yyerror("channel element type too large (>64kB)") + yyerrorl(typePos(t1), "channel element type too large (>64kB)") } w = 1 // anything will do @@ -308,10 +391,7 @@ func dowidth(t *types.Type) { checkwidth(t.Key()) case TFORW: // should have been filled in - if !t.Broke() { - t.SetBroke(true) - yyerror("invalid recursive type %v", t) - } + reportTypeLoop(t) w = 1 // anything will do case TANY: @@ -334,7 +414,7 @@ func dowidth(t *types.Type) { if t.Elem().Width != 0 { cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width) if uint64(t.NumElem()) > cap { - yyerror("type %L larger than address space", t) + yyerrorl(typePos(t), "type %L larger than address space", t) } } w = t.NumElem() * t.Elem().Width @@ -376,7 +456,7 @@ func dowidth(t *types.Type) { } if Widthptr == 4 && w != int64(int32(w)) { - yyerror("type %v too large", t) + yyerrorl(typePos(t), "type %v too large", t) } t.Width = w diff --git a/src/cmd/compile/internal/gc/bench_test.go b/src/cmd/compile/internal/gc/bench_test.go index 09aaf428c3..8c4288128f 100644 --- a/src/cmd/compile/internal/gc/bench_test.go +++ b/src/cmd/compile/internal/gc/bench_test.go @@ -7,6 +7,7 @@ package gc import "testing" var globl int64 +var globl32 int32 func BenchmarkLoadAdd(b *testing.B) { x := make([]int64, 1024) @@ -20,6 +21,18 @@ func BenchmarkLoadAdd(b *testing.B) { } } +// Added for ppc64 extswsli on power9 +func BenchmarkExtShift(b *testing.B) { + x := make([]int32, 1024) + for i := 0; i < b.N; i++ { + var s int64 + for i := range x { + s ^= int64(x[i]+32) * 8 + } + globl = s + } +} + func BenchmarkModify(b *testing.B) { a := make([]int64, 1024) v := globl @@ -30,6 +43,17 @@ func BenchmarkModify(b *testing.B) { } } +func BenchmarkMullImm(b *testing.B) { + x := make([]int32, 1024) + for i := 0; i < b.N; i++ { + var s int32 + for i := range x { + s += x[i] * 100 + } + globl32 = s + } +} + func BenchmarkConstModify(b *testing.B) { a := make([]int64, 1024) for i := 0; i < b.N; i++ { diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go index 5ced66c0da..10f21f86df 100644 --- a/src/cmd/compile/internal/gc/bexport.go +++ b/src/cmd/compile/internal/gc/bexport.go @@ -81,11 +81,6 @@ func (p *exporter) markType(t *types.Type) { } } -// deltaNewFile is a magic line delta offset indicating a new file. -// We use -64 because it is rare; see issue 20080 and CL 41619. -// -64 is the smallest int that fits in a single byte as a varint. -const deltaNewFile = -64 - // ---------------------------------------------------------------------------- // Export format @@ -126,30 +121,6 @@ const ( aliasTag ) -// untype returns the "pseudo" untyped type for a Ctype (import/export use only). -// (we can't use a pre-initialized array because we must be sure all types are -// set up) -func untype(ctype Ctype) *types.Type { - switch ctype { - case CTINT: - return types.Idealint - case CTRUNE: - return types.Idealrune - case CTFLT: - return types.Idealfloat - case CTCPLX: - return types.Idealcomplex - case CTSTR: - return types.Idealstring - case CTBOOL: - return types.Idealbool - case CTNIL: - return types.Types[TNIL] - } - Fatalf("exporter: unknown Ctype") - return nil -} - var predecl []*types.Type // initialized lazily func predeclared() []*types.Type { @@ -184,13 +155,13 @@ func predeclared() []*types.Type { types.Errortype, // untyped types - untype(CTBOOL), - untype(CTINT), - untype(CTRUNE), - untype(CTFLT), - untype(CTCPLX), - untype(CTSTR), - untype(CTNIL), + types.UntypedBool, + types.UntypedInt, + types.UntypedRune, + types.UntypedFloat, + types.UntypedComplex, + types.UntypedString, + types.Types[TNIL], // package unsafe types.Types[TUNSAFEPTR], diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go index 861ffaaa5b..e04f23e229 100644 --- a/src/cmd/compile/internal/gc/builtin.go +++ b/src/cmd/compile/internal/gc/builtin.go @@ -44,6 +44,7 @@ var runtimeDecls = [...]struct { {"printcomplex", funcTag, 27}, {"printstring", funcTag, 29}, {"printpointer", funcTag, 30}, + {"printuintptr", funcTag, 31}, {"printiface", funcTag, 30}, {"printeface", funcTag, 30}, {"printslice", funcTag, 30}, @@ -51,20 +52,19 @@ var runtimeDecls = [...]struct { {"printsp", funcTag, 9}, {"printlock", funcTag, 9}, {"printunlock", funcTag, 9}, - {"concatstring2", funcTag, 33}, - {"concatstring3", funcTag, 34}, - {"concatstring4", funcTag, 35}, - {"concatstring5", funcTag, 36}, - {"concatstrings", funcTag, 38}, - {"cmpstring", funcTag, 39}, - {"intstring", funcTag, 42}, - {"slicebytetostring", funcTag, 43}, - {"slicebytetostringtmp", funcTag, 44}, - {"slicerunetostring", funcTag, 47}, - {"stringtoslicebyte", funcTag, 49}, - {"stringtoslicerune", funcTag, 52}, - {"slicecopy", funcTag, 53}, - {"slicestringcopy", funcTag, 54}, + {"concatstring2", funcTag, 34}, + {"concatstring3", funcTag, 35}, + {"concatstring4", funcTag, 36}, + {"concatstring5", funcTag, 37}, + {"concatstrings", funcTag, 39}, + {"cmpstring", funcTag, 40}, + {"intstring", funcTag, 43}, + {"slicebytetostring", funcTag, 44}, + {"slicebytetostringtmp", funcTag, 45}, + {"slicerunetostring", funcTag, 48}, + {"stringtoslicebyte", funcTag, 50}, + {"stringtoslicerune", funcTag, 53}, + {"slicecopy", funcTag, 54}, {"decoderune", funcTag, 55}, {"countrunes", funcTag, 56}, {"convI2I", funcTag, 57}, @@ -175,15 +175,16 @@ var runtimeDecls = [...]struct { {"uint64tofloat64", funcTag, 118}, {"uint32tofloat64", funcTag, 119}, {"complex128div", funcTag, 120}, - {"racefuncenter", funcTag, 121}, + {"racefuncenter", funcTag, 31}, {"racefuncenterfp", funcTag, 9}, {"racefuncexit", funcTag, 9}, - {"raceread", funcTag, 121}, - {"racewrite", funcTag, 121}, - {"racereadrange", funcTag, 122}, - {"racewriterange", funcTag, 122}, - {"msanread", funcTag, 122}, - {"msanwrite", funcTag, 122}, + {"raceread", funcTag, 31}, + {"racewrite", funcTag, 31}, + {"racereadrange", funcTag, 121}, + {"racewriterange", funcTag, 121}, + {"msanread", funcTag, 121}, + {"msanwrite", funcTag, 121}, + {"msanmove", funcTag, 122}, {"checkptrAlignment", funcTag, 123}, {"checkptrArithmetic", funcTag, 125}, {"libfuzzerTraceCmp1", funcTag, 127}, @@ -234,31 +235,31 @@ func runtimeTypes() []*types.Type { typs[28] = types.Types[TSTRING] typs[29] = functype(nil, []*Node{anonfield(typs[28])}, nil) typs[30] = functype(nil, []*Node{anonfield(typs[2])}, nil) - typs[31] = types.NewArray(typs[0], 32) - typs[32] = types.NewPtr(typs[31]) - typs[33] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) - typs[34] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) - typs[35] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) - typs[36] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) - typs[37] = types.NewSlice(typs[28]) - typs[38] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[37])}, []*Node{anonfield(typs[28])}) - typs[39] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])}) - typs[40] = types.NewArray(typs[0], 4) - typs[41] = types.NewPtr(typs[40]) - typs[42] = functype(nil, []*Node{anonfield(typs[41]), anonfield(typs[22])}, []*Node{anonfield(typs[28])}) - typs[43] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])}) - typs[44] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])}) - typs[45] = types.Runetype - typs[46] = types.NewSlice(typs[45]) - typs[47] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[46])}, []*Node{anonfield(typs[28])}) - typs[48] = types.NewSlice(typs[0]) - typs[49] = functype(nil, []*Node{anonfield(typs[32]), anonfield(typs[28])}, []*Node{anonfield(typs[48])}) - typs[50] = types.NewArray(typs[45], 32) - typs[51] = types.NewPtr(typs[50]) - typs[52] = functype(nil, []*Node{anonfield(typs[51]), anonfield(typs[28])}, []*Node{anonfield(typs[46])}) - typs[53] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])}) - typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[28])}, []*Node{anonfield(typs[15])}) - typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[45]), anonfield(typs[15])}) + typs[31] = functype(nil, []*Node{anonfield(typs[5])}, nil) + typs[32] = types.NewArray(typs[0], 32) + typs[33] = types.NewPtr(typs[32]) + typs[34] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) + typs[35] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) + typs[36] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) + typs[37] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])}) + typs[38] = types.NewSlice(typs[28]) + typs[39] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[38])}, []*Node{anonfield(typs[28])}) + typs[40] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])}) + typs[41] = types.NewArray(typs[0], 4) + typs[42] = types.NewPtr(typs[41]) + typs[43] = functype(nil, []*Node{anonfield(typs[42]), anonfield(typs[22])}, []*Node{anonfield(typs[28])}) + typs[44] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])}) + typs[45] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])}) + typs[46] = types.Runetype + typs[47] = types.NewSlice(typs[46]) + typs[48] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[47])}, []*Node{anonfield(typs[28])}) + typs[49] = types.NewSlice(typs[0]) + typs[50] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28])}, []*Node{anonfield(typs[49])}) + typs[51] = types.NewArray(typs[46], 32) + typs[52] = types.NewPtr(typs[51]) + typs[53] = functype(nil, []*Node{anonfield(typs[52]), anonfield(typs[28])}, []*Node{anonfield(typs[47])}) + typs[54] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])}) + typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[46]), anonfield(typs[15])}) typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])}) typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])}) typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])}) @@ -324,8 +325,8 @@ func runtimeTypes() []*types.Type { typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])}) typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])}) typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])}) - typs[121] = functype(nil, []*Node{anonfield(typs[5])}, nil) - typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil) + typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil) + typs[122] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5]), anonfield(typs[5])}, nil) typs[123] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil) typs[124] = types.NewSlice(typs[7]) typs[125] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[124])}, nil) diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go index 635da80f7c..acb69c7b28 100644 --- a/src/cmd/compile/internal/gc/builtin/runtime.go +++ b/src/cmd/compile/internal/gc/builtin/runtime.go @@ -54,6 +54,7 @@ func printuint(uint64) func printcomplex(complex128) func printstring(string) func printpointer(any) +func printuintptr(uintptr) func printiface(any) func printeface(any) func printslice(any) @@ -75,8 +76,7 @@ func slicebytetostringtmp(ptr *byte, n int) string func slicerunetostring(*[32]byte, []rune) string func stringtoslicebyte(*[32]byte, string) []byte func stringtoslicerune(*[32]rune, string) []rune -func slicecopy(toPtr *any, toLen int, frPtr *any, frLen int, wid uintptr) int -func slicestringcopy(toPtr *byte, toLen int, fr string) int +func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int func decoderune(string, int) (retv rune, retk int) func countrunes(string) int @@ -237,6 +237,7 @@ func racewriterange(addr, size uintptr) // memory sanitizer func msanread(addr, size uintptr) func msanwrite(addr, size uintptr) +func msanmove(dst, src, size uintptr) func checkptrAlignment(unsafe.Pointer, *byte, uintptr) func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer) diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 250be38e5b..bd350f696e 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -71,6 +71,10 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *Node { return clo } +// typecheckclosure typechecks an OCLOSURE node. It also creates the named +// function associated with the closure. +// TODO: This creation of the named function should probably really be done in a +// separate pass from type-checking. func typecheckclosure(clo *Node, top int) { xfunc := clo.Func.Closure // Set current associated iota value, so iota can be used inside @@ -198,7 +202,7 @@ func capturevars(xfunc *Node) { outer = nod(OADDR, outer, nil) } - if Debug['m'] > 1 { + if Debug.m > 1 { var name *types.Sym if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil { name = v.Name.Curfn.Func.Nname.Sym @@ -434,6 +438,8 @@ func typecheckpartialcall(fn *Node, sym *types.Sym) { fn.Type = xfunc.Type } +// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed +// for partial calls. func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node { rcvrtype := fn.Left.Type sym := methodSymSuffix(rcvrtype, meth, "-fm") @@ -500,6 +506,10 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node { funcbody() xfunc = typecheck(xfunc, ctxStmt) + // Need to typecheck the body of the just-generated wrapper. + // typecheckslice() requires that Curfn is set when processing an ORETURN. + Curfn = xfunc + typecheckslice(xfunc.Nbody.Slice(), ctxStmt) sym.Def = asTypesNode(xfunc) xtop = append(xtop, xfunc) Curfn = savecurfn diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index fe73df9d57..b92c8d66b5 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -44,7 +44,7 @@ func (v Val) Ctype() Ctype { Fatalf("unexpected Ctype for %T", v.U) panic("unreachable") case nil: - return 0 + return CTxxx case *NilVal: return CTNIL case bool: @@ -114,16 +114,16 @@ func (v Val) Interface() interface{} { type NilVal struct{} -// Int64 returns n as an int64. +// Int64Val returns n as an int64. // n must be an integer or rune constant. -func (n *Node) Int64() int64 { +func (n *Node) Int64Val() int64 { if !Isconst(n, CTINT) { - Fatalf("Int64(%v)", n) + Fatalf("Int64Val(%v)", n) } return n.Val().U.(*Mpint).Int64() } -// CanInt64 reports whether it is safe to call Int64() on n. +// CanInt64 reports whether it is safe to call Int64Val() on n. func (n *Node) CanInt64() bool { if !Isconst(n, CTINT) { return false @@ -131,18 +131,27 @@ func (n *Node) CanInt64() bool { // if the value inside n cannot be represented as an int64, the // return value of Int64 is undefined - return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0 + return n.Val().U.(*Mpint).CmpInt64(n.Int64Val()) == 0 } -// Bool returns n as a bool. +// BoolVal returns n as a bool. // n must be a boolean constant. -func (n *Node) Bool() bool { +func (n *Node) BoolVal() bool { if !Isconst(n, CTBOOL) { - Fatalf("Bool(%v)", n) + Fatalf("BoolVal(%v)", n) } return n.Val().U.(bool) } +// StringVal returns the value of a literal string Node as a string. +// n must be a string constant. +func (n *Node) StringVal() string { + if !Isconst(n, CTSTR) { + Fatalf("StringVal(%v)", n) + } + return n.Val().U.(string) +} + // truncate float literal fv to 32-bit or 64-bit precision // according to type; return truncated value. func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt { @@ -261,7 +270,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod } if t == nil || !okforconst[t.Etype] { - t = defaultType(idealkind(n)) + t = defaultType(n.Type) } switch n.Op { @@ -612,7 +621,7 @@ func evconst(n *Node) { var strs []string i2 := i1 for i2 < len(s) && Isconst(s[i2], CTSTR) { - strs = append(strs, strlit(s[i2])) + strs = append(strs, s[i2].StringVal()) i2++ } @@ -635,7 +644,7 @@ func evconst(n *Node) { switch nl.Type.Etype { case TSTRING: if Isconst(nl, CTSTR) { - setintconst(n, int64(len(strlit(nl)))) + setintconst(n, int64(len(nl.StringVal()))) } case TARRAY: if !hascallchan(nl) { @@ -838,10 +847,6 @@ Outer: return Val{} } u.Quo(y) - case OMOD, OOR, OAND, OANDNOT, OXOR: - // TODO(mdempsky): Move to typecheck; see #31060. - yyerror("invalid operation: operator %v not defined on untyped float", op) - return Val{} default: break Outer } @@ -867,10 +872,6 @@ Outer: yyerror("complex division by zero") return Val{} } - case OMOD, OOR, OAND, OANDNOT, OXOR: - // TODO(mdempsky): Move to typecheck; see #31060. - yyerror("invalid operation: operator %v not defined on untyped complex", op) - return Val{} default: break Outer } @@ -932,15 +933,6 @@ func unaryOp(op Op, x Val, t *types.Type) Val { } u.Xor(x) return Val{U: u} - - case CTFLT: - // TODO(mdempsky): Move to typecheck; see #31060. - yyerror("invalid operation: operator %v not defined on untyped float", op) - return Val{} - case CTCPLX: - // TODO(mdempsky): Move to typecheck; see #31060. - yyerror("invalid operation: operator %v not defined on untyped complex", op) - return Val{} } case ONOT: @@ -994,10 +986,8 @@ func setconst(n *Node, v Val) { Xoffset: BADWIDTH, } n.SetVal(v) - if n.Type.IsUntyped() { - // TODO(mdempsky): Make typecheck responsible for setting - // the correct untyped type. - n.Type = idealType(v.Ctype()) + if vt := idealType(v.Ctype()); n.Type.IsUntyped() && n.Type != vt { + Fatalf("untyped type mismatch, have: %v, want: %v", n.Type, vt) } // Check range. @@ -1038,17 +1028,17 @@ func nodlit(v Val) *Node { func idealType(ct Ctype) *types.Type { switch ct { case CTSTR: - return types.Idealstring + return types.UntypedString case CTBOOL: - return types.Idealbool + return types.UntypedBool case CTINT: - return types.Idealint + return types.UntypedInt case CTRUNE: - return types.Idealrune + return types.UntypedRune case CTFLT: - return types.Idealfloat + return types.UntypedFloat case CTCPLX: - return types.Idealcomplex + return types.UntypedComplex case CTNIL: return types.Types[TNIL] } @@ -1056,67 +1046,6 @@ func idealType(ct Ctype) *types.Type { return nil } -// idealkind returns a constant kind like consttype -// but for an arbitrary "ideal" (untyped constant) expression. -func idealkind(n *Node) Ctype { - if n == nil || !n.Type.IsUntyped() { - return CTxxx - } - - switch n.Op { - default: - return CTxxx - - case OLITERAL: - return n.Val().Ctype() - - // numeric kinds. - case OADD, - OAND, - OANDNOT, - OBITNOT, - ODIV, - ONEG, - OMOD, - OMUL, - OSUB, - OXOR, - OOR, - OPLUS: - k1 := idealkind(n.Left) - k2 := idealkind(n.Right) - if k1 > k2 { - return k1 - } else { - return k2 - } - - case OREAL, OIMAG: - return CTFLT - - case OCOMPLEX: - return CTCPLX - - case OADDSTR: - return CTSTR - - case OANDAND, - OEQ, - OGE, - OGT, - OLE, - OLT, - ONE, - ONOT, - OOROR: - return CTBOOL - - // shifts (beware!). - case OLSH, ORSH: - return idealkind(n.Left) - } -} - // defaultlit on both nodes simultaneously; // if they're both ideal going in they better // get the same type going out. @@ -1152,41 +1081,63 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { return l, r } - k := idealkind(l) - if rk := idealkind(r); rk > k { - k = rk - } - t := defaultType(k) + t := defaultType(mixUntyped(l.Type, r.Type)) l = convlit(l, t) r = convlit(r, t) return l, r } -func defaultType(k Ctype) *types.Type { - switch k { - case CTBOOL: +func ctype(t *types.Type) Ctype { + switch t { + case types.UntypedBool: + return CTBOOL + case types.UntypedString: + return CTSTR + case types.UntypedInt: + return CTINT + case types.UntypedRune: + return CTRUNE + case types.UntypedFloat: + return CTFLT + case types.UntypedComplex: + return CTCPLX + } + Fatalf("bad type %v", t) + panic("unreachable") +} + +func mixUntyped(t1, t2 *types.Type) *types.Type { + t := t1 + if ctype(t2) > ctype(t1) { + t = t2 + } + return t +} + +func defaultType(t *types.Type) *types.Type { + if !t.IsUntyped() || t.Etype == TNIL { + return t + } + + switch t { + case types.UntypedBool: return types.Types[TBOOL] - case CTSTR: + case types.UntypedString: return types.Types[TSTRING] - case CTINT: + case types.UntypedInt: return types.Types[TINT] - case CTRUNE: + case types.UntypedRune: return types.Runetype - case CTFLT: + case types.UntypedFloat: return types.Types[TFLOAT64] - case CTCPLX: + case types.UntypedComplex: return types.Types[TCOMPLEX128] } - Fatalf("bad idealkind: %v", k) - return nil -} -// strlit returns the value of a literal string Node as a string. -func strlit(n *Node) string { - return n.Val().U.(string) + Fatalf("bad type %v", t) + return nil } -// TODO(gri) smallintconst is only used in one place - can we used indexconst? func smallintconst(n *Node) bool { if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { switch simtype[n.Type.Etype] { diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 69eb13f607..6e90eb4d65 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -257,6 +257,8 @@ func symfield(s *types.Sym, typ *types.Type) *Node { // oldname returns the Node that declares symbol s in the current scope. // If no such Node currently exists, an ONONAME Node is returned instead. +// Automatically creates a new closure variable if the referenced symbol was +// declared in a different (containing) function. func oldname(s *types.Sym) *Node { n := asNode(s.Def) if n == nil { @@ -283,7 +285,7 @@ func oldname(s *types.Sym) *Node { c.Name.Defn = n // Link into list of active closure variables. - // Popped from list in func closurebody. + // Popped from list in func funcLit. c.Name.Param.Outer = n.Name.Param.Innermost n.Name.Param.Innermost = c @@ -382,14 +384,11 @@ func ifacedcl(n *Node) { // returns in auto-declaration context. func funchdr(n *Node) { // change the declaration context from extern to auto - if Curfn == nil && dclcontext != PEXTERN { - Fatalf("funchdr: dclcontext = %d", dclcontext) - } - + funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext}) + Curfn = n dclcontext = PAUTO + types.Markdcl() - funcstack = append(funcstack, Curfn) - Curfn = n if n.Func.Nname != nil { funcargs(n.Func.Nname.Name.Param.Ntype) @@ -497,21 +496,22 @@ func funcarg2(f *types.Field, ctxt Class) { declare(n, ctxt) } -var funcstack []*Node // stack of previous values of Curfn +var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext + +type funcStackEnt struct { + curfn *Node + dclcontext Class +} // finish the body. // called in auto-declaration context. // returns in extern-declaration context. func funcbody() { - // change the declaration context from auto to extern - if dclcontext != PAUTO { - Fatalf("funcbody: unexpected dclcontext %d", dclcontext) - } + // change the declaration context from auto to previous context types.Popdcl() - funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1] - if Curfn == nil { - dclcontext = PEXTERN - } + var e funcStackEnt + funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1] + Curfn, dclcontext = e.curfn, e.dclcontext } // structs, functions, and methods. diff --git a/src/cmd/compile/internal/gc/dwinl.go b/src/cmd/compile/internal/gc/dwinl.go index 27e2cbcd98..bb5ae61cbb 100644 --- a/src/cmd/compile/internal/gc/dwinl.go +++ b/src/cmd/compile/internal/gc/dwinl.go @@ -8,6 +8,7 @@ import ( "cmd/internal/dwarf" "cmd/internal/obj" "cmd/internal/src" + "fmt" "strings" ) @@ -34,7 +35,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls { // Walk progs to build up the InlCalls data structure var prevpos src.XPos - for p := fnsym.Func.Text; p != nil; p = p.Link { + for p := fnsym.Func().Text; p != nil; p = p.Link { if p.Pos == prevpos { continue } @@ -150,7 +151,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls { start := int64(-1) curii := -1 var prevp *obj.Prog - for p := fnsym.Func.Text; p != nil; prevp, p = p, p.Link { + for p := fnsym.Func().Text; p != nil; prevp, p = p, p.Link { if prevp != nil && p.Pos == prevp.Pos { continue } @@ -170,12 +171,32 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls { addRange(inlcalls.Calls, start, fnsym.Size, curii, imap) } + // Issue 33188: if II foo is a child of II bar, then ensure that + // bar's ranges include the ranges of foo (the loop above will produce + // disjoint ranges). + for k, c := range inlcalls.Calls { + if c.Root { + unifyCallRanges(inlcalls, k) + } + } + // Debugging if Debug_gendwarfinl != 0 { dumpInlCalls(inlcalls) dumpInlVars(dwVars) } + // Perform a consistency check on inlined routine PC ranges + // produced by unifyCallRanges above. In particular, complain in + // cases where you have A -> B -> C (e.g. C is inlined into B, and + // B is inlined into A) and the ranges for B are not enclosed + // within the ranges for A, or C within B. + for k, c := range inlcalls.Calls { + if c.Root { + checkInlCall(fnsym.Name, inlcalls, fnsym.Size, k, -1) + } + } + return inlcalls } @@ -355,3 +376,74 @@ func dumpInlVars(dwvars []*dwarf.Var) { Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ) } } + +func rangesContains(par []dwarf.Range, rng dwarf.Range) (bool, string) { + for _, r := range par { + if rng.Start >= r.Start && rng.End <= r.End { + return true, "" + } + } + msg := fmt.Sprintf("range [%d,%d) not contained in {", rng.Start, rng.End) + for _, r := range par { + msg += fmt.Sprintf(" [%d,%d)", r.Start, r.End) + } + msg += " }" + return false, msg +} + +func rangesContainsAll(parent, child []dwarf.Range) (bool, string) { + for _, r := range child { + c, m := rangesContains(parent, r) + if !c { + return false, m + } + } + return true, "" +} + +// checkInlCall verifies that the PC ranges for inline info 'idx' are +// enclosed/contained within the ranges of its parent inline (or if +// this is a root/toplevel inline, checks that the ranges fall within +// the extent of the top level function). A panic is issued if a +// malformed range is found. +func checkInlCall(funcName string, inlCalls dwarf.InlCalls, funcSize int64, idx, parentIdx int) { + + // Callee + ic := inlCalls.Calls[idx] + callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex).Name + calleeRanges := ic.Ranges + + // Caller + caller := funcName + parentRanges := []dwarf.Range{dwarf.Range{Start: int64(0), End: funcSize}} + if parentIdx != -1 { + pic := inlCalls.Calls[parentIdx] + caller = Ctxt.InlTree.InlinedFunction(pic.InlIndex).Name + parentRanges = pic.Ranges + } + + // Callee ranges contained in caller ranges? + c, m := rangesContainsAll(parentRanges, calleeRanges) + if !c { + Fatalf("** malformed inlined routine range in %s: caller %s callee %s II=%d %s\n", funcName, caller, callee, idx, m) + } + + // Now visit kids + for _, k := range ic.Children { + checkInlCall(funcName, inlCalls, funcSize, k, idx) + } +} + +// unifyCallRanges ensures that the ranges for a given inline +// transitively include all of the ranges for its child inlines. +func unifyCallRanges(inlcalls dwarf.InlCalls, idx int) { + ic := &inlcalls.Calls[idx] + for _, childIdx := range ic.Children { + // First make sure child ranges are unified. + unifyCallRanges(inlcalls, childIdx) + + // Then merge child ranges into ranges for this inline. + cic := inlcalls.Calls[childIdx] + ic.Ranges = dwarf.MergeRanges(ic.Ranges, cic.Ranges) + } +} diff --git a/src/cmd/compile/internal/gc/embed.go b/src/cmd/compile/internal/gc/embed.go new file mode 100644 index 0000000000..103949c1f9 --- /dev/null +++ b/src/cmd/compile/internal/gc/embed.go @@ -0,0 +1,273 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gc + +import ( + "cmd/compile/internal/syntax" + "cmd/compile/internal/types" + "cmd/internal/obj" + "encoding/json" + "io/ioutil" + "log" + "path" + "sort" + "strconv" + "strings" +) + +var embedlist []*Node + +var embedCfg struct { + Patterns map[string][]string + Files map[string]string +} + +func readEmbedCfg(file string) { + data, err := ioutil.ReadFile(file) + if err != nil { + log.Fatalf("-embedcfg: %v", err) + } + if err := json.Unmarshal(data, &embedCfg); err != nil { + log.Fatalf("%s: %v", file, err) + } + if embedCfg.Patterns == nil { + log.Fatalf("%s: invalid embedcfg: missing Patterns", file) + } + if embedCfg.Files == nil { + log.Fatalf("%s: invalid embedcfg: missing Files", file) + } +} + +const ( + embedUnknown = iota + embedBytes + embedString + embedFiles +) + +var numLocalEmbed int + +func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []PragmaEmbed) (newExprs []*Node) { + haveEmbed := false + for _, decl := range p.file.DeclList { + imp, ok := decl.(*syntax.ImportDecl) + if !ok { + // imports always come first + break + } + path, _ := strconv.Unquote(imp.Path.Value) + if path == "embed" { + haveEmbed = true + break + } + } + + pos := embeds[0].Pos + if !haveEmbed { + p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"") + return exprs + } + if embedCfg.Patterns == nil { + p.yyerrorpos(pos, "invalid go:embed: build system did not supply embed configuration") + return exprs + } + if len(names) > 1 { + p.yyerrorpos(pos, "go:embed cannot apply to multiple vars") + return exprs + } + if len(exprs) > 0 { + p.yyerrorpos(pos, "go:embed cannot apply to var with initializer") + return exprs + } + if typ == nil { + // Should not happen, since len(exprs) == 0 now. + p.yyerrorpos(pos, "go:embed cannot apply to var without type") + return exprs + } + + kind := embedKindApprox(typ) + if kind == embedUnknown { + p.yyerrorpos(pos, "go:embed cannot apply to var of type %v", typ) + return exprs + } + + // Build list of files to store. + have := make(map[string]bool) + var list []string + for _, e := range embeds { + for _, pattern := range e.Patterns { + files, ok := embedCfg.Patterns[pattern] + if !ok { + p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern) + } + for _, file := range files { + if embedCfg.Files[file] == "" { + p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map file: %s", file) + continue + } + if !have[file] { + have[file] = true + list = append(list, file) + } + if kind == embedFiles { + for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) { + have[dir] = true + list = append(list, dir+"/") + } + } + } + } + } + sort.Slice(list, func(i, j int) bool { + return embedFileLess(list[i], list[j]) + }) + + if kind == embedString || kind == embedBytes { + if len(list) > 1 { + p.yyerrorpos(pos, "invalid go:embed: multiple files for type %v", typ) + return exprs + } + } + + v := names[0] + if dclcontext != PEXTERN { + numLocalEmbed++ + v = newnamel(v.Pos, lookupN("embed.", numLocalEmbed)) + v.Sym.Def = asTypesNode(v) + v.Name.Param.Ntype = typ + v.SetClass(PEXTERN) + externdcl = append(externdcl, v) + exprs = []*Node{v} + } + + v.Name.Param.SetEmbedFiles(list) + embedlist = append(embedlist, v) + return exprs +} + +// embedKindApprox determines the kind of embedding variable, approximately. +// The match is approximate because we haven't done scope resolution yet and +// can't tell whether "string" and "byte" really mean "string" and "byte". +// The result must be confirmed later, after type checking, using embedKind. +func embedKindApprox(typ *Node) int { + if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) { + return embedFiles + } + // These are not guaranteed to match only string and []byte - + // maybe the local package has redefined one of those words. + // But it's the best we can do now during the noder. + // The stricter check happens later, in initEmbed calling embedKind. + if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == localpkg { + return embedString + } + if typ.Op == OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == localpkg { + return embedBytes + } + return embedUnknown +} + +// embedKind determines the kind of embedding variable. +func embedKind(typ *types.Type) int { + if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) { + return embedFiles + } + if typ == types.Types[TSTRING] { + return embedString + } + if typ.Sym == nil && typ.IsSlice() && typ.Elem() == types.Bytetype { + return embedBytes + } + return embedUnknown +} + +func embedFileNameSplit(name string) (dir, elem string, isDir bool) { + if name[len(name)-1] == '/' { + isDir = true + name = name[:len(name)-1] + } + i := len(name) - 1 + for i >= 0 && name[i] != '/' { + i-- + } + if i < 0 { + return ".", name, isDir + } + return name[:i], name[i+1:], isDir +} + +// embedFileLess implements the sort order for a list of embedded files. +// See the comment inside ../../../../embed/embed.go's Files struct for rationale. +func embedFileLess(x, y string) bool { + xdir, xelem, _ := embedFileNameSplit(x) + ydir, yelem, _ := embedFileNameSplit(y) + return xdir < ydir || xdir == ydir && xelem < yelem +} + +func dumpembeds() { + for _, v := range embedlist { + initEmbed(v) + } +} + +// initEmbed emits the init data for a //go:embed variable, +// which is either a string, a []byte, or an embed.FS. +func initEmbed(v *Node) { + files := v.Name.Param.EmbedFiles() + switch kind := embedKind(v.Type); kind { + case embedUnknown: + yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type) + + case embedString, embedBytes: + file := files[0] + fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], kind == embedString, nil) + if err != nil { + yyerrorl(v.Pos, "embed %s: %v", file, err) + } + sym := v.Sym.Linksym() + off := 0 + off = dsymptr(sym, off, fsym, 0) // data string + off = duintptr(sym, off, uint64(size)) // len + if kind == embedBytes { + duintptr(sym, off, uint64(size)) // cap for slice + } + + case embedFiles: + slicedata := Ctxt.Lookup(`"".` + v.Sym.Name + `.files`) + off := 0 + // []files pointed at by Files + off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice + off = duintptr(slicedata, off, uint64(len(files))) + off = duintptr(slicedata, off, uint64(len(files))) + + // embed/embed.go type file is: + // name string + // data string + // hash [16]byte + // Emit one of these per file in the set. + const hashSize = 16 + hash := make([]byte, hashSize) + for _, file := range files { + off = dsymptr(slicedata, off, stringsym(v.Pos, file), 0) // file string + off = duintptr(slicedata, off, uint64(len(file))) + if strings.HasSuffix(file, "/") { + // entry for directory - no data + off = duintptr(slicedata, off, 0) + off = duintptr(slicedata, off, 0) + off += hashSize + } else { + fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], true, hash) + if err != nil { + yyerrorl(v.Pos, "embed %s: %v", file, err) + } + off = dsymptr(slicedata, off, fsym, 0) // data string + off = duintptr(slicedata, off, uint64(size)) + off = int(slicedata.WriteBytes(Ctxt, int64(off), hash)) + } + } + ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL) + sym := v.Sym.Linksym() + dsymptr(sym, 0, slicedata, 0) + } +} diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 4b843aba35..6f328ab5ea 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -169,36 +169,47 @@ func mayAffectMemory(n *Node) bool { } } -func mustHeapAlloc(n *Node) bool { +// heapAllocReason returns the reason the given Node must be heap +// allocated, or the empty string if it doesn't. +func heapAllocReason(n *Node) string { if n.Type == nil { - return false + return "" } // Parameters are always passed via the stack. if n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) { - return false + return "" } if n.Type.Width > maxStackVarSize { - return true + return "too large for stack" } if (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize { - return true + return "too large for stack" } if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize { - return true + return "too large for stack" } if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize { - return true + return "too large for stack" } - if n.Op == OMAKESLICE && !isSmallMakeSlice(n) { - return true + if n.Op == OMAKESLICE { + r := n.Right + if r == nil { + r = n.Left + } + if !smallintconst(r) { + return "non-constant size" + } + if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width { + return "too large for stack" + } } - return false + return "" } // addrescapes tags node n as having had its address taken @@ -271,7 +282,7 @@ func addrescapes(n *Node) { // moveToHeap records the parameter or local variable n as moved to the heap. func moveToHeap(n *Node) { - if Debug['r'] != 0 { + if Debug.r != 0 { Dump("MOVE", n) } if compiling_runtime { @@ -348,7 +359,7 @@ func moveToHeap(n *Node) { n.Xoffset = 0 n.Name.Param.Heapaddr = heapaddr n.Esc = EscHeap - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(n.Pos, "moved to heap: %v", n) } } @@ -377,8 +388,8 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { // This really doesn't have much to do with escape analysis per se, // but we are reusing the ability to annotate an individual function // argument and pass those annotations along to importing code. - if f.Type.Etype == TUINTPTR { - if Debug['m'] != 0 { + if f.Type.IsUintptr() { + if Debug.m != 0 { Warnl(f.Pos, "assuming %v is unsafe uintptr", name()) } return unsafeUintptrTag @@ -393,11 +404,11 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { // External functions are assumed unsafe, unless // //go:noescape is given before the declaration. if fn.Func.Pragma&Noescape != 0 { - if Debug['m'] != 0 && f.Sym != nil { + if Debug.m != 0 && f.Sym != nil { Warnl(f.Pos, "%v does not escape", name()) } } else { - if Debug['m'] != 0 && f.Sym != nil { + if Debug.m != 0 && f.Sym != nil { Warnl(f.Pos, "leaking param: %v", name()) } esc.AddHeap(0) @@ -407,15 +418,15 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { } if fn.Func.Pragma&UintptrEscapes != 0 { - if f.Type.Etype == TUINTPTR { - if Debug['m'] != 0 { + if f.Type.IsUintptr() { + if Debug.m != 0 { Warnl(f.Pos, "marking %v as escaping uintptr", name()) } return uintptrEscapesTag } - if f.IsDDD() && f.Type.Elem().Etype == TUINTPTR { + if f.IsDDD() && f.Type.Elem().IsUintptr() { // final argument is ...uintptr. - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(f.Pos, "marking %v as escaping ...uintptr", name()) } return uintptrEscapesTag @@ -437,7 +448,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { esc := loc.paramEsc esc.Optimize() - if Debug['m'] != 0 && !loc.escapes { + if Debug.m != 0 && !loc.escapes { if esc.Empty() { Warnl(f.Pos, "%v does not escape", name()) } diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index d5cca4a38b..618bdf78e2 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -170,7 +170,7 @@ func (e *Escape) initFunc(fn *Node) { Fatalf("unexpected node: %v", fn) } fn.Esc = EscFuncPlanned - if Debug['m'] > 3 { + if Debug.m > 3 { Dump("escAnalyze", fn) } @@ -247,7 +247,7 @@ func (e *Escape) stmt(n *Node) { lineno = lno }() - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("%v:[%d] %v stmt: %v\n", linestr(lineno), e.loopDepth, funcSym(e.curfn), n) } @@ -275,11 +275,11 @@ func (e *Escape) stmt(n *Node) { case OLABEL: switch asNode(n.Sym.Label) { case &nonlooping: - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n) } case &looping: - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("%v: %v looping label\n", linestr(lineno), n) } e.loopDepth++ @@ -485,7 +485,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) { e.discard(max) case OCONV, OCONVNOP: - if checkPtr(e.curfn, 2) && n.Type.Etype == TUNSAFEPTR && n.Left.Type.IsPtr() { + if checkPtr(e.curfn, 2) && n.Type.IsUnsafePtr() && n.Left.Type.IsPtr() { // When -d=checkptr=2 is enabled, treat // conversions to unsafe.Pointer as an // escaping operation. This allows better @@ -493,7 +493,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) { // easily detect object boundaries on the heap // than the stack. e.assignHeap(n.Left, "conversion to unsafe.Pointer", n) - } else if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR { + } else if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() { e.unsafeValue(k, n.Left) } else { e.expr(k, n.Left) @@ -625,7 +625,7 @@ func (e *Escape) unsafeValue(k EscHole, n *Node) { switch n.Op { case OCONV, OCONVNOP: - if n.Left.Type.Etype == TUNSAFEPTR { + if n.Left.Type.IsUnsafePtr() { e.expr(k, n.Left) } else { e.discard(n.Left) @@ -717,7 +717,7 @@ func (e *Escape) addrs(l Nodes) []EscHole { func (e *Escape) assign(dst, src *Node, why string, where *Node) { // Filter out some no-op assignments for escape analysis. ignore := dst != nil && src != nil && isSelfAssign(dst, src) - if ignore && Debug['m'] != 0 { + if ignore && Debug.m != 0 { Warnl(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where) } @@ -771,10 +771,11 @@ func (e *Escape) call(ks []EscHole, call, where *Node) { var fn *Node switch call.Op { case OCALLFUNC: - if call.Left.Op == ONAME && call.Left.Class() == PFUNC { - fn = call.Left - } else if call.Left.Op == OCLOSURE { - fn = call.Left.Func.Closure.Func.Nname + switch v := staticValue(call.Left); { + case v.Op == ONAME && v.Class() == PFUNC: + fn = v + case v.Op == OCLOSURE: + fn = v.Func.Closure.Func.Nname } case OCALLMETH: fn = asNode(call.Left.Type.FuncType().Nname) @@ -930,7 +931,7 @@ func (k EscHole) note(where *Node, why string) EscHole { if where == nil || why == "" { Fatalf("note: missing where/why") } - if Debug['m'] >= 2 || logopt.Enabled() { + if Debug.m >= 2 || logopt.Enabled() { k.notes = &EscNote{ next: k.notes, where: where, @@ -1030,7 +1031,7 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation { Fatalf("e.curfn isn't set") } if n != nil && n.Type != nil && n.Type.NotInHeap() { - yyerrorl(n.Pos, "%v is go:notinheap; stack allocation disallowed", n.Type) + yyerrorl(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type) } n = canonicalNode(n) @@ -1051,11 +1052,7 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation { } n.SetOpt(loc) - if mustHeapAlloc(n) { - why := "too large for stack" - if n.Op == OMAKESLICE && (!Isconst(n.Left, CTINT) || !Isconst(n.Right, CTINT)) { - why = "non-constant size" - } + if why := heapAllocReason(n); why != "" { e.flow(e.heapHole().addr(n, why), loc) } } @@ -1080,9 +1077,9 @@ func (e *Escape) flow(k EscHole, src *EscLocation) { return } if dst.escapes && k.derefs < 0 { // dst = &src - if Debug['m'] >= 2 || logopt.Enabled() { + if Debug.m >= 2 || logopt.Enabled() { pos := linestr(src.n.Pos) - if Debug['m'] >= 2 { + if Debug.m >= 2 { fmt.Printf("%s: %v escapes to heap:\n", pos, src.n) } explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{}) @@ -1182,8 +1179,8 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc // that value flow for tagging the function // later. if l.isName(PPARAM) { - if (logopt.Enabled() || Debug['m'] >= 2) && !l.escapes { - if Debug['m'] >= 2 { + if (logopt.Enabled() || Debug.m >= 2) && !l.escapes { + if Debug.m >= 2 { fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", linestr(l.n.Pos), l.n, e.explainLoc(root), base) } explanation := e.explainPath(root, l) @@ -1199,8 +1196,8 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc // outlives it, then l needs to be heap // allocated. if addressOf && !l.escapes { - if logopt.Enabled() || Debug['m'] >= 2 { - if Debug['m'] >= 2 { + if logopt.Enabled() || Debug.m >= 2 { + if Debug.m >= 2 { fmt.Printf("%s: %v escapes to heap:\n", linestr(l.n.Pos), l.n) } explanation := e.explainPath(root, l) @@ -1238,7 +1235,7 @@ func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt { for { // Prevent infinite loop. if visited[src] { - if Debug['m'] >= 2 { + if Debug.m >= 2 { fmt.Printf("%s: warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos) } break @@ -1266,7 +1263,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n if derefs >= 0 { ops = strings.Repeat("*", derefs) } - print := Debug['m'] >= 2 + print := Debug.m >= 2 flow := fmt.Sprintf(" flow: %s = %s%v:", e.explainLoc(dst), ops, e.explainLoc(srcloc)) if print { @@ -1420,7 +1417,7 @@ func (e *Escape) finish(fns []*Node) { if loc.escapes { if n.Op != ONAME { - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(n.Pos, "%S escapes to heap", n) } if logopt.Enabled() { @@ -1430,7 +1427,7 @@ func (e *Escape) finish(fns []*Node) { n.Esc = EscHeap addrescapes(n) } else { - if Debug['m'] != 0 && n.Op != ONAME { + if Debug.m != 0 && n.Op != ONAME { Warnl(n.Pos, "%S does not escape", n) } n.Esc = EscNone diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go index 44bea2b1fd..c6917e0f81 100644 --- a/src/cmd/compile/internal/gc/export.go +++ b/src/cmd/compile/internal/gc/export.go @@ -31,7 +31,7 @@ func exportsym(n *Node) { } n.Sym.SetOnExportList(true) - if Debug['E'] != 0 { + if Debug.E != 0 { fmt.Printf("export symbol %v\n", n.Sym) } @@ -96,7 +96,7 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node { return n } -// pkgtype returns the named type declared by symbol s. +// importtype returns the named type declared by symbol s. // If no such type has been declared yet, a forward declaration is returned. // ipkg is the package being imported func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type { @@ -150,7 +150,7 @@ func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val n.SetVal(val) - if Debug['E'] != 0 { + if Debug.E != 0 { fmt.Printf("import const %v %L = %v\n", s, t, val) } } @@ -166,7 +166,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { n.Func = new(Func) t.SetNname(asTypesNode(n)) - if Debug['E'] != 0 { + if Debug.E != 0 { fmt.Printf("import func %v%S\n", s, t) } } @@ -179,7 +179,7 @@ func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { return } - if Debug['E'] != 0 { + if Debug.E != 0 { fmt.Printf("import var %v %L\n", s, t) } } @@ -192,7 +192,7 @@ func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { return } - if Debug['E'] != 0 { + if Debug.E != 0 { fmt.Printf("import type %v = %L\n", s, t) } } diff --git a/src/cmd/compile/internal/gc/float_test.go b/src/cmd/compile/internal/gc/float_test.go index 6ae363be22..c619d25705 100644 --- a/src/cmd/compile/internal/gc/float_test.go +++ b/src/cmd/compile/internal/gc/float_test.go @@ -6,17 +6,9 @@ package gc import ( "math" - "os" - "runtime" "testing" ) -// For GO386=387, make sure fucomi* opcodes are not used -// for comparison operations. -// Note that this test will fail only on a Pentium MMX -// processor (with GOARCH=386 GO386=387), as it just runs -// some code and looks for an unimplemented instruction fault. - //go:noinline func compare1(a, b float64) bool { return a < b @@ -137,9 +129,6 @@ func TestFloatCompareFolded(t *testing.T) { } } -// For GO386=387, make sure fucomi* opcodes are not used -// for float->int conversions. - //go:noinline func cvt1(a float64) uint64 { return uint64(a) @@ -370,14 +359,6 @@ func TestFloat32StoreToLoadConstantFold(t *testing.T) { // are not converted to quiet NaN (qNaN) values during compilation. // See issue #27193 for more information. - // TODO: this method for detecting 387 won't work if the compiler has been - // built using GOARCH=386 GO386=387 and either the target is a different - // architecture or the GO386=387 environment variable is not set when the - // test is run. - if runtime.GOARCH == "386" && os.Getenv("GO386") == "387" { - t.Skip("signaling NaNs are not propagated on 387 (issue #27516)") - } - // signaling NaNs { const nan = uint32(0x7f800001) // sNaN diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index 866cd0a714..f92f5d0e88 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -419,10 +419,19 @@ func (n *Node) format(s fmt.State, verb rune, mode fmtMode) { func (n *Node) jconv(s fmt.State, flag FmtFlag) { c := flag & FmtShort + // Useful to see which nodes in a Node Dump/dumplist are actually identical + if Debug_dumpptrs != 0 { + fmt.Fprintf(s, " p(%p)", n) + } if c == 0 && n.Name != nil && n.Name.Vargen != 0 { fmt.Fprintf(s, " g(%d)", n.Name.Vargen) } + if Debug_dumpptrs != 0 && c == 0 && n.Name != nil && n.Name.Defn != nil { + // Useful to see where Defn is set and what node it points to + fmt.Fprintf(s, " defn(%p)", n.Name.Defn) + } + if n.Pos.IsKnown() { pfx := "" switch n.Pos.IsStmt() { @@ -492,6 +501,15 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) { if n.Name.Assigned() { fmt.Fprint(s, " assigned") } + if n.Name.IsClosureVar() { + fmt.Fprint(s, " closurevar") + } + if n.Name.Captured() { + fmt.Fprint(s, " captured") + } + if n.Name.IsOutputParamHeapAddr() { + fmt.Fprint(s, " outputparamheapaddr") + } } if n.Bounded() { fmt.Fprint(s, " bounded") @@ -711,6 +729,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited return } + if t.Etype == types.TRESULTS { + tys := t.Extra.(*types.Results).Types + for i, et := range tys { + if i > 0 { + b.WriteByte(',') + } + b.WriteString(et.String()) + } + return + } + flag, mode = flag.update(mode) if mode == FTypeIdName { flag |= FmtUnsigned @@ -762,17 +791,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" { var name string switch t { - case types.Idealbool: + case types.UntypedBool: name = "untyped bool" - case types.Idealstring: + case types.UntypedString: name = "untyped string" - case types.Idealint: + case types.UntypedInt: name = "untyped int" - case types.Idealrune: + case types.UntypedRune: name = "untyped rune" - case types.Idealfloat: + case types.UntypedFloat: name = "untyped float" - case types.Idealcomplex: + case types.UntypedComplex: name = "untyped complex" default: name = basicnames[t.Etype] @@ -781,6 +810,13 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited return } + if mode == FDbg { + b.WriteString(t.Etype.String()) + b.WriteByte('-') + tconv2(b, t, flag, FErr, visited) + return + } + // At this point, we might call tconv2 recursively. Add the current type to the visited list so we don't // try to print it recursively. // We record the offset in the result buffer where the type's text starts. This offset serves as a reference @@ -794,12 +830,6 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited visited[t] = b.Len() defer delete(visited, t) - if mode == FDbg { - b.WriteString(t.Etype.String()) - b.WriteByte('-') - tconv2(b, t, flag, FErr, visited) - return - } switch t.Etype { case TPTR: b.WriteByte('*') @@ -1322,7 +1352,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { n.Orig.exprfmt(s, prec, mode) return } - if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != types.Idealbool && n.Type != types.Idealstring { + if n.Type != nil && !n.Type.IsUntyped() { // Need parens when type begins with what might // be misinterpreted as a unary operator: * or <-. if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) { @@ -1407,7 +1437,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { return } if n.Right != nil { - mode.Fprintf(s, "%v literal", n.Right) + mode.Fprintf(s, "%v{%s}", n.Right, ellipsisIf(n.List.Len() != 0)) return } @@ -1421,7 +1451,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT: if mode == FErr { - mode.Fprintf(s, "%v literal", n.Type) + mode.Fprintf(s, "%v{%s}", n.Type, ellipsisIf(n.List.Len() != 0)) return } mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List) @@ -1698,6 +1728,9 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) { } } + if n.Op == OCLOSURE && n.Func.Closure != nil && n.Func.Closure.Func.Nname.Sym != nil { + mode.Fprintf(s, " fnName %v", n.Func.Closure.Func.Nname.Sym) + } if n.Sym != nil && n.Op != ONAME { mode.Fprintf(s, " %v", n.Sym) } @@ -1713,6 +1746,16 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) { if n.Right != nil { mode.Fprintf(s, "%v", n.Right) } + if n.Func != nil && n.Func.Closure != nil && n.Func.Closure.Nbody.Len() != 0 { + indent(s) + // The function associated with a closure + mode.Fprintf(s, "%v-clofunc%v", n.Op, n.Func.Closure) + } + if n.Func != nil && n.Func.Dcl != nil && len(n.Func.Dcl) != 0 { + indent(s) + // The dcls for a func or closure + mode.Fprintf(s, "%v-dcl%v", n.Op, asNodes(n.Func.Dcl)) + } if n.List.Len() != 0 { indent(s) mode.Fprintf(s, "%v-list%v", n.Op, n.List) @@ -1934,3 +1977,10 @@ func indent(s fmt.State) { fmt.Fprint(s, ". ") } } + +func ellipsisIf(b bool) string { + if b { + return "..." + } + return "" +} diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index 9079ce2afc..274930bd15 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -61,12 +61,12 @@ type Class uint8 //go:generate stringer -type=Class const ( Pxxx Class = iota // no class; used during ssa conversion to indicate pseudo-variables - PEXTERN // global variable + PEXTERN // global variables PAUTO // local variables - PAUTOHEAP // local variable or parameter moved to heap + PAUTOHEAP // local variables or parameters moved to heap PPARAM // input arguments PPARAMOUT // output results - PFUNC // global function + PFUNC // global functions // Careful: Class is stored in three bits in Node.flags. _ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3) @@ -116,7 +116,15 @@ var decldepth int32 var nolocalimports bool -var Debug [256]int +// gc debug flags +type DebugFlags struct { + P, B, C, E, + K, L, N, S, + W, e, h, j, + l, m, r, w int +} + +var Debug DebugFlags var debugstr string @@ -259,7 +267,6 @@ type Arch struct { REGSP int MAXWIDTH int64 - Use387 bool // should 386 backend use 387 FP instructions instead of sse2. SoftFloat bool PadFrame func(int64) int64 @@ -302,6 +309,7 @@ var ( growslice, msanread, msanwrite, + msanmove, newobject, newproc, panicdivide, @@ -328,10 +336,6 @@ var ( BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym - // GO386=387 - ControlWord64trunc, - ControlWord32 *obj.LSym - // Wasm WasmMove, WasmZero, diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index 480d411f49..d599a383e7 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -70,12 +70,8 @@ func newProgs(fn *Node, worker int) *Progs { pp.pos = fn.Pos pp.settext(fn) // PCDATA tables implicitly start with index -1. - pp.prevLive = LivenessIndex{-1, -1, false} - if go115ReduceLiveness { - pp.nextLive = pp.prevLive - } else { - pp.nextLive = LivenessInvalid - } + pp.prevLive = LivenessIndex{-1, false} + pp.nextLive = pp.prevLive return pp } @@ -120,31 +116,15 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog { Addrconst(&p.From, objabi.PCDATA_StackMapIndex) Addrconst(&p.To, int64(idx)) } - if !go115ReduceLiveness { + if pp.nextLive.isUnsafePoint != pp.prevLive.isUnsafePoint { + // Emit unsafe-point marker. + pp.prevLive.isUnsafePoint = pp.nextLive.isUnsafePoint + p := pp.Prog(obj.APCDATA) + Addrconst(&p.From, objabi.PCDATA_UnsafePoint) if pp.nextLive.isUnsafePoint { - // Unsafe points are encoded as a special value in the - // register map. - pp.nextLive.regMapIndex = objabi.PCDATA_RegMapUnsafe - } - if pp.nextLive.regMapIndex != pp.prevLive.regMapIndex { - // Emit register map index change. - idx := pp.nextLive.regMapIndex - pp.prevLive.regMapIndex = idx - p := pp.Prog(obj.APCDATA) - Addrconst(&p.From, objabi.PCDATA_RegMapIndex) - Addrconst(&p.To, int64(idx)) - } - } else { - if pp.nextLive.isUnsafePoint != pp.prevLive.isUnsafePoint { - // Emit unsafe-point marker. - pp.prevLive.isUnsafePoint = pp.nextLive.isUnsafePoint - p := pp.Prog(obj.APCDATA) - Addrconst(&p.From, objabi.PCDATA_UnsafePoint) - if pp.nextLive.isUnsafePoint { - Addrconst(&p.To, objabi.PCDATA_UnsafePointUnsafe) - } else { - Addrconst(&p.To, objabi.PCDATA_UnsafePointSafe) - } + Addrconst(&p.To, objabi.PCDATA_UnsafePointUnsafe) + } else { + Addrconst(&p.To, objabi.PCDATA_UnsafePointSafe) } } @@ -153,7 +133,7 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog { pp.clearp(pp.next) p.Link = pp.next - if !pp.pos.IsKnown() && Debug['K'] != 0 { + if !pp.pos.IsKnown() && Debug.K != 0 { Warn("prog: unknown position (line 0)") } @@ -199,7 +179,7 @@ func (pp *Progs) settext(fn *Node) { ptxt := pp.Prog(obj.ATEXT) pp.Text = ptxt - fn.Func.lsym.Func.Text = ptxt + fn.Func.lsym.Func().Text = ptxt ptxt.From.Type = obj.TYPE_MEM ptxt.From.Name = obj.NAME_EXTERN ptxt.From.Sym = fn.Func.lsym @@ -322,6 +302,12 @@ func ggloblnod(nam *Node) { if nam.Name.LibfuzzerExtraCounter() { s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER } + if nam.Sym.Linkname != "" { + // Make sure linkname'd symbol is non-package. When a symbol is + // both imported and linkname'd, s.Pkg may not set to "_" in + // types.Sym.Linksym because LSym already exists. Set it here. + s.Pkg = "_" + } } func ggloblsym(s *obj.LSym, width int32, flags int16) { diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go index b3f50b63af..1f53d8ca7d 100644 --- a/src/cmd/compile/internal/gc/iexport.go +++ b/src/cmd/compile/internal/gc/iexport.go @@ -751,11 +751,11 @@ func (w *exportWriter) param(f *types.Field) { func constTypeOf(typ *types.Type) Ctype { switch typ { - case types.Idealint, types.Idealrune: + case types.UntypedInt, types.UntypedRune: return CTINT - case types.Idealfloat: + case types.UntypedFloat: return CTFLT - case types.Idealcomplex: + case types.UntypedComplex: return CTCPLX } @@ -780,8 +780,8 @@ func constTypeOf(typ *types.Type) Ctype { } func (w *exportWriter) value(typ *types.Type, v Val) { - if typ.IsUntyped() { - typ = untype(v.Ctype()) + if vt := idealType(v.Ctype()); typ.IsUntyped() && typ != vt { + Fatalf("exporter: untyped type mismatch, have: %v, want: %v", typ, vt) } w.typ(typ) @@ -1017,6 +1017,8 @@ func (w *exportWriter) symIdx(s *types.Sym) { } func (w *exportWriter) typeExt(t *types.Type) { + // Export whether this type is marked notinheap. + w.bool(t.NotInHeap()) // For type T, export the index of type descriptor symbols of T and *T. if i, ok := typeSymIdx[t]; ok { w.int64(i[0]) @@ -1136,13 +1138,10 @@ func (w *exportWriter) stmt(n *Node) { w.pos(n.Pos) w.stmtList(n.Ninit) w.exprsOrNil(n.Left, nil) - w.stmtList(n.List) + w.caseList(n) - case OCASE: - w.op(OCASE) - w.pos(n.Pos) - w.stmtList(n.List) - w.stmtList(n.Nbody) + // case OCASE: + // handled by caseList case OFALL: w.op(OFALL) @@ -1166,6 +1165,24 @@ func (w *exportWriter) stmt(n *Node) { } } +func (w *exportWriter) caseList(sw *Node) { + namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil + + cases := sw.List.Slice() + w.uint64(uint64(len(cases))) + for _, cas := range cases { + if cas.Op != OCASE { + Fatalf("expected OCASE, got %v", cas) + } + w.pos(cas.Pos) + w.stmtList(cas.List) + if namedTypeSwitch { + w.localName(cas.Rlist.First()) + } + w.stmtList(cas.Nbody) + } +} + func (w *exportWriter) exprList(list Nodes) { for _, n := range list.Slice() { w.expr(n) @@ -1230,6 +1247,19 @@ func (w *exportWriter) expr(n *Node) { w.op(OTYPE) w.typ(n.Type) + case OTYPESW: + w.op(OTYPESW) + w.pos(n.Pos) + var s *types.Sym + if n.Left != nil { + if n.Left.Op != ONONAME { + Fatalf("expected ONONAME, got %v", n.Left) + } + s = n.Left.Sym + } + w.localIdent(s, 0) // declared pseudo-variable, if any + w.exprsOrNil(n.Right, nil) + // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: // should have been resolved by typechecking - handled by default case @@ -1264,8 +1294,13 @@ func (w *exportWriter) expr(n *Node) { // case OSTRUCTKEY: // unreachable - handled in case OSTRUCTLIT by elemList - // case OCALLPART: - // unimplemented - handled by default case + case OCALLPART: + // An OCALLPART is an OXDOT before type checking. + w.op(OXDOT) + w.pos(n.Pos) + w.expr(n.Left) + // Right node should be ONAME + w.selector(n.Right.Sym) case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH: w.op(OXDOT) diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 4169222c14..c0114d0e53 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -375,7 +375,7 @@ func (p *importReader) value() (typ *types.Type, v Val) { v.U = p.string() case CTINT: x := new(Mpint) - x.Rune = typ == types.Idealrune + x.Rune = typ == types.UntypedRune p.mpint(&x.Val, typ) v.U = x case CTFLT: @@ -596,7 +596,6 @@ func (r *importReader) typ1() *types.Type { // Ensure we expand the interface in the frontend (#25055). checkwidth(t) - return t } } @@ -711,6 +710,7 @@ func (r *importReader) symIdx(s *types.Sym) { } func (r *importReader) typeExt(t *types.Type) { + t.SetNotInHeap(r.bool()) i, pi := r.int64(), r.int64() if i != -1 && pi != -1 { typeSymIdx[t] = [2]int64{i, pi} @@ -742,8 +742,8 @@ func (r *importReader) doInline(n *Node) { importlist = append(importlist, n) - if Debug['E'] > 0 && Debug['m'] > 2 { - if Debug['m'] > 3 { + if Debug.E > 0 && Debug.m > 2 { + if Debug.m > 3 { fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body)) } else { fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body)) @@ -784,6 +784,28 @@ func (r *importReader) stmtList() []*Node { return list } +func (r *importReader) caseList(sw *Node) []*Node { + namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil + + cases := make([]*Node, r.uint64()) + for i := range cases { + cas := nodl(r.pos(), OCASE, nil, nil) + cas.List.Set(r.stmtList()) + if namedTypeSwitch { + // Note: per-case variables will have distinct, dotted + // names after import. That's okay: swt.go only needs + // Sym for diagnostics anyway. + caseVar := newnamel(cas.Pos, r.ident()) + declare(caseVar, dclcontext) + cas.Rlist.Set1(caseVar) + caseVar.Name.Defn = sw.Left + } + cas.Nbody.Set(r.stmtList()) + cases[i] = cas + } + return cases +} + func (r *importReader) exprList() []*Node { var list []*Node for { @@ -831,6 +853,14 @@ func (r *importReader) node() *Node { case OTYPE: return typenod(r.typ()) + case OTYPESW: + n := nodl(r.pos(), OTYPESW, nil, nil) + if s := r.ident(); s != nil { + n.Left = npos(n.Pos, newnoname(s)) + } + n.Right, _ = r.exprsOrNil() + return n + // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: // unreachable - should have been resolved by typechecking @@ -866,7 +896,7 @@ func (r *importReader) node() *Node { // unreachable - handled in case OSTRUCTLIT by elemList // case OCALLPART: - // unimplemented + // unreachable - mapped to case OXDOT below by exporter // case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH: // unreachable - mapped to case OXDOT below by exporter @@ -1025,16 +1055,11 @@ func (r *importReader) node() *Node { n := nodl(r.pos(), op, nil, nil) n.Ninit.Set(r.stmtList()) n.Left, _ = r.exprsOrNil() - n.List.Set(r.stmtList()) + n.List.Set(r.caseList(n)) return n - case OCASE: - n := nodl(r.pos(), OCASE, nil, nil) - n.List.Set(r.exprList()) - // TODO(gri) eventually we must declare variables for type switch - // statements (type switch statements are not yet exported) - n.Nbody.Set(r.stmtList()) - return n + // case OCASE: + // handled by caseList case OFALL: n := nodl(r.pos(), OFALL, nil, nil) diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go index 94cbcf9846..ec9cc4bddc 100644 --- a/src/cmd/compile/internal/gc/init.go +++ b/src/cmd/compile/internal/gc/init.go @@ -59,7 +59,7 @@ func fninit(n []*Node) { Curfn = fn typecheckslice(nf, ctxStmt) Curfn = nil - funccompile(fn) + xtop = append(xtop, fn) fns = append(fns, initializers.Linksym()) } if dummyInitFn.Func.Dcl != nil { @@ -68,16 +68,14 @@ func fninit(n []*Node) { // something's weird if we get here. Fatalf("dummyInitFn still has declarations") } + dummyInitFn = nil // Record user init functions. for i := 0; i < renameinitgen; i++ { s := lookupN("init.", i) fn := asNode(s.Def).Name.Defn // Skip init functions with empty bodies. - // noder.go doesn't allow external init functions, and - // order.go has already removed any OEMPTY nodes, so - // checking Len() == 0 is sufficient here. - if fn.Nbody.Len() == 0 { + if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == OEMPTY { continue } fns = append(fns, s.Linksym()) diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index fa5b3ec698..419056985f 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -7,7 +7,7 @@ // saves a copy of the body. Then inlcalls walks each function body to // expand calls to inlinable functions. // -// The debug['l'] flag controls the aggressiveness. Note that main() swaps level 0 and 1, +// The Debug.l flag controls the aggressiveness. Note that main() swaps level 0 and 1, // making 1 the default and -l disable. Additional levels (beyond -l) may be buggy and // are not supported. // 0: disabled @@ -21,7 +21,7 @@ // The -d typcheckinl flag enables early typechecking of all imported bodies, // which is useful to flush out bugs. // -// The debug['m'] flag enables diagnostic output. a single -m is useful for verifying +// The Debug.m flag enables diagnostic output. a single -m is useful for verifying // which calls get inlined or not, more is for debugging, and may go away at any point. package gc @@ -85,7 +85,7 @@ func typecheckinl(fn *Node) { return // typecheckinl on local function } - if Debug['m'] > 2 || Debug_export != 0 { + if Debug.m > 2 || Debug_export != 0 { fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body)) } @@ -94,10 +94,11 @@ func typecheckinl(fn *Node) { typecheckslice(fn.Func.Inl.Body, ctxStmt) Curfn = savefn - // During typechecking, declarations are added to - // Curfn.Func.Dcl. Move them to Inl.Dcl for consistency with - // how local functions behave. (Append because typecheckinl - // may be called multiple times.) + // During expandInline (which imports fn.Func.Inl.Body), + // declarations are added to fn.Func.Dcl by funcHdr(). Move them + // to fn.Func.Inl.Dcl for consistency with how local functions + // behave. (Append because typecheckinl may be called multiple + // times.) fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...) fn.Func.Dcl = nil @@ -116,10 +117,10 @@ func caninl(fn *Node) { } var reason string // reason, if any, that the function was not inlined - if Debug['m'] > 1 || logopt.Enabled() { + if Debug.m > 1 || logopt.Enabled() { defer func() { if reason != "" { - if Debug['m'] > 1 { + if Debug.m > 1 { fmt.Printf("%v: cannot inline %v: %s\n", fn.Line(), fn.Func.Nname, reason) } if logopt.Enabled() { @@ -187,7 +188,7 @@ func caninl(fn *Node) { defer n.Func.SetInlinabilityChecked(true) cc := int32(inlineExtraCallCost) - if Debug['l'] == 4 { + if Debug.l == 4 { cc = 1 // this appears to yield better performance than 0. } @@ -224,9 +225,9 @@ func caninl(fn *Node) { // this is so export can find the body of a method fn.Type.FuncType().Nname = asTypesNode(n) - if Debug['m'] > 1 { + if Debug.m > 1 { fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", fn.Line(), n, inlineMaxBudget-visitor.budget, fn.Type, asNodes(n.Func.Inl.Body)) - } else if Debug['m'] != 0 { + } else if Debug.m != 0 { fmt.Printf("%v: can inline %v\n", fn.Line(), n) } if logopt.Enabled() { @@ -257,21 +258,39 @@ func inlFlood(n *Node) { typecheckinl(n) + // Recursively identify all referenced functions for + // reexport. We want to include even non-called functions, + // because after inlining they might be callable. inspectList(asNodes(n.Func.Inl.Body), func(n *Node) bool { switch n.Op { case ONAME: - // Mark any referenced global variables or - // functions for reexport. Skip methods, - // because they're reexported alongside their - // receiver type. - if n.Class() == PEXTERN || n.Class() == PFUNC && !n.isMethodExpression() { + switch n.Class() { + case PFUNC: + if n.isMethodExpression() { + inlFlood(asNode(n.Type.Nname())) + } else { + inlFlood(n) + exportsym(n) + } + case PEXTERN: exportsym(n) } - case OCALLFUNC, OCALLMETH: - // Recursively flood any functions called by - // this one. - inlFlood(asNode(n.Left.Type.Nname())) + case ODOTMETH: + fn := asNode(n.Type.Nname()) + inlFlood(fn) + + case OCALLPART: + // Okay, because we don't yet inline indirect + // calls to method values. + case OCLOSURE: + // If the closure is inlinable, we'll need to + // flood it too. But today we don't support + // inlining functions that contain closures. + // + // When we do, we'll probably want: + // inlFlood(n.Func.Closure.Func.Nname) + Fatalf("unexpected closure in inlinable function") } return true }) @@ -325,18 +344,10 @@ func (v *hairyVisitor) visit(n *Node) bool { break } - if fn := n.Left.Func; fn != nil && fn.Inl != nil { - v.budget -= fn.Inl.Cost + if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil { + v.budget -= fn.Func.Inl.Cost break } - if n.Left.isMethodExpression() { - if d := asNode(n.Left.Sym.Def); d != nil && d.Func.Inl != nil { - v.budget -= d.Func.Inl.Cost - break - } - } - // TODO(mdempsky): Budget for OCLOSURE calls if we - // ever allow that. See #15561 and #23093. // Call cost for non-leaf inlining. v.budget -= v.extraCallCost @@ -383,16 +394,11 @@ func (v *hairyVisitor) visit(n *Node) bool { return true case OCLOSURE, - OCALLPART, ORANGE, - OFOR, - OFORUNTIL, OSELECT, - OTYPESW, OGO, ODEFER, ODCLTYPE, // can't print yet - OBREAK, ORETJMP: v.reason = "unhandled op " + n.Op.String() return true @@ -400,10 +406,23 @@ func (v *hairyVisitor) visit(n *Node) bool { case OAPPEND: v.budget -= inlineExtraAppendCost - case ODCLCONST, OEMPTY, OFALL, OLABEL: + case ODCLCONST, OEMPTY, OFALL: // These nodes don't produce code; omit from inlining budget. return false + case OLABEL: + // TODO(mdempsky): Add support for inlining labeled control statements. + if n.labeledControl() != nil { + v.reason = "labeled control" + return true + } + + case OBREAK, OCONTINUE: + if n.Sym != nil { + // Should have short-circuited due to labeledControl above. + Fatalf("unexpected labeled break/continue: %v", n) + } + case OIF: if Isconst(n.Left, CTBOOL) { // This if and the condition cost nothing. @@ -421,7 +440,7 @@ func (v *hairyVisitor) visit(n *Node) bool { v.budget-- // When debugging, don't stop early, to get full cost of inlining this function - if v.budget < 0 && Debug['m'] < 2 && !logopt.Enabled() { + if v.budget < 0 && Debug.m < 2 && !logopt.Enabled() { return true } @@ -430,9 +449,9 @@ func (v *hairyVisitor) visit(n *Node) bool { v.visitList(n.Ninit) || v.visitList(n.Nbody) } -// Inlcopy and inlcopylist recursively copy the body of a function. -// Any name-like node of non-local class is marked for re-export by adding it to -// the exportlist. +// inlcopylist (together with inlcopy) recursively copies a list of nodes, except +// that it keeps the same ONAME, OTYPE, and OLITERAL nodes. It is used for copying +// the body and dcls of an inlineable function. func inlcopylist(ll []*Node) []*Node { s := make([]*Node, 0, len(ll)) for _, n := range ll { @@ -452,7 +471,7 @@ func inlcopy(n *Node) *Node { } m := n.copy() - if m.Func != nil { + if n.Op != OCALLPART && m.Func != nil { Fatalf("unexpected Func: %v", m) } m.Left = inlcopy(n.Left) @@ -570,13 +589,11 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node { } switch n.Op { - // inhibit inlining of their argument case ODEFER, OGO: switch n.Left.Op { case OCALLFUNC, OCALLMETH: n.Left.SetNoInline(true) } - return n // TODO do them here (or earlier), // so escape analysis can avoid more heapmoves. @@ -666,60 +683,18 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node { switch n.Op { case OCALLFUNC: - if Debug['m'] > 3 { + if Debug.m > 3 { fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left) } - if n.Left.Func != nil && n.Left.Func.Inl != nil && !isIntrinsicCall(n) { // normal case - n = mkinlcall(n, n.Left, maxCost, inlMap) - } else if n.Left.isMethodExpression() && asNode(n.Left.Sym.Def) != nil { - n = mkinlcall(n, asNode(n.Left.Sym.Def), maxCost, inlMap) - } else if n.Left.Op == OCLOSURE { - if f := inlinableClosure(n.Left); f != nil { - n = mkinlcall(n, f, maxCost, inlMap) - } - } else if n.Left.Op == ONAME && n.Left.Name != nil && n.Left.Name.Defn != nil { - if d := n.Left.Name.Defn; d.Op == OAS && d.Right.Op == OCLOSURE { - if f := inlinableClosure(d.Right); f != nil { - // NB: this check is necessary to prevent indirect re-assignment of the variable - // having the address taken after the invocation or only used for reads is actually fine - // but we have no easy way to distinguish the safe cases - if d.Left.Name.Addrtaken() { - if Debug['m'] > 1 { - fmt.Printf("%v: cannot inline escaping closure variable %v\n", n.Line(), n.Left) - } - if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(), - fmt.Sprintf("%v cannot be inlined (escaping closure variable)", n.Left)) - } - break - } - - // ensure the variable is never re-assigned - if unsafe, a := reassigned(n.Left); unsafe { - if Debug['m'] > 1 { - if a != nil { - fmt.Printf("%v: cannot inline re-assigned closure variable at %v: %v\n", n.Line(), a.Line(), a) - if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(), - fmt.Sprintf("%v cannot be inlined (re-assigned closure variable)", a)) - } - } else { - fmt.Printf("%v: cannot inline global closure variable %v\n", n.Line(), n.Left) - if logopt.Enabled() { - logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(), - fmt.Sprintf("%v cannot be inlined (global closure variable)", n.Left)) - } - } - } - break - } - n = mkinlcall(n, f, maxCost, inlMap) - } - } + if isIntrinsicCall(n) { + break + } + if fn := inlCallee(n.Left); fn != nil && fn.Func.Inl != nil { + n = mkinlcall(n, fn, maxCost, inlMap) } case OCALLMETH: - if Debug['m'] > 3 { + if Debug.m > 3 { fmt.Printf("%v:call to meth %L\n", n.Line(), n.Left.Right) } @@ -739,16 +714,85 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node { return n } -// inlinableClosure takes an OCLOSURE node and follows linkage to the matching ONAME with -// the inlinable body. Returns nil if the function is not inlinable. -func inlinableClosure(n *Node) *Node { - c := n.Func.Closure - caninl(c) - f := c.Func.Nname - if f == nil || f.Func.Inl == nil { +// inlCallee takes a function-typed expression and returns the underlying function ONAME +// that it refers to if statically known. Otherwise, it returns nil. +func inlCallee(fn *Node) *Node { + fn = staticValue(fn) + switch { + case fn.Op == ONAME && fn.Class() == PFUNC: + if fn.isMethodExpression() { + n := asNode(fn.Type.Nname()) + // Check that receiver type matches fn.Left. + // TODO(mdempsky): Handle implicit dereference + // of pointer receiver argument? + if n == nil || !types.Identical(n.Type.Recv().Type, fn.Left.Type) { + return nil + } + return n + } + return fn + case fn.Op == OCLOSURE: + c := fn.Func.Closure + caninl(c) + return c.Func.Nname + } + return nil +} + +func staticValue(n *Node) *Node { + for { + if n.Op == OCONVNOP { + n = n.Left + continue + } + + n1 := staticValue1(n) + if n1 == nil { + return n + } + n = n1 + } +} + +// staticValue1 implements a simple SSA-like optimization. If n is a local variable +// that is initialized and never reassigned, staticValue1 returns the initializer +// expression. Otherwise, it returns nil. +func staticValue1(n *Node) *Node { + if n.Op != ONAME || n.Class() != PAUTO || n.Name.Addrtaken() { + return nil + } + + defn := n.Name.Defn + if defn == nil { + return nil + } + + var rhs *Node +FindRHS: + switch defn.Op { + case OAS: + rhs = defn.Right + case OAS2: + for i, lhs := range defn.List.Slice() { + if lhs == n { + rhs = defn.Rlist.Index(i) + break FindRHS + } + } + Fatalf("%v missing from LHS of %v", n, defn) + default: return nil } - return f + if rhs == nil { + Fatalf("RHS is nil: %v", defn) + } + + unsafe, _ := reassigned(n) + if unsafe { + return nil + } + + return rhs } // reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean @@ -792,14 +836,12 @@ func (v *reassignVisitor) visit(n *Node) *Node { if n.Left == v.name && n != v.name.Name.Defn { return n } - return nil case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE: for _, p := range n.List.Slice() { if p == v.name && n != v.name.Name.Defn { return n } } - return nil } if a := v.visit(n.Left); a != nil { return a @@ -831,24 +873,27 @@ func (v *reassignVisitor) visitList(l Nodes) *Node { return nil } -func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node { - if n := asNode(t.Nname); n != nil && !n.isBlank() { - inlvar := inlvars[n] - if inlvar == nil { - Fatalf("missing inlvar for %v\n", n) - } - return inlvar +func inlParam(t *types.Field, as *Node, inlvars map[*Node]*Node) *Node { + n := asNode(t.Nname) + if n == nil || n.isBlank() { + return nblank } - return typecheck(nblank, ctxExpr|ctxAssign) + inlvar := inlvars[n] + if inlvar == nil { + Fatalf("missing inlvar for %v", n) + } + as.Ninit.Append(nod(ODCL, inlvar, nil)) + inlvar.Name.Defn = as + return inlvar } var inlgen int -// If n is a call, and fn is a function with an inlinable body, -// return an OINLCALL. -// On return ninit has the parameter assignments, the nbody is the -// inlined function body and list, rlist contain the input, output +// If n is a call node (OCALLFUNC or OCALLMETH), and fn is an ONAME node for a +// function with an inlinable body, return an OINLCALL node that can replace n. +// The returned node's Ninit has the parameter assignments, the Nbody is the +// inlined function body, and (List, Rlist) contain the (input, output) // parameters. // The result of mkinlcall MUST be assigned back to n, e.g. // n.Left = mkinlcall(n.Left, fn, isddd) @@ -889,7 +934,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { } if inlMap[fn] { - if Debug['m'] > 1 { + if Debug.m > 1 { fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", n.Line(), fn, Curfn.funcname()) } return n @@ -903,12 +948,12 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { } // We have a function node, and it has an inlineable body. - if Debug['m'] > 1 { + if Debug.m > 1 { fmt.Printf("%v: inlining call to %v %#v { %#v }\n", n.Line(), fn.Sym, fn.Type, asNodes(fn.Func.Inl.Body)) - } else if Debug['m'] != 0 { + } else if Debug.m != 0 { fmt.Printf("%v: inlining call to %v\n", n.Line(), fn) } - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n) } @@ -918,6 +963,21 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { ninit := n.Ninit + // For normal function calls, the function callee expression + // may contain side effects (e.g., added by addinit during + // inlconv2expr or inlconv2list). Make sure to preserve these, + // if necessary (#42703). + if n.Op == OCALLFUNC { + callee := n.Left + for callee.Op == OCONVNOP { + ninit.AppendNodes(&callee.Ninit) + callee = callee.Left + } + if callee.Op != ONAME && callee.Op != OCLOSURE { + Fatalf("unexpected callee expression: %v", callee) + } + } + // Make temp names to use instead of the originals. inlvars := make(map[*Node]*Node) @@ -970,14 +1030,15 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { continue } if ln.isParamStackCopy() { // ignore the on-stack copy of a parameter that moved to the heap - continue - } - inlvars[ln] = typecheck(inlvar(ln), ctxExpr) - if ln.Class() == PPARAM || ln.Name.Param.Stackcopy != nil && ln.Name.Param.Stackcopy.Class() == PPARAM { - ninit.Append(nod(ODCL, inlvars[ln], nil)) + // TODO(mdempsky): Remove once I'm confident + // this never actually happens. We currently + // perform inlining before escape analysis, so + // nothing should have moved to the heap yet. + Fatalf("impossible: %v", ln) } + inlf := typecheck(inlvar(ln), ctxExpr) + inlvars[ln] = inlf if genDwarfInline > 0 { - inlf := inlvars[ln] if ln.Class() == PPARAM { inlf.Name.SetInlFormal(true) } else { @@ -988,15 +1049,28 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { } } + nreturns := 0 + inspectList(asNodes(fn.Func.Inl.Body), func(n *Node) bool { + if n != nil && n.Op == ORETURN { + nreturns++ + } + return true + }) + + // We can delay declaring+initializing result parameters if: + // (1) there's only one "return" statement in the inlined + // function, and (2) the result parameters aren't named. + delayretvars := nreturns == 1 + // temporaries for return values. var retvars []*Node for i, t := range fn.Type.Results().Fields().Slice() { var m *Node - mpos := t.Pos - if n := asNode(t.Nname); n != nil && !n.isBlank() { + if n := asNode(t.Nname); n != nil && !n.isBlank() && !strings.HasPrefix(n.Sym.Name, "~r") { m = inlvar(n) m = typecheck(m, ctxExpr) inlvars[n] = m + delayretvars = false // found a named result parameter } else { // anonymous return values, synthesize names for use in assignment that replaces return m = retvar(t, i) @@ -1008,67 +1082,52 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { // were not part of the original callee. if !strings.HasPrefix(m.Sym.Name, "~R") { m.Name.SetInlFormal(true) - m.Pos = mpos + m.Pos = t.Pos inlfvars = append(inlfvars, m) } } - ninit.Append(nod(ODCL, m, nil)) retvars = append(retvars, m) } // Assign arguments to the parameters' temp names. as := nod(OAS2, nil, nil) - as.Rlist.Set(n.List.Slice()) + as.SetColas(true) + if n.Op == OCALLMETH { + if n.Left.Left == nil { + Fatalf("method call without receiver: %+v", n) + } + as.Rlist.Append(n.Left.Left) + } + as.Rlist.Append(n.List.Slice()...) // For non-dotted calls to variadic functions, we assign the // variadic parameter's temp name separately. var vas *Node - if fn.IsMethod() { - rcv := fn.Type.Recv() - - if n.Left.Op == ODOTMETH { - // For x.M(...), assign x directly to the - // receiver parameter. - if n.Left.Left == nil { - Fatalf("method call without receiver: %+v", n) - } - ras := nod(OAS, tinlvar(rcv, inlvars), n.Left.Left) - ras = typecheck(ras, ctxStmt) - ninit.Append(ras) - } else { - // For T.M(...), add the receiver parameter to - // as.List, so it's assigned by the normal - // arguments. - if as.Rlist.Len() == 0 { - Fatalf("non-method call to method without first arg: %+v", n) - } - as.List.Append(tinlvar(rcv, inlvars)) - } + if recv := fn.Type.Recv(); recv != nil { + as.List.Append(inlParam(recv, as, inlvars)) } - for _, param := range fn.Type.Params().Fields().Slice() { // For ordinary parameters or variadic parameters in // dotted calls, just add the variable to the // assignment list, and we're done. if !param.IsDDD() || n.IsDDD() { - as.List.Append(tinlvar(param, inlvars)) + as.List.Append(inlParam(param, as, inlvars)) continue } // Otherwise, we need to collect the remaining values // to pass as a slice. - numvals := n.List.Len() - x := as.List.Len() - for as.List.Len() < numvals { + for as.List.Len() < as.Rlist.Len() { as.List.Append(argvar(param.Type, as.List.Len())) } varargs := as.List.Slice()[x:] - vas = nod(OAS, tinlvar(param, inlvars), nil) + vas = nod(OAS, nil, nil) + vas.Left = inlParam(param, vas, inlvars) if len(varargs) == 0 { vas.Right = nodnil() vas.Right.Type = param.Type @@ -1088,11 +1147,14 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { ninit.Append(vas) } - // Zero the return parameters. - for _, n := range retvars { - ras := nod(OAS, n, nil) - ras = typecheck(ras, ctxStmt) - ninit.Append(ras) + if !delayretvars { + // Zero the return parameters. + for _, n := range retvars { + ninit.Append(nod(ODCL, n, nil)) + ras := nod(OAS, n, nil) + ras = typecheck(ras, ctxStmt) + ninit.Append(ras) + } } retlabel := autolabel(".i") @@ -1123,11 +1185,12 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { } subst := inlsubst{ - retlabel: retlabel, - retvars: retvars, - inlvars: inlvars, - bases: make(map[*src.PosBase]*src.PosBase), - newInlIndex: newIndex, + retlabel: retlabel, + retvars: retvars, + delayretvars: delayretvars, + inlvars: inlvars, + bases: make(map[*src.PosBase]*src.PosBase), + newInlIndex: newIndex, } body := subst.list(asNodes(fn.Func.Inl.Body)) @@ -1165,7 +1228,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { } } - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call) } @@ -1176,7 +1239,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node { // PAUTO's in the calling functions, and link them off of the // PPARAM's, PAUTOS and PPARAMOUTs of the called function. func inlvar(var_ *Node) *Node { - if Debug['m'] > 3 { + if Debug.m > 3 { fmt.Printf("inlvar %+v\n", var_) } @@ -1223,6 +1286,10 @@ type inlsubst struct { // Temporary result variables. retvars []*Node + // Whether result variables should be initialized at the + // "return" statement. + delayretvars bool + inlvars map[*Node]*Node // bases maps from original PosBase to PosBase with an extra @@ -1255,13 +1322,13 @@ func (subst *inlsubst) node(n *Node) *Node { switch n.Op { case ONAME: if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("substituting name %+v -> %+v\n", n, inlvar) } return inlvar } - if Debug['m'] > 2 { + if Debug.m > 2 { fmt.Printf("not substituting name %+v\n", n) } return n @@ -1291,6 +1358,14 @@ func (subst *inlsubst) node(n *Node) *Node { as.List.Append(n) } as.Rlist.Set(subst.list(n.List)) + + if subst.delayretvars { + for _, n := range as.List.Slice() { + as.Ninit.Append(nod(ODCL, n, nil)) + n.Name.Defn = as + } + } + as = typecheck(as, ctxStmt) m.Ninit.Append(as) } @@ -1353,3 +1428,68 @@ func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node { } return s } + +// devirtualize replaces interface method calls within fn with direct +// concrete-type method calls where applicable. +func devirtualize(fn *Node) { + Curfn = fn + inspectList(fn.Nbody, func(n *Node) bool { + if n.Op == OCALLINTER { + devirtualizeCall(n) + } + return true + }) +} + +func devirtualizeCall(call *Node) { + recv := staticValue(call.Left.Left) + if recv.Op != OCONVIFACE { + return + } + + typ := recv.Left.Type + if typ.IsInterface() { + return + } + + x := nodl(call.Left.Pos, ODOTTYPE, call.Left.Left, nil) + x.Type = typ + x = nodlSym(call.Left.Pos, OXDOT, x, call.Left.Sym) + x = typecheck(x, ctxExpr|ctxCallee) + switch x.Op { + case ODOTMETH: + if Debug.m != 0 { + Warnl(call.Pos, "devirtualizing %v to %v", call.Left, typ) + } + call.Op = OCALLMETH + call.Left = x + case ODOTINTER: + // Promoted method from embedded interface-typed field (#42279). + if Debug.m != 0 { + Warnl(call.Pos, "partially devirtualizing %v to %v", call.Left, typ) + } + call.Op = OCALLINTER + call.Left = x + default: + // TODO(mdempsky): Turn back into Fatalf after more testing. + if Debug.m != 0 { + Warnl(call.Pos, "failed to devirtualize %v (%v)", x, x.Op) + } + return + } + + // Duplicated logic from typecheck for function call return + // value types. + // + // Receiver parameter size may have changed; need to update + // call.Type to get correct stack offsets for result + // parameters. + checkwidth(x.Type) + switch ft := x.Type; ft.NumResults() { + case 0: + case 1: + call.Type = ft.Results().Field(0).Type + default: + call.Type = ft.Results() + } +} diff --git a/src/cmd/compile/internal/gc/inl_test.go b/src/cmd/compile/internal/gc/inl_test.go index 9d3b8c59fd..02735e50fb 100644 --- a/src/cmd/compile/internal/gc/inl_test.go +++ b/src/cmd/compile/internal/gc/inl_test.go @@ -51,6 +51,7 @@ func TestIntendedInlining(t *testing.T) { "funcPC", "getArgInfoFast", "getm", + "getMCache", "isDirectIface", "itabHashFunc", "noescape", @@ -83,7 +84,7 @@ func TestIntendedInlining(t *testing.T) { "puintptr.ptr", "spanOf", "spanOfUnchecked", - //"(*gcWork).putFast", // TODO(austin): For debugging #27993 + "(*gcWork).putFast", "(*gcWork).tryGetFast", "(*guintptr).set", "(*markBits).advance", @@ -115,6 +116,7 @@ func TestIntendedInlining(t *testing.T) { "byLiteral.Len", "byLiteral.Less", "byLiteral.Swap", + "(*dictDecoder).tryWriteCopy", }, "encoding/base64": { "assemble32", diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go index 1a344c6566..7cce371408 100644 --- a/src/cmd/compile/internal/gc/lex.go +++ b/src/cmd/compile/internal/gc/lex.go @@ -48,8 +48,11 @@ const ( Nowritebarrierrec // error on write barrier in this or recursive callees Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees - // Runtime-only type pragmas + // Runtime and cgo type pragmas NotInHeap // values of this type must not be heap allocated + + // Go command pragmas + GoBuildPragma ) const ( @@ -71,6 +74,8 @@ const ( func pragmaFlag(verb string) PragmaFlag { switch verb { + case "go:build": + return GoBuildPragma case "go:nointerface": if objabi.Fieldtrack_enabled != 0 { return Nointerface diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index eedfc4bb25..a6963a3d66 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -34,8 +34,6 @@ import ( "strings" ) -var imported_unsafe bool - var ( buildid string spectre string @@ -48,6 +46,7 @@ var ( Debug_closure int Debug_compilelater int debug_dclstack int + Debug_dumpptrs int Debug_libfuzzer int Debug_panic int Debug_slice int @@ -77,6 +76,7 @@ var debugtab = []struct { {"compilelater", "compile functions as late as possible", &Debug_compilelater}, {"disablenil", "disable nil checks", &disable_checknil}, {"dclstack", "run internal dclstack check", &debug_dclstack}, + {"dumpptrs", "show Node pointer values in Dump/dumplist output", &Debug_dumpptrs}, {"gcprog", "print dump of GC programs", &Debug_gcprog}, {"libfuzzer", "coverage instrumentation for libfuzzer", &Debug_libfuzzer}, {"nil", "print information about nil checks", &Debug_checknil}, @@ -91,6 +91,7 @@ var debugtab = []struct { {"dwarfinl", "print information about DWARF inlined function creation", &Debug_gendwarfinl}, {"softfloat", "force compiler to emit soft-float code", &Debug_softfloat}, {"defer", "print information about defer compilation", &Debug_defer}, + {"fieldtrack", "enable fieldtracking", &objabi.Fieldtrack_enabled}, } const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>] @@ -132,7 +133,7 @@ func hidePanic() { // supportsDynlink reports whether or not the code generator for the given // architecture supports the -shared and -dynlink flags. func supportsDynlink(arch *sys.Arch) bool { - return arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.S390X) + return arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X) } // timing data for compiler phases @@ -211,18 +212,27 @@ func Main(archInit func(*Arch)) { flag.BoolVar(&compiling_runtime, "+", false, "compiling runtime") flag.BoolVar(&compiling_std, "std", false, "compiling standard library") - objabi.Flagcount("%", "debug non-static initializers", &Debug['%']) - objabi.Flagcount("B", "disable bounds checking", &Debug['B']) - objabi.Flagcount("C", "disable printing of columns in error messages", &Debug['C']) // TODO(gri) remove eventually flag.StringVar(&localimport, "D", "", "set relative `path` for local imports") - objabi.Flagcount("E", "debug symbol export", &Debug['E']) + + objabi.Flagcount("%", "debug non-static initializers", &Debug.P) + objabi.Flagcount("B", "disable bounds checking", &Debug.B) + objabi.Flagcount("C", "disable printing of columns in error messages", &Debug.C) + objabi.Flagcount("E", "debug symbol export", &Debug.E) + objabi.Flagcount("K", "debug missing line numbers", &Debug.K) + objabi.Flagcount("L", "show full file names in error messages", &Debug.L) + objabi.Flagcount("N", "disable optimizations", &Debug.N) + objabi.Flagcount("S", "print assembly listing", &Debug.S) + objabi.Flagcount("W", "debug parse tree after type checking", &Debug.W) + objabi.Flagcount("e", "no limit on number of errors reported", &Debug.e) + objabi.Flagcount("h", "halt on error", &Debug.h) + objabi.Flagcount("j", "debug runtime-initialized variables", &Debug.j) + objabi.Flagcount("l", "disable inlining", &Debug.l) + objabi.Flagcount("m", "print optimization decisions", &Debug.m) + objabi.Flagcount("r", "debug generated wrappers", &Debug.r) + objabi.Flagcount("w", "debug type checking", &Debug.w) + objabi.Flagfn1("I", "add `directory` to import search path", addidir) - objabi.Flagcount("K", "debug missing line numbers", &Debug['K']) - objabi.Flagcount("L", "show full file names in error messages", &Debug['L']) - objabi.Flagcount("N", "disable optimizations", &Debug['N']) - objabi.Flagcount("S", "print assembly listing", &Debug['S']) objabi.AddVersionFlag() // -V - objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W']) flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`") flag.StringVar(&buildid, "buildid", "", "record `id` as the build id in the export metadata") flag.IntVar(&nBackendWorkers, "c", 1, "concurrency during compilation, 1 means no concurrency") @@ -231,17 +241,13 @@ func Main(archInit func(*Arch)) { flag.BoolVar(&flagDWARF, "dwarf", !Wasm, "generate DWARF symbols") flag.BoolVar(&Ctxt.Flag_locationlists, "dwarflocationlists", true, "add location lists to DWARF in optimized mode") flag.IntVar(&genDwarfInline, "gendwarfinl", 2, "generate DWARF inline info records") - objabi.Flagcount("e", "no limit on number of errors reported", &Debug['e']) - objabi.Flagcount("h", "halt on error", &Debug['h']) + objabi.Flagfn1("embedcfg", "read go:embed configuration from `file`", readEmbedCfg) objabi.Flagfn1("importmap", "add `definition` of the form source=actual to import map", addImportMap) objabi.Flagfn1("importcfg", "read import configuration from `file`", readImportCfg) flag.StringVar(&flag_installsuffix, "installsuffix", "", "set pkg directory `suffix`") - objabi.Flagcount("j", "debug runtime-initialized variables", &Debug['j']) - objabi.Flagcount("l", "disable inlining", &Debug['l']) flag.StringVar(&flag_lang, "lang", "", "release to compile for") flag.StringVar(&linkobj, "linkobj", "", "write linker-specific object to `file`") objabi.Flagcount("live", "debug liveness analysis", &debuglive) - objabi.Flagcount("m", "print optimization decisions", &Debug['m']) if sys.MSanSupported(objabi.GOOS, objabi.GOARCH) { flag.BoolVar(&flag_msan, "msan", false, "build code compatible with C/C++ memory sanitizer") } @@ -249,7 +255,6 @@ func Main(archInit func(*Arch)) { flag.StringVar(&outfile, "o", "", "write output to `file`") flag.StringVar(&myimportpath, "p", "", "set expected package import `path`") flag.BoolVar(&writearchive, "pack", false, "write to file.a instead of file.o") - objabi.Flagcount("r", "debug generated wrappers", &Debug['r']) if sys.RaceDetectorSupported(objabi.GOOS, objabi.GOARCH) { flag.BoolVar(&flag_race, "race", false, "enable race detector") } @@ -259,7 +264,6 @@ func Main(archInit func(*Arch)) { } flag.StringVar(&pathPrefix, "trimpath", "", "remove `prefix` from recorded source file paths") flag.BoolVar(&Debug_vlog, "v", false, "increase debug verbosity") - objabi.Flagcount("w", "debug type checking", &Debug['w']) flag.BoolVar(&use_writebarrier, "wb", true, "enable write barrier") var flag_shared bool var flag_dynlink bool @@ -325,9 +329,9 @@ func Main(archInit func(*Arch)) { Ctxt.Flag_shared = flag_dynlink || flag_shared Ctxt.Flag_dynlink = flag_dynlink - Ctxt.Flag_optimize = Debug['N'] == 0 + Ctxt.Flag_optimize = Debug.N == 0 - Ctxt.Debugasm = Debug['S'] + Ctxt.Debugasm = Debug.S Ctxt.Debugvlog = Debug_vlog if flagDWARF { Ctxt.DebugInfo = debuginfo @@ -399,7 +403,7 @@ func Main(archInit func(*Arch)) { instrumenting = true } - if compiling_runtime && Debug['N'] != 0 { + if compiling_runtime && Debug.N != 0 { log.Fatal("cannot disable optimizations while compiling runtime") } if nBackendWorkers < 1 { @@ -504,11 +508,11 @@ func Main(archInit func(*Arch)) { } // enable inlining. for now: - // default: inlining on. (debug['l'] == 1) - // -l: inlining off (debug['l'] == 0) - // -l=2, -l=3: inlining on again, with extra debugging (debug['l'] > 1) - if Debug['l'] <= 1 { - Debug['l'] = 1 - Debug['l'] + // default: inlining on. (Debug.l == 1) + // -l: inlining off (Debug.l == 0) + // -l=2, -l=3: inlining on again, with extra debugging (Debug.l > 1) + if Debug.l <= 1 { + Debug.l = 1 - Debug.l } if jsonLogOpt != "" { // parse version,destination from json logging optimization. @@ -516,6 +520,7 @@ func Main(archInit func(*Arch)) { } ssaDump = os.Getenv("GOSSAFUNC") + ssaDir = os.Getenv("GOSSADIR") if ssaDump != "" { if strings.HasSuffix(ssaDump, "+") { ssaDump = ssaDump[:len(ssaDump)-1] @@ -594,7 +599,7 @@ func Main(archInit func(*Arch)) { timings.Start("fe", "typecheck", "top1") for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias) { + if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias()) { xtop[i] = typecheck(n, ctxStmt) } } @@ -606,7 +611,7 @@ func Main(archInit func(*Arch)) { timings.Start("fe", "typecheck", "top2") for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias { + if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias() { xtop[i] = typecheck(n, ctxStmt) } } @@ -617,7 +622,7 @@ func Main(archInit func(*Arch)) { var fcount int64 for i := 0; i < len(xtop); i++ { n := xtop[i] - if op := n.Op; op == ODCLFUNC || op == OCLOSURE { + if n.Op == ODCLFUNC { Curfn = n decldepth = 1 saveerrors() @@ -642,6 +647,8 @@ func Main(archInit func(*Arch)) { errorexit() } + fninit(xtop) + // Phase 4: Decide how to capture closed variables. // This needs to run before escape analysis, // because variables captured by value do not escape. @@ -663,7 +670,7 @@ func Main(archInit func(*Arch)) { // Phase 5: Inlining timings.Start("fe", "inlining") if Debug_typecheckinl != 0 { - // Typecheck imported function bodies if debug['l'] > 1, + // Typecheck imported function bodies if Debug.l > 1, // otherwise lazily when used or re-exported. for _, n := range importlist { if n.Func.Inl != nil { @@ -677,7 +684,7 @@ func Main(archInit func(*Arch)) { } } - if Debug['l'] != 0 { + if Debug.l != 0 { // Find functions that can be inlined and clone them before walk expands them. visitBottomUp(xtop, func(list []*Node, recursive bool) { numfns := numNonClosures(list) @@ -688,7 +695,7 @@ func Main(archInit func(*Arch)) { // across more than one function. caninl(n) } else { - if Debug['m'] > 1 { + if Debug.m > 1 { fmt.Printf("%v: cannot inline %v: recursive\n", n.Line(), n.Func.Nname) } } @@ -697,6 +704,13 @@ func Main(archInit func(*Arch)) { }) } + for _, n := range xtop { + if n.Op == ODCLFUNC { + devirtualize(n) + } + } + Curfn = nil + // Phase 6: Escape analysis. // Required for moving heap allocations onto stack, // which in turn is required by the closure implementation, @@ -751,10 +765,6 @@ func Main(archInit func(*Arch)) { } timings.AddEvent(fcount, "funcs") - if nsavederrors+nerrors == 0 { - fninit(xtop) - } - compileFunctions() if nowritebarrierrecCheck != nil { @@ -809,6 +819,9 @@ func Main(archInit func(*Arch)) { } } + if len(funcStack) != 0 { + Fatalf("funcStack is non-empty: %v", len(funcStack)) + } if len(compilequeue) != 0 { Fatalf("%d uncompiled functions", len(compilequeue)) } @@ -966,9 +979,10 @@ func readSymABIs(file, myimportpath string) { if len(parts) != 3 { log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0]) } - sym, abi := parts[1], parts[2] - if abi != "ABI0" { // Only supported external ABI right now - log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abi) + sym, abistr := parts[1], parts[2] + abi, valid := obj.ParseABI(abistr) + if !valid { + log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abistr) } // If the symbol is already prefixed with @@ -981,9 +995,9 @@ func readSymABIs(file, myimportpath string) { // Record for later. if parts[0] == "def" { - symabiDefs[sym] = obj.ABI0 + symabiDefs[sym] = abi } else { - symabiRefs[sym] = obj.ABI0 + symabiRefs[sym] = abi } default: log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0]) @@ -1172,7 +1186,6 @@ func importfile(f *Val) *types.Pkg { } if path_ == "unsafe" { - imported_unsafe = true return unsafepkg } @@ -1405,29 +1418,34 @@ func IsAlias(sym *types.Sym) bool { return sym.Def != nil && asNode(sym.Def).Sym != sym } -// By default, assume any debug flags are incompatible with concurrent compilation. -// A few are safe and potentially in common use for normal compiles, though; mark them as such here. -var concurrentFlagOK = [256]bool{ - 'B': true, // disabled bounds checking - 'C': true, // disable printing of columns in error messages - 'e': true, // no limit on errors; errors all come from non-concurrent code - 'I': true, // add `directory` to import search path - 'N': true, // disable optimizations - 'l': true, // disable inlining - 'w': true, // all printing happens before compilation - 'W': true, // all printing happens before compilation - 'S': true, // printing disassembly happens at the end (but see concurrentBackendAllowed below) +// By default, assume any debug flags are incompatible with concurrent +// compilation. A few are safe and potentially in common use for +// normal compiles, though; return true for those. +func concurrentFlagOk() bool { + // Report whether any debug flag that would prevent concurrent + // compilation is set, by zeroing out the allowed ones and then + // checking if the resulting struct is zero. + d := Debug + d.B = 0 // disable bounds checking + d.C = 0 // disable printing of columns in error messages + d.e = 0 // no limit on errors; errors all come from non-concurrent code + d.N = 0 // disable optimizations + d.l = 0 // disable inlining + d.w = 0 // all printing happens before compilation + d.W = 0 // all printing happens before compilation + d.S = 0 // printing disassembly happens at the end (but see concurrentBackendAllowed below) + + return d == DebugFlags{} } func concurrentBackendAllowed() bool { - for i, x := range &Debug { - if x != 0 && !concurrentFlagOK[i] { - return false - } + if !concurrentFlagOk() { + return false } - // Debug['S'] by itself is ok, because all printing occurs + + // Debug.S by itself is ok, because all printing occurs // while writing the object file, and that is non-concurrent. - // Adding Debug_vlog, however, causes Debug['S'] to also print + // Adding Debug_vlog, however, causes Debug.S to also print // while flushing the plist, which happens concurrently. if Debug_vlog || debugstr != "" || debuglive > 0 { return false diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 5dce533e4b..67d24ef0bc 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -11,6 +11,7 @@ import ( "runtime" "strconv" "strings" + "unicode" "unicode/utf8" "cmd/compile/internal/syntax" @@ -90,7 +91,11 @@ func (p *noder) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase { } else { // line directive base p0 := b0.Pos() - p1 := src.MakePos(p.makeSrcPosBase(p0.Base()), p0.Line(), p0.Col()) + p0b := p0.Base() + if p0b == b0 { + panic("infinite recursion in makeSrcPosBase") + } + p1 := src.MakePos(p.makeSrcPosBase(p0b), p0.Line(), p0.Col()) b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col()) } p.basemap[b0] = b1 @@ -130,11 +135,13 @@ type noder struct { base *src.PosBase } - file *syntax.File - linknames []linkname - pragcgobuf [][]string - err chan syntax.Error - scope ScopeID + file *syntax.File + linknames []linkname + pragcgobuf [][]string + err chan syntax.Error + scope ScopeID + importedUnsafe bool + importedEmbed bool // scopeVars is a stack tracking the number of variables declared in the // current function at the moment each open scope was opened. @@ -236,19 +243,21 @@ type linkname struct { func (p *noder) node() { types.Block = 1 - imported_unsafe = false + p.importedUnsafe = false + p.importedEmbed = false p.setlineno(p.file.PkgName) mkpackage(p.file.PkgName.Value) if pragma, ok := p.file.Pragma.(*Pragma); ok { + pragma.Flag &^= GoBuildPragma p.checkUnused(pragma) } xtop = append(xtop, p.decls(p.file.DeclList)...) for _, n := range p.linknames { - if !imported_unsafe { + if !p.importedUnsafe { p.yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"") continue } @@ -323,7 +332,6 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) { val := p.basicLit(imp.Path) ipkg := importfile(&val) - if ipkg == nil { if nerrors == 0 { Fatalf("phase error in import") @@ -331,6 +339,13 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) { return } + if ipkg == unsafepkg { + p.importedUnsafe = true + } + if ipkg.Path == "embed" { + p.importedEmbed = true + } + ipkg.Direct = true var my *types.Sym @@ -372,6 +387,20 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []*Node { } if pragma, ok := decl.Pragma.(*Pragma); ok { + if len(pragma.Embeds) > 0 { + if !p.importedEmbed { + // This check can't be done when building the list pragma.Embeds + // because that list is created before the noder starts walking over the file, + // so at that point it hasn't seen the imports. + // We're left to check now, just before applying the //go:embed lines. + for _, e := range pragma.Embeds { + p.yyerrorpos(e.Pos, "//go:embed only allowed in Go files that import \"embed\"") + } + } else { + exprs = varEmbed(p, names, typ, exprs, pragma.Embeds) + } + pragma.Embeds = nil + } p.checkUnused(pragma) } @@ -454,17 +483,17 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node { param := n.Name.Param param.Ntype = typ - param.Alias = decl.Alias + param.SetAlias(decl.Alias) if pragma, ok := decl.Pragma.(*Pragma); ok { if !decl.Alias { - param.Pragma = pragma.Flag & TypePragmas + param.SetPragma(pragma.Flag & TypePragmas) pragma.Flag &^= TypePragmas } p.checkUnused(pragma) } nod := p.nod(decl, ODCLTYPE, n, nil) - if param.Alias && !langSupported(1, 9, localpkg) { + if param.Alias() && !langSupported(1, 9, localpkg) { yyerrorl(nod.Pos, "type aliases only supported as of -lang=go1.9") } return nod @@ -773,7 +802,7 @@ func (p *noder) sum(x syntax.Expr) *Node { n := p.expr(x) if Isconst(n, CTSTR) && n.Sym == nil { nstr = n - chunks = append(chunks, strlit(nstr)) + chunks = append(chunks, nstr.StringVal()) } for i := len(adds) - 1; i >= 0; i-- { @@ -783,12 +812,12 @@ func (p *noder) sum(x syntax.Expr) *Node { if Isconst(r, CTSTR) && r.Sym == nil { if nstr != nil { // Collapse r into nstr instead of adding to n. - chunks = append(chunks, strlit(r)) + chunks = append(chunks, r.StringVal()) continue } nstr = r - chunks = append(chunks, strlit(nstr)) + chunks = append(chunks, nstr.StringVal()) } else { if len(chunks) > 1 { nstr.SetVal(Val{U: strings.Join(chunks, "")}) @@ -1437,11 +1466,6 @@ func (p *noder) mkname(name *syntax.Name) *Node { return mkname(p.name(name)) } -func (p *noder) newname(name *syntax.Name) *Node { - // TODO(mdempsky): Set line number? - return newname(p.name(name)) -} - func (p *noder) wrapname(n syntax.Node, x *Node) *Node { // These nodes do not carry line numbers. // Introduce a wrapper node to give them the correct line. @@ -1497,13 +1521,15 @@ var allowedStdPragmas = map[string]bool{ "go:cgo_import_dynamic": true, "go:cgo_ldflag": true, "go:cgo_dynamic_linker": true, + "go:embed": true, "go:generate": true, } // *Pragma is the value stored in a syntax.Pragma during parsing. type Pragma struct { - Flag PragmaFlag // collected bits - Pos []PragmaPos // position of each individual flag + Flag PragmaFlag // collected bits + Pos []PragmaPos // position of each individual flag + Embeds []PragmaEmbed } type PragmaPos struct { @@ -1511,12 +1537,22 @@ type PragmaPos struct { Pos syntax.Pos } +type PragmaEmbed struct { + Pos syntax.Pos + Patterns []string +} + func (p *noder) checkUnused(pragma *Pragma) { for _, pos := range pragma.Pos { if pos.Flag&pragma.Flag != 0 { p.yyerrorpos(pos.Pos, "misplaced compiler directive") } } + if len(pragma.Embeds) > 0 { + for _, e := range pragma.Embeds { + p.yyerrorpos(e.Pos, "misplaced go:embed directive") + } + } } func (p *noder) checkUnusedDuringParse(pragma *Pragma) { @@ -1525,6 +1561,11 @@ func (p *noder) checkUnusedDuringParse(pragma *Pragma) { p.error(syntax.Error{Pos: pos.Pos, Msg: "misplaced compiler directive"}) } } + if len(pragma.Embeds) > 0 { + for _, e := range pragma.Embeds { + p.error(syntax.Error{Pos: e.Pos, Msg: "misplaced go:embed directive"}) + } + } } // pragma is called concurrently if files are parsed concurrently. @@ -1569,6 +1610,17 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P } p.linknames = append(p.linknames, linkname{pos, f[1], target}) + case text == "go:embed", strings.HasPrefix(text, "go:embed "): + args, err := parseGoEmbed(text[len("go:embed"):]) + if err != nil { + p.error(syntax.Error{Pos: pos, Msg: err.Error()}) + } + if len(args) == 0 { + p.error(syntax.Error{Pos: pos, Msg: "usage: //go:embed pattern..."}) + break + } + pragma.Embeds = append(pragma.Embeds, PragmaEmbed{pos, args}) + case strings.HasPrefix(text, "go:cgo_import_dynamic "): // This is permitted for general use because Solaris // code relies on it in golang.org/x/sys/unix and others. @@ -1641,3 +1693,64 @@ func mkname(sym *types.Sym) *Node { } return n } + +// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns. +// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings. +// go/build/read.go also processes these strings and contains similar logic. +func parseGoEmbed(args string) ([]string, error) { + var list []string + for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) { + var path string + Switch: + switch args[0] { + default: + i := len(args) + for j, c := range args { + if unicode.IsSpace(c) { + i = j + break + } + } + path = args[:i] + args = args[i:] + + case '`': + i := strings.Index(args[1:], "`") + if i < 0 { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + path = args[1 : 1+i] + args = args[1+i+1:] + + case '"': + i := 1 + for ; i < len(args); i++ { + if args[i] == '\\' { + i++ + continue + } + if args[i] == '"' { + q, err := strconv.Unquote(args[:i+1]) + if err != nil { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1]) + } + path = q + args = args[i+1:] + break Switch + } + } + if i >= len(args) { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + } + + if args != "" { + r, _ := utf8.DecodeRuneInString(args) + if !unicode.IsSpace(r) { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + } + list = append(list, path) + } + return list, nil +} diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index af5037c5a8..32aa7c5bb1 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -14,6 +14,8 @@ import ( "encoding/json" "fmt" "io" + "io/ioutil" + "os" "sort" "strconv" ) @@ -113,14 +115,19 @@ func dumpCompilerObj(bout *bio.Writer) { func dumpdata() { externs := len(externdcl) + xtops := len(xtop) dumpglobls() addptabs() + exportlistLen := len(exportlist) addsignats(externdcl) dumpsignats() dumptabs() + ptabsLen := len(ptabs) + itabsLen := len(itabs) dumpimportstrings() dumpbasictypes() + dumpembeds() // Calls to dumpsignats can generate functions, // like method wrappers and hash and equality routines. @@ -129,9 +136,19 @@ func dumpdata() { // number of types in a finite amount of code. // In the typical case, we loop 0 or 1 times. // It was not until issue 24761 that we found any code that required a loop at all. - for len(compilequeue) > 0 { + for { + for i := xtops; i < len(xtop); i++ { + n := xtop[i] + if n.Op == ODCLFUNC { + funccompile(n) + } + } + xtops = len(xtop) compileFunctions() dumpsignats() + if xtops == len(xtop) { + break + } } // Dump extra globals. @@ -149,6 +166,16 @@ func dumpdata() { } addGCLocals() + + if exportlistLen != len(exportlist) { + Fatalf("exportlist changed after compile functions loop") + } + if ptabsLen != len(ptabs) { + Fatalf("ptabs changed after compile functions loop") + } + if itabsLen != len(itabs) { + Fatalf("itabs changed after compile functions loop") + } } func dumpLinkerObj(bout *bio.Writer) { @@ -248,7 +275,7 @@ func dumpGlobalConst(n *Node) { default: return } - Ctxt.DwarfIntConst(myimportpath, n.Sym.Name, typesymname(t), n.Int64()) + Ctxt.DwarfIntConst(myimportpath, n.Sym.Name, typesymname(t), n.Int64Val()) } func dumpglobls() { @@ -281,20 +308,21 @@ func dumpglobls() { // global symbols can't be declared during parallel compilation. func addGCLocals() { for _, s := range Ctxt.Text { - if s.Func == nil { + fn := s.Func() + if fn == nil { continue } - for _, gcsym := range []*obj.LSym{s.Func.GCArgs, s.Func.GCLocals, s.Func.GCRegs} { + for _, gcsym := range []*obj.LSym{fn.GCArgs, fn.GCLocals} { if gcsym != nil && !gcsym.OnList() { ggloblsym(gcsym, int32(len(gcsym.P)), obj.RODATA|obj.DUPOK) } } - if x := s.Func.StackObjects; x != nil { + if x := fn.StackObjects; x != nil { attr := int16(obj.RODATA) ggloblsym(x, int32(len(x.P)), attr) x.Set(obj.AttrStatic, true) } - if x := s.Func.OpenCodedDeferInfo; x != nil { + if x := fn.OpenCodedDeferInfo; x != nil { ggloblsym(x, int32(len(x.P)), obj.RODATA|obj.DUPOK) } } @@ -333,28 +361,31 @@ func dbvec(s *obj.LSym, off int, bv bvec) int { return off } +const ( + stringSymPrefix = "go.string." + stringSymPattern = ".gostring.%d.%x" +) + +// stringsym returns a symbol containing the string s. +// The symbol contains the string data, not a string header. func stringsym(pos src.XPos, s string) (data *obj.LSym) { var symname string if len(s) > 100 { // Huge strings are hashed to avoid long names in object files. // Indulge in some paranoia by writing the length of s, too, // as protection against length extension attacks. + // Same pattern is known to fileStringSym below. h := sha256.New() io.WriteString(h, s) - symname = fmt.Sprintf(".gostring.%d.%x", len(s), h.Sum(nil)) + symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil)) } else { // Small strings get named directly by their contents. symname = strconv.Quote(s) } - const prefix = "go.string." - symdataname := prefix + symname - - symdata := Ctxt.Lookup(symdataname) - + symdata := Ctxt.Lookup(stringSymPrefix + symname) if !symdata.OnList() { - // string data - off := dsname(symdata, 0, s, pos, "string") + off := dstringdata(symdata, 0, s, pos, "string") ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL) symdata.Set(obj.AttrContentAddressable, true) } @@ -362,26 +393,122 @@ func stringsym(pos src.XPos, s string) (data *obj.LSym) { return symdata } -var slicebytes_gen int +// fileStringSym returns a symbol for the contents and the size of file. +// If readonly is true, the symbol shares storage with any literal string +// or other file with the same content and is placed in a read-only section. +// If readonly is false, the symbol is a read-write copy separate from any other, +// for use as the backing store of a []byte. +// The content hash of file is copied into hash. (If hash is nil, nothing is copied.) +// The returned symbol contains the data itself, not a string header. +func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.LSym, int64, error) { + f, err := os.Open(file) + if err != nil { + return nil, 0, err + } + defer f.Close() + info, err := f.Stat() + if err != nil { + return nil, 0, err + } + if !info.Mode().IsRegular() { + return nil, 0, fmt.Errorf("not a regular file") + } + size := info.Size() + if size <= 1*1024 { + data, err := ioutil.ReadAll(f) + if err != nil { + return nil, 0, err + } + if int64(len(data)) != size { + return nil, 0, fmt.Errorf("file changed between reads") + } + var sym *obj.LSym + if readonly { + sym = stringsym(pos, string(data)) + } else { + sym = slicedata(pos, string(data)).Sym.Linksym() + } + if len(hash) > 0 { + sum := sha256.Sum256(data) + copy(hash, sum[:]) + } + return sym, size, nil + } + if size > 2e9 { + // ggloblsym takes an int32, + // and probably the rest of the toolchain + // can't handle such big symbols either. + // See golang.org/issue/9862. + return nil, 0, fmt.Errorf("file too large") + } + + // File is too big to read and keep in memory. + // Compute hash if needed for read-only content hashing or if the caller wants it. + var sum []byte + if readonly || len(hash) > 0 { + h := sha256.New() + n, err := io.Copy(h, f) + if err != nil { + return nil, 0, err + } + if n != size { + return nil, 0, fmt.Errorf("file changed between reads") + } + sum = h.Sum(nil) + copy(hash, sum) + } + + var symdata *obj.LSym + if readonly { + symname := fmt.Sprintf(stringSymPattern, size, sum) + symdata = Ctxt.Lookup(stringSymPrefix + symname) + if !symdata.OnList() { + info := symdata.NewFileInfo() + info.Name = file + info.Size = size + ggloblsym(symdata, int32(size), obj.DUPOK|obj.RODATA|obj.LOCAL) + // Note: AttrContentAddressable cannot be set here, + // because the content-addressable-handling code + // does not know about file symbols. + } + } else { + // Emit a zero-length data symbol + // and then fix up length and content to use file. + symdata = slicedata(pos, "").Sym.Linksym() + symdata.Size = size + symdata.Type = objabi.SNOPTRDATA + info := symdata.NewFileInfo() + info.Name = file + info.Size = size + } + + return symdata, size, nil +} + +var slicedataGen int -func slicebytes(nam *Node, s string) { - slicebytes_gen++ - symname := fmt.Sprintf(".gobytes.%d", slicebytes_gen) +func slicedata(pos src.XPos, s string) *Node { + slicedataGen++ + symname := fmt.Sprintf(".gobytes.%d", slicedataGen) sym := localpkg.Lookup(symname) symnode := newname(sym) sym.Def = asTypesNode(symnode) lsym := sym.Linksym() - off := dsname(lsym, 0, s, nam.Pos, "slice") + off := dstringdata(lsym, 0, s, pos, "slice") ggloblsym(lsym, int32(off), obj.NOPTR|obj.LOCAL) + return symnode +} + +func slicebytes(nam *Node, s string) { if nam.Op != ONAME { Fatalf("slicebytes %v", nam) } - slicesym(nam, symnode, int64(len(s))) + slicesym(nam, slicedata(nam.Pos, s), int64(len(s))) } -func dsname(s *obj.LSym, off int, t string, pos src.XPos, what string) int { +func dstringdata(s *obj.LSym, off int, t string, pos src.XPos, what string) int { // Objects that are too large will cause the data section to overflow right away, // causing a cryptic error message by the linker. Check for oversize objects here // and provide a useful error message instead. diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index aa91160e5c..30e1535c09 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -50,7 +50,7 @@ type Order struct { // Order rewrites fn.Nbody to apply the ordering constraints // described in the comment at the top of the file. func order(fn *Node) { - if Debug['W'] > 1 { + if Debug.W > 1 { s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym) dumplist(s, fn.Nbody) } @@ -288,20 +288,13 @@ func (o *Order) popTemp(mark ordermarker) { o.temp = o.temp[:mark] } -// cleanTempNoPop emits VARKILL and if needed VARLIVE instructions -// to *out for each temporary above the mark on the temporary stack. +// cleanTempNoPop emits VARKILL instructions to *out +// for each temporary above the mark on the temporary stack. // It does not pop the temporaries from the stack. func (o *Order) cleanTempNoPop(mark ordermarker) []*Node { var out []*Node for i := len(o.temp) - 1; i >= int(mark); i-- { n := o.temp[i] - if n.Name.Keepalive() { - n.Name.SetKeepalive(false) - n.Name.SetAddrtaken(true) // ensure SSA keeps the n variable - live := nod(OVARLIVE, n, nil) - live = typecheck(live, ctxStmt) - out = append(out, live) - } kill := nod(OVARKILL, n, nil) kill = typecheck(kill, ctxStmt) out = append(out, kill) @@ -330,12 +323,7 @@ func (o *Order) stmtList(l Nodes) { // and rewrites it to: // m = OMAKESLICECOPY([]T, x, s); nil func orderMakeSliceCopy(s []*Node) { - const go115makeslicecopy = true - if !go115makeslicecopy { - return - } - - if Debug['N'] != 0 || instrumenting { + if Debug.N != 0 || instrumenting { return } @@ -500,8 +488,9 @@ func (o *Order) call(n *Node) { // still alive when we pop the temp stack. if arg.Op == OCONVNOP && arg.Left.Type.IsUnsafePtr() { x := o.copyExpr(arg.Left, arg.Left.Type, false) - x.Name.SetKeepalive(true) arg.Left = x + x.Name.SetAddrtaken(true) // ensure SSA keeps the x variable + n.Nbody.Append(typecheck(nod(OVARLIVE, x, nil), ctxStmt)) } } @@ -902,7 +891,7 @@ func (o *Order) stmt(n *Node) { // c is always evaluated; x and ok are only evaluated when assigned. r.Right.Left = o.expr(r.Right.Left, nil) - if r.Right.Left.Op != ONAME { + if !r.Right.Left.IsAutoTmp() { r.Right.Left = o.copyExpr(r.Right.Left, r.Right.Left.Type, false) } @@ -1108,7 +1097,7 @@ func (o *Order) expr(n, lhs *Node) *Node { haslit := false for _, n1 := range n.List.Slice() { hasbyte = hasbyte || n1.Op == OBYTES2STR - haslit = haslit || n1.Op == OLITERAL && len(strlit(n1)) != 0 + haslit = haslit || n1.Op == OLITERAL && len(n1.StringVal()) != 0 } if haslit && hasbyte { @@ -1280,7 +1269,7 @@ func (o *Order) expr(n, lhs *Node) *Node { var t *types.Type switch n.Op { case OSLICELIT: - t = types.NewArray(n.Type.Elem(), n.Right.Int64()) + t = types.NewArray(n.Type.Elem(), n.Right.Int64Val()) case OCALLPART: t = partialCallType(n) } diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 74262595b0..353f4b08c9 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -231,6 +231,11 @@ func compile(fn *Node) { return } + // Set up the function's LSym early to avoid data races with the assemblers. + // Do this before walk, as walk needs the LSym to set attributes/relocations + // (e.g. in markTypeUsedInInterface). + fn.Func.initLSym(true) + walk(fn) if nerrors != 0 { return @@ -250,9 +255,6 @@ func compile(fn *Node) { return } - // Set up the function's LSym early to avoid data races with the assemblers. - fn.Func.initLSym(true) - // Make sure type syms are declared for all types that might // be types of stack objects. We need to do this here // because symbols must be allocated before the parallel @@ -264,8 +266,8 @@ func compile(fn *Node) { dtypesym(n.Type) // Also make sure we allocate a linker symbol // for the stack object data, for the same reason. - if fn.Func.lsym.Func.StackObjects == nil { - fn.Func.lsym.Func.StackObjects = Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj") + if fn.Func.lsym.Func().StackObjects == nil { + fn.Func.lsym.Func().StackObjects = Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj") } } } @@ -413,7 +415,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S case PAUTO: if !n.Name.Used() { // Text == nil -> generating abstract function - if fnsym.Func.Text != nil { + if fnsym.Func().Text != nil { Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)") } continue @@ -423,7 +425,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S continue } apdecls = append(apdecls, n) - fnsym.Func.RecordAutoType(ngotype(n).Linksym()) + fnsym.Func().RecordAutoType(ngotype(n).Linksym()) } decls, dwarfVars := createDwarfVars(fnsym, fn.Func, apdecls) @@ -433,7 +435,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S // the function symbol to insure that the type included in DWARF // processing during linking. typesyms := []*obj.LSym{} - for t, _ := range fnsym.Func.Autot { + for t, _ := range fnsym.Func().Autot { typesyms = append(typesyms, t) } sort.Sort(obj.BySymName(typesyms)) @@ -442,7 +444,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S r.Sym = sym r.Type = objabi.R_USETYPE } - fnsym.Func.Autot = nil + fnsym.Func().Autot = nil var varScopes []ScopeID for _, decl := range decls { @@ -520,7 +522,7 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var { } typename := dwarf.InfoPrefix + typesymname(n.Type) - delete(fnsym.Func.Autot, ngotype(n).Linksym()) + delete(fnsym.Func().Autot, ngotype(n).Linksym()) inlIndex := 0 if genDwarfInline > 1 { if n.Name.InlFormal() || n.Name.InlLocal() { @@ -665,7 +667,7 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, apDecls []*Node) ([]*Node, []*dw ChildIndex: -1, }) // Record go type of to insure that it gets emitted by the linker. - fnsym.Func.RecordAutoType(ngotype(n).Linksym()) + fnsym.Func().RecordAutoType(ngotype(n).Linksym()) } return decls, vars @@ -729,7 +731,7 @@ func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var { } gotype := ngotype(n).Linksym() - delete(fnsym.Func.Autot, gotype) + delete(fnsym.Func().Autot, gotype) typename := dwarf.InfoPrefix + gotype.Name[len("type."):] inlIndex := 0 if genDwarfInline > 1 { diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go index 8976ed657a..a48173e0d6 100644 --- a/src/cmd/compile/internal/gc/plive.go +++ b/src/cmd/compile/internal/gc/plive.go @@ -24,16 +24,6 @@ import ( "strings" ) -// go115ReduceLiveness disables register maps and only produces stack -// maps at call sites. -// -// In Go 1.15, we changed debug call injection to use conservative -// scanning instead of precise pointer maps, so these are no longer -// necessary. -// -// Keep in sync with runtime/preempt.go:go115ReduceLiveness. -const go115ReduceLiveness = true - // OpVarDef is an annotation for the liveness analysis, marking a place // where a complete initialization (definition) of a variable begins. // Since the liveness analysis can see initialization of single-word @@ -96,15 +86,15 @@ type BlockEffects struct { // // uevar: upward exposed variables (used before set in block) // varkill: killed variables (set in block) - uevar varRegVec - varkill varRegVec + uevar bvec + varkill bvec // Computed during Liveness.solve using control flow information: // // livein: variables live at block entry // liveout: variables live at block exit - livein varRegVec - liveout varRegVec + livein bvec + liveout bvec } // A collection of global state used by liveness analysis. @@ -128,16 +118,14 @@ type Liveness struct { // current Block during Liveness.epilogue. Indexed in Value // order for that block. Additionally, for the entry block // livevars[0] is the entry bitmap. Liveness.compact moves - // these to stackMaps and regMaps. - livevars []varRegVec + // these to stackMaps. + livevars []bvec // livenessMap maps from safe points (i.e., CALLs) to their // liveness map indexes. livenessMap LivenessMap stackMapSet bvecSet stackMaps []bvec - regMapSet map[liveRegMask]int - regMaps []liveRegMask cache progeffectscache } @@ -158,7 +146,7 @@ func (m *LivenessMap) reset() { delete(m.vals, k) } } - m.deferreturn = LivenessInvalid + m.deferreturn = LivenessDontCare } func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) { @@ -166,27 +154,17 @@ func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) { } func (m LivenessMap) Get(v *ssa.Value) LivenessIndex { - if !go115ReduceLiveness { - // All safe-points are in the map, so if v isn't in - // the map, it's an unsafe-point. - if idx, ok := m.vals[v.ID]; ok { - return idx - } - return LivenessInvalid - } - // If v isn't in the map, then it's a "don't care" and not an // unsafe-point. if idx, ok := m.vals[v.ID]; ok { return idx } - return LivenessIndex{StackMapDontCare, StackMapDontCare, false} + return LivenessIndex{StackMapDontCare, false} } // LivenessIndex stores the liveness map information for a Value. type LivenessIndex struct { stackMapIndex int - regMapIndex int // only for !go115ReduceLiveness // isUnsafePoint indicates that this is an unsafe-point. // @@ -197,8 +175,10 @@ type LivenessIndex struct { isUnsafePoint bool } -// LivenessInvalid indicates an unsafe point with no stack map. -var LivenessInvalid = LivenessIndex{StackMapDontCare, StackMapDontCare, true} // only for !go115ReduceLiveness +// LivenessDontCare indicates that the liveness information doesn't +// matter. Currently it is used in deferreturn liveness when we don't +// actually need it. It should never be emitted to the PCDATA stream. +var LivenessDontCare = LivenessIndex{StackMapDontCare, true} // StackMapDontCare indicates that the stack map index at a Value // doesn't matter. @@ -212,46 +192,12 @@ func (idx LivenessIndex) StackMapValid() bool { return idx.stackMapIndex != StackMapDontCare } -func (idx LivenessIndex) RegMapValid() bool { - return idx.regMapIndex != StackMapDontCare -} - type progeffectscache struct { retuevar []int32 tailuevar []int32 initialized bool } -// varRegVec contains liveness bitmaps for variables and registers. -type varRegVec struct { - vars bvec - regs liveRegMask -} - -func (v *varRegVec) Eq(v2 varRegVec) bool { - return v.vars.Eq(v2.vars) && v.regs == v2.regs -} - -func (v *varRegVec) Copy(v2 varRegVec) { - v.vars.Copy(v2.vars) - v.regs = v2.regs -} - -func (v *varRegVec) Clear() { - v.vars.Clear() - v.regs = 0 -} - -func (v *varRegVec) Or(v1, v2 varRegVec) { - v.vars.Or(v1.vars, v2.vars) - v.regs = v1.regs | v2.regs -} - -func (v *varRegVec) AndNot(v1, v2 varRegVec) { - v.vars.AndNot(v1.vars, v2.vars) - v.regs = v1.regs &^ v2.regs -} - // livenessShouldTrack reports whether the liveness analysis // should track the variable n. // We don't care about variables that have no pointers, @@ -400,110 +346,6 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) { } } -// regEffects returns the registers affected by v. -func (lv *Liveness) regEffects(v *ssa.Value) (uevar, kill liveRegMask) { - if go115ReduceLiveness { - return 0, 0 - } - if v.Op == ssa.OpPhi { - // All phi node arguments must come from the same - // register and the result must also go to that - // register, so there's no overall effect. - return 0, 0 - } - addLocs := func(mask liveRegMask, v *ssa.Value, ptrOnly bool) liveRegMask { - if int(v.ID) >= len(lv.f.RegAlloc) { - // v has no allocated registers. - return mask - } - loc := lv.f.RegAlloc[v.ID] - if loc == nil { - // v has no allocated registers. - return mask - } - if v.Op == ssa.OpGetG { - // GetG represents the G register, which is a - // pointer, but not a valid GC register. The - // current G is always reachable, so it's okay - // to ignore this register. - return mask - } - - // Collect registers and types from v's location. - var regs [2]*ssa.Register - nreg := 0 - switch loc := loc.(type) { - case ssa.LocalSlot: - return mask - case *ssa.Register: - if ptrOnly && !v.Type.HasPointers() { - return mask - } - regs[0] = loc - nreg = 1 - case ssa.LocPair: - // The value will have TTUPLE type, and the - // children are nil or *ssa.Register. - if v.Type.Etype != types.TTUPLE { - v.Fatalf("location pair %s has non-tuple type %v", loc, v.Type) - } - for i, loc1 := range &loc { - if loc1 == nil { - continue - } - if ptrOnly && !v.Type.FieldType(i).HasPointers() { - continue - } - regs[nreg] = loc1.(*ssa.Register) - nreg++ - } - default: - v.Fatalf("weird RegAlloc location: %s (%T)", loc, loc) - } - - // Add register locations to vars. - for _, reg := range regs[:nreg] { - if reg.GCNum() == -1 { - if ptrOnly { - v.Fatalf("pointer in non-pointer register %v", reg) - } else { - continue - } - } - mask |= 1 << uint(reg.GCNum()) - } - return mask - } - - // v clobbers all registers it writes to (whether or not the - // write is pointer-typed). - kill = addLocs(0, v, false) - for _, arg := range v.Args { - // v uses all registers is reads from, but we only - // care about marking those containing pointers. - uevar = addLocs(uevar, arg, true) - } - return uevar, kill -} - -type liveRegMask uint32 // only if !go115ReduceLiveness - -func (m liveRegMask) niceString(config *ssa.Config) string { - if m == 0 { - return "<none>" - } - str := "" - for i, reg := range config.GCRegMap { - if m&(1<<uint(i)) != 0 { - if str != "" { - str += "," - } - str += reg.String() - } - } - return str -} - type livenessFuncCache struct { be []BlockEffects livenessMap LivenessMap @@ -519,8 +361,6 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt vars: vars, idx: idx, stkptrsize: stkptrsize, - - regMapSet: make(map[liveRegMask]int), } // Significant sources of allocation are kept in the ssa.Cache @@ -533,7 +373,7 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt if cap(lc.be) >= f.NumBlocks() { lv.be = lc.be[:f.NumBlocks()] } - lv.livenessMap = LivenessMap{vals: lc.livenessMap.vals, deferreturn: LivenessInvalid} + lv.livenessMap = LivenessMap{vals: lc.livenessMap.vals, deferreturn: LivenessDontCare} lc.livenessMap.vals = nil } if lv.be == nil { @@ -546,10 +386,10 @@ func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkpt for _, b := range f.Blocks { be := lv.blockEffects(b) - be.uevar = varRegVec{vars: bulk.next()} - be.varkill = varRegVec{vars: bulk.next()} - be.livein = varRegVec{vars: bulk.next()} - be.liveout = varRegVec{vars: bulk.next()} + be.uevar = bulk.next() + be.varkill = bulk.next() + be.livein = bulk.next() + be.liveout = bulk.next() } lv.livenessMap.reset() @@ -637,20 +477,6 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) { } } -// usedRegs returns the maximum width of the live register map. -func (lv *Liveness) usedRegs() int32 { - var any liveRegMask - for _, live := range lv.regMaps { - any |= live - } - i := int32(0) - for any != 0 { - any >>= 1 - i++ - } - return i -} - // Generates live pointer value maps for arguments and local variables. The // this argument and the in arguments are always assumed live. The vars // argument is a slice of *Nodes. @@ -851,31 +677,16 @@ func (lv *Liveness) markUnsafePoints() { // particular, call Values can have a stack map in case the callee // grows the stack, but not themselves be a safe-point. func (lv *Liveness) hasStackMap(v *ssa.Value) bool { - // The runtime only has safe-points in function prologues, so - // we only need stack maps at call sites. go:nosplit functions - // are similar. - if go115ReduceLiveness || compiling_runtime || lv.f.NoSplit { - if !v.Op.IsCall() { - return false - } - // typedmemclr and typedmemmove are write barriers and - // deeply non-preemptible. They are unsafe points and - // hence should not have liveness maps. - if sym, _ := v.Aux.(*obj.LSym); sym == typedmemclr || sym == typedmemmove { - return false - } - return true + if !v.Op.IsCall() { + return false } - - switch v.Op { - case ssa.OpInitMem, ssa.OpArg, ssa.OpSP, ssa.OpSB, - ssa.OpSelect0, ssa.OpSelect1, ssa.OpGetG, - ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive, - ssa.OpPhi: - // These don't produce code (see genssa). + // typedmemclr and typedmemmove are write barriers and + // deeply non-preemptible. They are unsafe points and + // hence should not have liveness maps. + if sym, ok := v.Aux.(*ssa.AuxCall); ok && (sym.Fn == typedmemclr || sym.Fn == typedmemmove) { return false } - return !lv.unsafePoints.Get(int32(v.ID)) + return true } // Initializes the sets for solving the live variables. Visits all the @@ -891,17 +702,13 @@ func (lv *Liveness) prologue() { // effects with the each prog effects. for j := len(b.Values) - 1; j >= 0; j-- { pos, e := lv.valueEffects(b.Values[j]) - regUevar, regKill := lv.regEffects(b.Values[j]) if e&varkill != 0 { - be.varkill.vars.Set(pos) - be.uevar.vars.Unset(pos) + be.varkill.Set(pos) + be.uevar.Unset(pos) } - be.varkill.regs |= regKill - be.uevar.regs &^= regKill if e&uevar != 0 { - be.uevar.vars.Set(pos) + be.uevar.Set(pos) } - be.uevar.regs |= regUevar } } } @@ -911,8 +718,8 @@ func (lv *Liveness) solve() { // These temporary bitvectors exist to avoid successive allocations and // frees within the loop. nvars := int32(len(lv.vars)) - newlivein := varRegVec{vars: bvalloc(nvars)} - newliveout := varRegVec{vars: bvalloc(nvars)} + newlivein := bvalloc(nvars) + newliveout := bvalloc(nvars) // Walk blocks in postorder ordering. This improves convergence. po := lv.f.Postorder() @@ -930,11 +737,11 @@ func (lv *Liveness) solve() { switch b.Kind { case ssa.BlockRet: for _, pos := range lv.cache.retuevar { - newliveout.vars.Set(pos) + newliveout.Set(pos) } case ssa.BlockRetJmp: for _, pos := range lv.cache.tailuevar { - newliveout.vars.Set(pos) + newliveout.Set(pos) } case ssa.BlockExit: // panic exit - nothing to do @@ -969,7 +776,7 @@ func (lv *Liveness) solve() { // variables at each safe point locations. func (lv *Liveness) epilogue() { nvars := int32(len(lv.vars)) - liveout := varRegVec{vars: bvalloc(nvars)} + liveout := bvalloc(nvars) livedefer := bvalloc(nvars) // always-live variables // If there is a defer (that could recover), then all output @@ -1025,12 +832,11 @@ func (lv *Liveness) epilogue() { { // Reserve an entry for function entry. live := bvalloc(nvars) - lv.livevars = append(lv.livevars, varRegVec{vars: live}) + lv.livevars = append(lv.livevars, live) } for _, b := range lv.f.Blocks { be := lv.blockEffects(b) - firstBitmapIndex := len(lv.livevars) // Walk forward through the basic block instructions and // allocate liveness maps for those instructions that need them. @@ -1040,7 +846,7 @@ func (lv *Liveness) epilogue() { } live := bvalloc(nvars) - lv.livevars = append(lv.livevars, varRegVec{vars: live}) + lv.livevars = append(lv.livevars, live) } // walk backward, construct maps at each safe point @@ -1056,21 +862,18 @@ func (lv *Liveness) epilogue() { live := &lv.livevars[index] live.Or(*live, liveout) - live.vars.Or(live.vars, livedefer) // only for non-entry safe points + live.Or(*live, livedefer) // only for non-entry safe points index-- } // Update liveness information. pos, e := lv.valueEffects(v) - regUevar, regKill := lv.regEffects(v) if e&varkill != 0 { - liveout.vars.Unset(pos) + liveout.Unset(pos) } - liveout.regs &^= regKill if e&uevar != 0 { - liveout.vars.Set(pos) + liveout.Set(pos) } - liveout.regs |= regUevar } if b == lv.f.Entry { @@ -1080,7 +883,7 @@ func (lv *Liveness) epilogue() { // Check to make sure only input variables are live. for i, n := range lv.vars { - if !liveout.vars.Get(int32(i)) { + if !liveout.Get(int32(i)) { continue } if n.Class() == PPARAM { @@ -1094,32 +897,16 @@ func (lv *Liveness) epilogue() { live.Or(*live, liveout) } - // Check that no registers are live across calls. - // For closure calls, the CALLclosure is the last use - // of the context register, so it's dead after the call. - index = int32(firstBitmapIndex) - for _, v := range b.Values { - if lv.hasStackMap(v) { - live := lv.livevars[index] - if v.Op.IsCall() && live.regs != 0 { - lv.printDebug() - v.Fatalf("%v register %s recorded as live at call", lv.fn.Func.Nname, live.regs.niceString(lv.f.Config)) - } - index++ - } - } - // The liveness maps for this block are now complete. Compact them. lv.compact(b) } // If we have an open-coded deferreturn call, make a liveness map for it. if lv.fn.Func.OpenCodedDeferDisallowed() { - lv.livenessMap.deferreturn = LivenessInvalid + lv.livenessMap.deferreturn = LivenessDontCare } else { lv.livenessMap.deferreturn = LivenessIndex{ stackMapIndex: lv.stackMapSet.add(livedefer), - regMapIndex: 0, // entry regMap, containing no live registers isUnsafePoint: false, } } @@ -1136,20 +923,10 @@ func (lv *Liveness) epilogue() { lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Func.Nname, n) } } - if !go115ReduceLiveness { - // Check that no registers are live at function entry. - // The context register, if any, comes from a - // LoweredGetClosurePtr operation first thing in the function, - // so it doesn't appear live at entry. - if regs := lv.regMaps[0]; regs != 0 { - lv.printDebug() - lv.f.Fatalf("%v register %s recorded as live on entry", lv.fn.Func.Nname, regs.niceString(lv.f.Config)) - } - } } // Compact coalesces identical bitmaps from lv.livevars into the sets -// lv.stackMapSet and lv.regMaps. +// lv.stackMapSet. // // Compact clears lv.livevars. // @@ -1165,45 +942,23 @@ func (lv *Liveness) epilogue() { // PCDATA tables cost about 100k. So for now we keep using a single index for // both bitmap lists. func (lv *Liveness) compact(b *ssa.Block) { - add := func(live varRegVec, isUnsafePoint bool) LivenessIndex { // only if !go115ReduceLiveness - // Deduplicate the stack map. - stackIndex := lv.stackMapSet.add(live.vars) - // Deduplicate the register map. - regIndex, ok := lv.regMapSet[live.regs] - if !ok { - regIndex = len(lv.regMapSet) - lv.regMapSet[live.regs] = regIndex - lv.regMaps = append(lv.regMaps, live.regs) - } - return LivenessIndex{stackIndex, regIndex, isUnsafePoint} - } pos := 0 if b == lv.f.Entry { // Handle entry stack map. - if !go115ReduceLiveness { - add(lv.livevars[0], false) - } else { - lv.stackMapSet.add(lv.livevars[0].vars) - } + lv.stackMapSet.add(lv.livevars[0]) pos++ } for _, v := range b.Values { - if go115ReduceLiveness { - hasStackMap := lv.hasStackMap(v) - isUnsafePoint := lv.allUnsafe || lv.unsafePoints.Get(int32(v.ID)) - idx := LivenessIndex{StackMapDontCare, StackMapDontCare, isUnsafePoint} - if hasStackMap { - idx.stackMapIndex = lv.stackMapSet.add(lv.livevars[pos].vars) - pos++ - } - if hasStackMap || isUnsafePoint { - lv.livenessMap.set(v, idx) - } - } else if lv.hasStackMap(v) { - isUnsafePoint := lv.allUnsafe || lv.unsafePoints.Get(int32(v.ID)) - lv.livenessMap.set(v, add(lv.livevars[pos], isUnsafePoint)) + hasStackMap := lv.hasStackMap(v) + isUnsafePoint := lv.allUnsafe || lv.unsafePoints.Get(int32(v.ID)) + idx := LivenessIndex{StackMapDontCare, isUnsafePoint} + if hasStackMap { + idx.stackMapIndex = lv.stackMapSet.add(lv.livevars[pos]) pos++ } + if hasStackMap || isUnsafePoint { + lv.livenessMap.set(v, idx) + } } // Reset livevars. @@ -1231,8 +986,8 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) { s := "live at " if v == nil { s += fmt.Sprintf("entry to %s:", lv.fn.funcname()) - } else if sym, ok := v.Aux.(*obj.LSym); ok { - fn := sym.Name + } else if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil { + fn := sym.Fn.Name if pos := strings.Index(fn, "."); pos >= 0 { fn = fn[pos+1:] } @@ -1250,8 +1005,8 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) { Warnl(pos, s) } -func (lv *Liveness) printbvec(printed bool, name string, live varRegVec) bool { - if live.vars.IsEmpty() && live.regs == 0 { +func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool { + if live.IsEmpty() { return printed } @@ -1264,19 +1019,18 @@ func (lv *Liveness) printbvec(printed bool, name string, live varRegVec) bool { comma := "" for i, n := range lv.vars { - if !live.vars.Get(int32(i)) { + if !live.Get(int32(i)) { continue } fmt.Printf("%s%s", comma, n.Sym.Name) comma = "," } - fmt.Printf("%s%s", comma, live.regs.niceString(lv.f.Config)) return true } -// printeffect is like printbvec, but for valueEffects and regEffects. -func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool, regMask liveRegMask) bool { - if !x && regMask == 0 { +// printeffect is like printbvec, but for valueEffects. +func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bool { + if !x { return printed } if !printed { @@ -1288,15 +1042,7 @@ func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool, re if x { fmt.Printf("%s", lv.vars[pos].Sym.Name) } - for j, reg := range lv.f.Config.GCRegMap { - if regMask&(1<<uint(j)) != 0 { - if x { - fmt.Printf(",") - } - x = true - fmt.Printf("%v", reg) - } - } + return true } @@ -1364,15 +1110,14 @@ func (lv *Liveness) printDebug() { pcdata := lv.livenessMap.Get(v) pos, effect := lv.valueEffects(v) - regUevar, regKill := lv.regEffects(v) printed = false - printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0, regUevar) - printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0, regKill) + printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0) + printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0) if printed { fmt.Printf("\n") } - if pcdata.StackMapValid() || pcdata.RegMapValid() { + if pcdata.StackMapValid() { fmt.Printf("\tlive=") printed = false if pcdata.StackMapValid() { @@ -1388,16 +1133,6 @@ func (lv *Liveness) printDebug() { printed = true } } - if pcdata.RegMapValid() { // only if !go115ReduceLiveness - regLive := lv.regMaps[pcdata.regMapIndex] - if regLive != 0 { - if printed { - fmt.Printf(",") - } - fmt.Printf("%s", regLive.niceString(lv.f.Config)) - printed = true - } - } fmt.Printf("\n") } @@ -1423,7 +1158,7 @@ func (lv *Liveness) printDebug() { // first word dumped is the total number of bitmaps. The second word is the // length of the bitmaps. All bitmaps are assumed to be of equal length. The // remaining bytes are the raw bitmaps. -func (lv *Liveness) emit() (argsSym, liveSym, regsSym *obj.LSym) { +func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) { // Size args bitmaps to be just large enough to hold the largest pointer. // First, find the largest Xoffset node we care about. // (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.) @@ -1452,7 +1187,7 @@ func (lv *Liveness) emit() (argsSym, liveSym, regsSym *obj.LSym) { maxLocals := lv.stkptrsize // Temporary symbols for encoding bitmaps. - var argsSymTmp, liveSymTmp, regsSymTmp obj.LSym + var argsSymTmp, liveSymTmp obj.LSym args := bvalloc(int32(maxArgs / int64(Widthptr))) aoff := duint32(&argsSymTmp, 0, uint32(len(lv.stackMaps))) // number of bitmaps @@ -1472,24 +1207,6 @@ func (lv *Liveness) emit() (argsSym, liveSym, regsSym *obj.LSym) { loff = dbvec(&liveSymTmp, loff, locals) } - if !go115ReduceLiveness { - regs := bvalloc(lv.usedRegs()) - roff := duint32(®sSymTmp, 0, uint32(len(lv.regMaps))) // number of bitmaps - roff = duint32(®sSymTmp, roff, uint32(regs.n)) // number of bits in each bitmap - if regs.n > 32 { - // Our uint32 conversion below won't work. - Fatalf("GP registers overflow uint32") - } - - if regs.n > 0 { - for _, live := range lv.regMaps { - regs.Clear() - regs.b[0] = uint32(live) - roff = dbvec(®sSymTmp, roff, regs) - } - } - } - // Give these LSyms content-addressable names, // so that they can be de-duplicated. // This provides significant binary size savings. @@ -1502,11 +1219,7 @@ func (lv *Liveness) emit() (argsSym, liveSym, regsSym *obj.LSym) { lsym.Set(obj.AttrContentAddressable, true) }) } - if !go115ReduceLiveness { - return makeSym(&argsSymTmp), makeSym(&liveSymTmp), makeSym(®sSymTmp) - } - // TODO(go115ReduceLiveness): Remove regsSym result - return makeSym(&argsSymTmp), makeSym(&liveSymTmp), nil + return makeSym(&argsSymTmp), makeSym(&liveSymTmp) } // Entry pointer for liveness analysis. Solves for the liveness of @@ -1552,27 +1265,20 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap { // Emit the live pointer map data structures ls := e.curfn.Func.lsym - ls.Func.GCArgs, ls.Func.GCLocals, ls.Func.GCRegs = lv.emit() + fninfo := ls.Func() + fninfo.GCArgs, fninfo.GCLocals = lv.emit() p := pp.Prog(obj.AFUNCDATA) Addrconst(&p.From, objabi.FUNCDATA_ArgsPointerMaps) p.To.Type = obj.TYPE_MEM p.To.Name = obj.NAME_EXTERN - p.To.Sym = ls.Func.GCArgs + p.To.Sym = fninfo.GCArgs p = pp.Prog(obj.AFUNCDATA) Addrconst(&p.From, objabi.FUNCDATA_LocalsPointerMaps) p.To.Type = obj.TYPE_MEM p.To.Name = obj.NAME_EXTERN - p.To.Sym = ls.Func.GCLocals - - if !go115ReduceLiveness { - p = pp.Prog(obj.AFUNCDATA) - Addrconst(&p.From, objabi.FUNCDATA_RegPointerMaps) - p.To.Type = obj.TYPE_MEM - p.To.Name = obj.NAME_EXTERN - p.To.Sym = ls.Func.GCRegs - } + p.To.Sym = fninfo.GCLocals return lv.livenessMap } diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 5434b0167a..1b4d765d42 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -112,12 +112,13 @@ func typecheckrangeExpr(n *Node) { v2 = nil } - var why string if v1 != nil { if v1.Name != nil && v1.Name.Defn == n { v1.Type = t1 - } else if v1.Type != nil && assignop(t1, v1.Type, &why) == 0 { - yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why) + } else if v1.Type != nil { + if op, why := assignop(t1, v1.Type); op == OXXX { + yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why) + } } checkassign(n, v1) } @@ -125,8 +126,10 @@ func typecheckrangeExpr(n *Node) { if v2 != nil { if v2.Name != nil && v2.Name.Defn == n { v2.Type = t2 - } else if v2.Type != nil && assignop(t2, v2.Type, &why) == 0 { - yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why) + } else if v2.Type != nil { + if op, why := assignop(t2, v2.Type); op == OXXX { + yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why) + } } checkassign(n, v2) } @@ -463,7 +466,7 @@ func walkrange(n *Node) *Node { // // where == for keys of map m is reflexive. func isMapClear(n *Node) bool { - if Debug['N'] != 0 || instrumenting { + if Debug.N != 0 || instrumenting { return false } @@ -530,7 +533,7 @@ func mapClear(m *Node) *Node { // // Parameters are as in walkrange: "for v1, v2 = range a". func arrayClear(n, v1, v2, a *Node) bool { - if Debug['N'] != 0 || instrumenting { + if Debug.N != 0 || instrumenting { return false } diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index 49b2a0ed49..9401eba7a5 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -61,8 +61,9 @@ const ( MAXELEMSIZE = 128 ) -func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{}) -func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{}) +func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{}) +func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{}) +func commonSize() int { return 4*Widthptr + 8 + 8 } // Sizeof(runtime._type{}) func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{}) if t.Sym == nil && len(methods(t)) == 0 { @@ -510,6 +511,7 @@ func dimportpath(p *types.Pkg) { s := Ctxt.Lookup("type..importpath." + p.Prefix + ".") ot := dnameData(s, 0, str, "", nil, false) ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA) + s.Set(obj.AttrContentAddressable, true) p.Pathsym = s } @@ -637,6 +639,7 @@ func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym { } ot := dnameData(s, 0, name, tag, pkg, exported) ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA) + s.Set(obj.AttrContentAddressable, true) return s } @@ -1422,6 +1425,20 @@ func dtypesym(t *types.Type) *obj.LSym { return lsym } +// ifaceMethodOffset returns the offset of the i-th method in the interface +// type descriptor, ityp. +func ifaceMethodOffset(ityp *types.Type, i int64) int64 { + // interface type descriptor layout is struct { + // _type // commonSize + // pkgpath // 1 word + // []imethod // 3 words (pointing to [...]imethod below) + // uncommontype // uncommonSize + // [...]imethod + // } + // The size of imethod is 8. + return int64(commonSize()+4*Widthptr+uncommonSize(ityp)) + i*8 +} + // for each itabEntry, gather the methods on // the concrete type that implement the interface func peekitabs() { @@ -1574,8 +1591,12 @@ func dumptabs() { // typ typeOff // pointer to symbol // } nsym := dname(p.s.Name, "", nil, true) + tsym := dtypesym(p.t) ot = dsymptrOff(s, ot, nsym) - ot = dsymptrOff(s, ot, dtypesym(p.t)) + ot = dsymptrOff(s, ot, tsym) + // Plugin exports symbols as interfaces. Mark their types + // as UsedInIface. + tsym.Set(obj.AttrUsedInIface, true) } ggloblsym(s, int32(ot), int16(obj.RODATA)) diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/gc/scc.go index 60e0a9b8b5..5c7935aa87 100644 --- a/src/cmd/compile/internal/gc/scc.go +++ b/src/cmd/compile/internal/gc/scc.go @@ -75,8 +75,19 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 { inspectList(n.Nbody, func(n *Node) bool { switch n.Op { - case OCALLFUNC, OCALLMETH: - fn := asNode(n.Left.Type.Nname()) + case ONAME: + if n.Class() == PFUNC { + if n.isMethodExpression() { + n = asNode(n.Type.Nname()) + } + if n != nil && n.Name.Defn != nil { + if m := v.visit(n.Name.Defn); m < min { + min = m + } + } + } + case ODOTMETH: + fn := asNode(n.Type.Nname()) if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil { if m := v.visit(fn.Name.Defn); m < min { min = m diff --git a/src/cmd/compile/internal/gc/scope.go b/src/cmd/compile/internal/gc/scope.go index d7239d5693..e66b859e10 100644 --- a/src/cmd/compile/internal/gc/scope.go +++ b/src/cmd/compile/internal/gc/scope.go @@ -62,9 +62,9 @@ func scopePCs(fnsym *obj.LSym, marks []Mark, dwarfScopes []dwarf.Scope) { if len(marks) == 0 { return } - p0 := fnsym.Func.Text + p0 := fnsym.Func().Text scope := findScope(marks, p0.Pos) - for p := fnsym.Func.Text; p != nil; p = p.Link { + for p := p0; p != nil; p = p.Link { if p.Pos == p0.Pos { continue } diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index 71ed558461..212fcc022d 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -39,7 +39,7 @@ func (s *InitSchedule) append(n *Node) { // staticInit adds an initialization statement n to the schedule. func (s *InitSchedule) staticInit(n *Node) { if !s.tryStaticInit(n) { - if Debug['%'] != 0 { + if Debug.P != 0 { Dump("nonstatic", n) } s.append(n) @@ -128,7 +128,7 @@ func (s *InitSchedule) staticcopy(l *Node, r *Node) bool { case OSLICELIT: // copy slice a := s.inittemps[r] - slicesym(l, a, r.Right.Int64()) + slicesym(l, a, r.Right.Int64Val()) return true case OARRAYLIT, OSTRUCTLIT: @@ -205,7 +205,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool { case OSTR2BYTES: if l.Class() == PEXTERN && r.Left.Op == OLITERAL { - sval := strlit(r.Left) + sval := r.Left.StringVal() slicebytes(l, sval) return true } @@ -213,7 +213,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool { case OSLICELIT: s.initplan(r) // Init slice. - bound := r.Right.Int64() + bound := r.Right.Int64Val() ta := types.NewArray(r.Type.Elem(), bound) ta.SetNoalg(true) a := staticname(ta) @@ -278,7 +278,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool { return Isconst(val, CTNIL) } - markTypeUsedInInterface(val.Type) + markTypeUsedInInterface(val.Type, l.Sym.Linksym()) var itab *Node if l.Type.IsEmptyInterface() { @@ -375,11 +375,6 @@ func readonlystaticname(t *types.Type) *Node { return n } -func isLiteral(n *Node) bool { - // Treat nils as zeros rather than literals. - return n.Op == OLITERAL && n.Val().Ctype() != CTNIL -} - func (n *Node) isSimpleName() bool { return n.Op == ONAME && n.Class() != PAUTOHEAP && n.Class() != PEXTERN } @@ -404,7 +399,7 @@ const ( func getdyn(n *Node, top bool) initGenType { switch n.Op { default: - if isLiteral(n) { + if n.isGoConst() { return initConst } return initDynamic @@ -413,7 +408,7 @@ func getdyn(n *Node, top bool) initGenType { if !top { return initDynamic } - if n.Right.Int64()/4 > int64(n.List.Len()) { + if n.Right.Int64Val()/4 > int64(n.List.Len()) { // <25% of entries have explicit values. // Very rough estimation, it takes 4 bytes of instructions // to initialize 1 byte of result. So don't use a static @@ -559,7 +554,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) continue } - islit := isLiteral(value) + islit := value.isGoConst() if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) { continue } @@ -589,12 +584,12 @@ func isSmallSliceLit(n *Node) bool { r := n.Right - return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64() <= smallArrayBytes/n.Type.Elem().Width) + return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64Val() <= smallArrayBytes/n.Type.Elem().Width) } func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { // make an array type corresponding the number of elements we have - t := types.NewArray(n.Type.Elem(), n.Right.Int64()) + t := types.NewArray(n.Type.Elem(), n.Right.Int64Val()) dowidth(t) if ctxt == inNonInitFunction { @@ -732,7 +727,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { continue } - if vstat != nil && isLiteral(value) { // already set by copy from static value + if vstat != nil && value.isGoConst() { // already set by copy from static value continue } @@ -993,7 +988,7 @@ func oaslit(n *Node, init *Nodes) bool { func getlit(lit *Node) int { if smallintconst(lit) { - return int(lit.Int64()) + return int(lit.Int64Val()) } return -1 } diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 52083d999e..5b74754b53 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -9,6 +9,7 @@ import ( "fmt" "html" "os" + "path/filepath" "sort" "bufio" @@ -26,6 +27,7 @@ var ssaConfig *ssa.Config var ssaCaches []ssa.Cache var ssaDump string // early copy of $GOSSAFUNC; the func name to dump output for +var ssaDir string // optional destination for ssa dump file var ssaDumpStdout bool // whether to dump to stdout var ssaDumpCFG string // generate CFGs for these phases const ssaDumpFile = "ssa.html" @@ -48,21 +50,16 @@ func initssaconfig() { // Caching is disabled in the backend, so generating these here avoids allocations. _ = types.NewPtr(types.Types[TINTER]) // *interface{} _ = types.NewPtr(types.NewPtr(types.Types[TSTRING])) // **string - _ = types.NewPtr(types.NewPtr(types.Idealstring)) // **string _ = types.NewPtr(types.NewSlice(types.Types[TINTER])) // *[]interface{} _ = types.NewPtr(types.NewPtr(types.Bytetype)) // **byte _ = types.NewPtr(types.NewSlice(types.Bytetype)) // *[]byte _ = types.NewPtr(types.NewSlice(types.Types[TSTRING])) // *[]string - _ = types.NewPtr(types.NewSlice(types.Idealstring)) // *[]string _ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[TUINT8]))) // ***uint8 _ = types.NewPtr(types.Types[TINT16]) // *int16 _ = types.NewPtr(types.Types[TINT64]) // *int64 _ = types.NewPtr(types.Errortype) // *error types.NewPtrCacheEnabled = false - ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, Ctxt, Debug['N'] == 0) - if thearch.LinkArch.Name == "386" { - ssaConfig.Set387(thearch.Use387) - } + ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, Ctxt, Debug.N == 0) ssaConfig.SoftFloat = thearch.SoftFloat ssaConfig.Race = flag_race ssaCaches = make([]ssa.Cache, nBackendWorkers) @@ -75,13 +72,14 @@ func initssaconfig() { deferproc = sysfunc("deferproc") deferprocStack = sysfunc("deferprocStack") Deferreturn = sysfunc("deferreturn") - Duffcopy = sysvar("duffcopy") // asm func with special ABI - Duffzero = sysvar("duffzero") // asm func with special ABI - gcWriteBarrier = sysvar("gcWriteBarrier") // asm func with special ABI + Duffcopy = sysfunc("duffcopy") + Duffzero = sysfunc("duffzero") + gcWriteBarrier = sysfunc("gcWriteBarrier") goschedguarded = sysfunc("goschedguarded") growslice = sysfunc("growslice") msanread = sysfunc("msanread") msanwrite = sysfunc("msanwrite") + msanmove = sysfunc("msanmove") newobject = sysfunc("newobject") newproc = sysfunc("newproc") panicdivide = sysfunc("panicdivide") @@ -108,51 +106,51 @@ func initssaconfig() { // asm funcs with special ABI if thearch.LinkArch.Name == "amd64" { GCWriteBarrierReg = map[int16]*obj.LSym{ - x86.REG_AX: sysvar("gcWriteBarrier"), - x86.REG_CX: sysvar("gcWriteBarrierCX"), - x86.REG_DX: sysvar("gcWriteBarrierDX"), - x86.REG_BX: sysvar("gcWriteBarrierBX"), - x86.REG_BP: sysvar("gcWriteBarrierBP"), - x86.REG_SI: sysvar("gcWriteBarrierSI"), - x86.REG_R8: sysvar("gcWriteBarrierR8"), - x86.REG_R9: sysvar("gcWriteBarrierR9"), + x86.REG_AX: sysfunc("gcWriteBarrier"), + x86.REG_CX: sysfunc("gcWriteBarrierCX"), + x86.REG_DX: sysfunc("gcWriteBarrierDX"), + x86.REG_BX: sysfunc("gcWriteBarrierBX"), + x86.REG_BP: sysfunc("gcWriteBarrierBP"), + x86.REG_SI: sysfunc("gcWriteBarrierSI"), + x86.REG_R8: sysfunc("gcWriteBarrierR8"), + x86.REG_R9: sysfunc("gcWriteBarrierR9"), } } if thearch.LinkArch.Family == sys.Wasm { - BoundsCheckFunc[ssa.BoundsIndex] = sysvar("goPanicIndex") - BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("goPanicIndexU") - BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("goPanicSliceAlen") - BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("goPanicSliceAlenU") - BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("goPanicSliceAcap") - BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("goPanicSliceAcapU") - BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("goPanicSliceB") - BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("goPanicSliceBU") - BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("goPanicSlice3Alen") - BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("goPanicSlice3AlenU") - BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("goPanicSlice3Acap") - BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("goPanicSlice3AcapU") - BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("goPanicSlice3B") - BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("goPanicSlice3BU") - BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("goPanicSlice3C") - BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("goPanicSlice3CU") + BoundsCheckFunc[ssa.BoundsIndex] = sysfunc("goPanicIndex") + BoundsCheckFunc[ssa.BoundsIndexU] = sysfunc("goPanicIndexU") + BoundsCheckFunc[ssa.BoundsSliceAlen] = sysfunc("goPanicSliceAlen") + BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysfunc("goPanicSliceAlenU") + BoundsCheckFunc[ssa.BoundsSliceAcap] = sysfunc("goPanicSliceAcap") + BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysfunc("goPanicSliceAcapU") + BoundsCheckFunc[ssa.BoundsSliceB] = sysfunc("goPanicSliceB") + BoundsCheckFunc[ssa.BoundsSliceBU] = sysfunc("goPanicSliceBU") + BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysfunc("goPanicSlice3Alen") + BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysfunc("goPanicSlice3AlenU") + BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysfunc("goPanicSlice3Acap") + BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysfunc("goPanicSlice3AcapU") + BoundsCheckFunc[ssa.BoundsSlice3B] = sysfunc("goPanicSlice3B") + BoundsCheckFunc[ssa.BoundsSlice3BU] = sysfunc("goPanicSlice3BU") + BoundsCheckFunc[ssa.BoundsSlice3C] = sysfunc("goPanicSlice3C") + BoundsCheckFunc[ssa.BoundsSlice3CU] = sysfunc("goPanicSlice3CU") } else { - BoundsCheckFunc[ssa.BoundsIndex] = sysvar("panicIndex") - BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("panicIndexU") - BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicSliceAlen") - BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicSliceAlenU") - BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicSliceAcap") - BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicSliceAcapU") - BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("panicSliceB") - BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("panicSliceBU") - BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicSlice3Alen") - BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicSlice3AlenU") - BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicSlice3Acap") - BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicSlice3AcapU") - BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("panicSlice3B") - BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicSlice3BU") - BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("panicSlice3C") - BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicSlice3CU") + BoundsCheckFunc[ssa.BoundsIndex] = sysfunc("panicIndex") + BoundsCheckFunc[ssa.BoundsIndexU] = sysfunc("panicIndexU") + BoundsCheckFunc[ssa.BoundsSliceAlen] = sysfunc("panicSliceAlen") + BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysfunc("panicSliceAlenU") + BoundsCheckFunc[ssa.BoundsSliceAcap] = sysfunc("panicSliceAcap") + BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysfunc("panicSliceAcapU") + BoundsCheckFunc[ssa.BoundsSliceB] = sysfunc("panicSliceB") + BoundsCheckFunc[ssa.BoundsSliceBU] = sysfunc("panicSliceBU") + BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysfunc("panicSlice3Alen") + BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysfunc("panicSlice3AlenU") + BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysfunc("panicSlice3Acap") + BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysfunc("panicSlice3AcapU") + BoundsCheckFunc[ssa.BoundsSlice3B] = sysfunc("panicSlice3B") + BoundsCheckFunc[ssa.BoundsSlice3BU] = sysfunc("panicSlice3BU") + BoundsCheckFunc[ssa.BoundsSlice3C] = sysfunc("panicSlice3C") + BoundsCheckFunc[ssa.BoundsSlice3CU] = sysfunc("panicSlice3CU") } if thearch.LinkArch.PtrSize == 4 { ExtendCheckFunc[ssa.BoundsIndex] = sysvar("panicExtendIndex") @@ -173,10 +171,6 @@ func initssaconfig() { ExtendCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicExtendSlice3CU") } - // GO386=387 runtime definitions - ControlWord64trunc = sysvar("controlWord64trunc") // uint16 - ControlWord32 = sysvar("controlWord32") // uint16 - // Wasm (all asm funcs with special ABIs) WasmMove = sysvar("wasmMove") WasmZero = sysvar("wasmZero") @@ -247,7 +241,7 @@ func dvarint(x *obj.LSym, off int, v int64) int { // - Offset of where argument should be placed in the args frame when making call func (s *state) emitOpenDeferInfo() { x := Ctxt.Lookup(s.curfn.Func.lsym.Name + ".opendefer") - s.curfn.Func.lsym.Func.OpenCodedDeferInfo = x + s.curfn.Func.lsym.Func().OpenCodedDeferInfo = x off := 0 // Compute maxargsize (max size of arguments for all defers) @@ -346,7 +340,13 @@ func buildssa(fn *Node, worker int) *ssa.Func { s.f.Entry.Pos = fn.Pos if printssa { - s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDumpFile, s.f, ssaDumpCFG) + ssaDF := ssaDumpFile + if ssaDir != "" { + ssaDF = filepath.Join(ssaDir, myimportpath+"."+name+".html") + ssaD := filepath.Dir(ssaDF) + os.MkdirAll(ssaD, 0755) + } + s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDF, s.f, ssaDumpCFG) // TODO: generate and print a mapping from nodes to values and blocks dumpSourcesColumn(s.f.HTMLWriter, fn) s.f.HTMLWriter.WriteAST("AST", astBuf) @@ -358,7 +358,7 @@ func buildssa(fn *Node, worker int) *ssa.Func { s.fwdVars = map[*Node]*ssa.Value{} s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem) - s.hasOpenDefers = Debug['N'] == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed() + s.hasOpenDefers = Debug.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed() switch { case s.hasOpenDefers && (Ctxt.Flag_shared || Ctxt.Flag_dynlink) && thearch.LinkArch.Name == "386": // Don't support open-coded defers for 386 ONLY when using shared @@ -410,11 +410,17 @@ func buildssa(fn *Node, worker int) *ssa.Func { // Generate addresses of local declarations s.decladdrs = map[*Node]*ssa.Value{} + var args []ssa.Param + var results []ssa.Param for _, n := range fn.Func.Dcl { switch n.Class() { - case PPARAM, PPARAMOUT: + case PPARAM: s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem) - if n.Class() == PPARAMOUT && s.canSSA(n) { + args = append(args, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)}) + case PPARAMOUT: + s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem) + results = append(results, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)}) + if s.canSSA(n) { // Save ssa-able PPARAMOUT variables so we can // store them back to the stack at the end of // the function. @@ -651,6 +657,8 @@ type state struct { lastDeferExit *ssa.Block // Entry block of last defer exit code we generated lastDeferFinalBlock *ssa.Block // Final block of last defer exit code we generated lastDeferCount int // Number of defers encountered at that point + + prevCall *ssa.Value // the previous call; use this to tie results to the call op. } type funcLine struct { @@ -740,7 +748,7 @@ func (s *state) pushLine(line src.XPos) { // the frontend may emit node with line number missing, // use the parent line number in this case. line = s.peekPos() - if Debug['K'] != 0 { + if Debug.K != 0 { Warn("buildssa: unknown position (line 0)") } } else { @@ -805,6 +813,11 @@ func (s *state) newValue2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Value) *ssa. return s.curBlock.NewValue2(s.peekPos(), op, t, arg0, arg1) } +// newValue2A adds a new value with two arguments and an aux value to the current block. +func (s *state) newValue2A(op ssa.Op, t *types.Type, aux interface{}, arg0, arg1 *ssa.Value) *ssa.Value { + return s.curBlock.NewValue2A(s.peekPos(), op, t, aux, arg0, arg1) +} + // newValue2Apos adds a new value with two arguments and an aux value to the current block. // isStmt determines whether the created values may be a statement or not // (i.e., false means never, yes means maybe). @@ -954,7 +967,45 @@ func (s *state) newValueOrSfCall2(op ssa.Op, t *types.Type, arg0, arg1 *ssa.Valu return s.newValue2(op, t, arg0, arg1) } -func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) { +type instrumentKind uint8 + +const ( + instrumentRead = iota + instrumentWrite + instrumentMove +) + +func (s *state) instrument(t *types.Type, addr *ssa.Value, kind instrumentKind) { + s.instrument2(t, addr, nil, kind) +} + +// instrumentFields instruments a read/write operation on addr. +// If it is instrumenting for MSAN and t is a struct type, it instruments +// operation for each field, instead of for the whole struct. +func (s *state) instrumentFields(t *types.Type, addr *ssa.Value, kind instrumentKind) { + if !flag_msan || !t.IsStruct() { + s.instrument(t, addr, kind) + return + } + for _, f := range t.Fields().Slice() { + if f.Sym.IsBlank() { + continue + } + offptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(f.Type), f.Offset, addr) + s.instrumentFields(f.Type, offptr, kind) + } +} + +func (s *state) instrumentMove(t *types.Type, dst, src *ssa.Value) { + if flag_msan { + s.instrument2(t, dst, src, instrumentMove) + } else { + s.instrument(t, src, instrumentRead) + s.instrument(t, dst, instrumentWrite) + } +} + +func (s *state) instrument2(t *types.Type, addr, addr2 *ssa.Value, kind instrumentKind) { if !s.curfn.Func.InstrumentBody() { return } @@ -971,33 +1022,54 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) { var fn *obj.LSym needWidth := false + if addr2 != nil && kind != instrumentMove { + panic("instrument2: non-nil addr2 for non-move instrumentation") + } + if flag_msan { - fn = msanread - if wr { + switch kind { + case instrumentRead: + fn = msanread + case instrumentWrite: fn = msanwrite + case instrumentMove: + fn = msanmove + default: + panic("unreachable") } needWidth = true } else if flag_race && t.NumComponents(types.CountBlankFields) > 1 { // for composite objects we have to write every address // because a write might happen to any subobject. // composites with only one element don't have subobjects, though. - fn = racereadrange - if wr { + switch kind { + case instrumentRead: + fn = racereadrange + case instrumentWrite: fn = racewriterange + default: + panic("unreachable") } needWidth = true } else if flag_race { // for non-composite objects we can write just the start // address, as any write must write the first byte. - fn = raceread - if wr { + switch kind { + case instrumentRead: + fn = raceread + case instrumentWrite: fn = racewrite + default: + panic("unreachable") } } else { panic("unreachable") } args := []*ssa.Value{addr} + if addr2 != nil { + args = append(args, addr2) + } if needWidth { args = append(args, s.constInt(types.Types[TUINTPTR], w)) } @@ -1005,7 +1077,7 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) { } func (s *state) load(t *types.Type, src *ssa.Value) *ssa.Value { - s.instrument(t, src, false) + s.instrumentFields(t, src, instrumentRead) return s.rawLoad(t, src) } @@ -1018,15 +1090,14 @@ func (s *state) store(t *types.Type, dst, val *ssa.Value) { } func (s *state) zero(t *types.Type, dst *ssa.Value) { - s.instrument(t, dst, true) + s.instrument(t, dst, instrumentWrite) store := s.newValue2I(ssa.OpZero, types.TypeMem, t.Size(), dst, s.mem()) store.Aux = t s.vars[&memVar] = store } func (s *state) move(t *types.Type, dst, src *ssa.Value) { - s.instrument(t, src, false) - s.instrument(t, dst, true) + s.instrumentMove(t, dst, src) store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem()) store.Aux = t s.vars[&memVar] = store @@ -1071,7 +1142,7 @@ func (s *state) stmt(n *Node) { fallthrough case OCALLMETH, OCALLINTER: - s.call(n, callNormal) + s.callResult(n, callNormal) if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class() == PFUNC { if fn := n.Left.Sym.Name; compiling_runtime && fn == "throw" || n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") { @@ -1103,10 +1174,10 @@ func (s *state) stmt(n *Node) { if n.Esc == EscNever { d = callDeferStack } - s.call(n.Left, d) + s.callResult(n.Left, d) } case OGO: - s.call(n.Left, callGo) + s.callResult(n.Left, callGo) case OAS2DOTTYPE: res, resok := s.dottype(n.Right, true) @@ -1208,7 +1279,7 @@ func (s *state) stmt(n *Node) { // Check whether we're writing the result of an append back to the same slice. // If so, we handle it specially to avoid write barriers on the fast // (non-growth) path. - if !samesafeexpr(n.Left, rhs.List.First()) || Debug['N'] != 0 { + if !samesafeexpr(n.Left, rhs.List.First()) || Debug.N != 0 { break } // If the slice can be SSA'd, it'll be on the stack, @@ -1265,7 +1336,7 @@ func (s *state) stmt(n *Node) { // We're assigning a slicing operation back to its source. // Don't write back fields we aren't changing. See issue #14855. i, j, k := rhs.SliceBounds() - if i != nil && (i.Op == OLITERAL && i.Val().Ctype() == CTINT && i.Int64() == 0) { + if i != nil && (i.Op == OLITERAL && i.Val().Ctype() == CTINT && i.Int64Val() == 0) { // [0:...] is the same as [:...] i = nil } @@ -1295,7 +1366,7 @@ func (s *state) stmt(n *Node) { case OIF: if Isconst(n.Left, CTBOOL) { s.stmtList(n.Left.Ninit) - if n.Left.Bool() { + if n.Left.BoolVal() { s.stmtList(n.Nbody) } else { s.stmtList(n.Rlist) @@ -2113,7 +2184,7 @@ func (s *state) expr(n *Node) *ssa.Value { } // unsafe.Pointer <--> *T - if to.Etype == TUNSAFEPTR && from.IsPtrShaped() || from.Etype == TUNSAFEPTR && to.IsPtrShaped() { + if to.IsUnsafePtr() && from.IsPtrShaped() || from.IsUnsafePtr() && to.IsPtrShaped() { return v } @@ -2466,6 +2537,11 @@ func (s *state) expr(n *Node) *ssa.Value { a := s.expr(n.Left) b := s.expr(n.Right) return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) + case OANDNOT: + a := s.expr(n.Left) + b := s.expr(n.Right) + b = s.newValue1(s.ssaOp(OBITNOT, b.Type), b.Type, b) + return s.newValue2(s.ssaOp(OAND, n.Type), a.Type, a, b) case OLSH, ORSH: a := s.expr(n.Left) b := s.expr(n.Right) @@ -2549,8 +2625,23 @@ func (s *state) expr(n *Node) *ssa.Value { return s.addr(n.Left) case ORESULT: - addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) - return s.load(n.Type, addr) + if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall { + // Do the old thing + addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) + return s.rawLoad(n.Type, addr) + } + which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset) + if which == -1 { + // Do the old thing // TODO: Panic instead. + addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) + return s.rawLoad(n.Type, addr) + } + if canSSAType(n.Type) { + return s.newValue1I(ssa.OpSelectN, n.Type, which, s.prevCall) + } else { + addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(n.Type), which, s.prevCall) + return s.rawLoad(n.Type, addr) + } case ODEREF: p := s.exprPtr(n.Left, n.Bounded(), n.Pos) @@ -2589,7 +2680,7 @@ func (s *state) expr(n *Node) *ssa.Value { // Replace "abc"[1] with 'b'. // Delayed until now because "abc"[1] is not an ideal constant. // See test/fixedbugs/issue11370.go. - return s.newValue0I(ssa.OpConst8, types.Types[TUINT8], int64(int8(strlit(n.Left)[n.Right.Int64()]))) + return s.newValue0I(ssa.OpConst8, types.Types[TUINT8], int64(int8(n.Left.StringVal()[n.Right.Int64Val()]))) } a := s.expr(n.Left) i := s.expr(n.Right) @@ -2598,7 +2689,7 @@ func (s *state) expr(n *Node) *ssa.Value { ptrtyp := s.f.Config.Types.BytePtr ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a) if Isconst(n.Right, CTINT) { - ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64(), ptr) + ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr) } else { ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i) } @@ -2710,8 +2801,7 @@ func (s *state) expr(n *Node) *ssa.Value { fallthrough case OCALLINTER, OCALLMETH: - a := s.call(n, callNormal) - return s.load(n.Type, a) + return s.callResult(n, callNormal) case OGETG: return s.newValue1(ssa.OpGetG, n.Type, s.mem()) @@ -3369,6 +3459,13 @@ func init() { return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) }, sys.PPC64, sys.S390X) + addF("runtime/internal/atomic", "LoadAcq64", + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + v := s.newValue2(ssa.OpAtomicLoadAcq64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], s.mem()) + s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) + }, + sys.PPC64) addF("runtime/internal/atomic", "Loadp", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { v := s.newValue2(ssa.OpAtomicLoadPtr, types.NewTuple(s.f.Config.Types.BytePtr, types.TypeMem), args[0], s.mem()) @@ -3407,6 +3504,12 @@ func init() { return nil }, sys.PPC64, sys.S390X) + addF("runtime/internal/atomic", "StoreRel64", + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + s.vars[&memVar] = s.newValue3(ssa.OpAtomicStoreRel64, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, + sys.PPC64) addF("runtime/internal/atomic", "Xchg", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { @@ -3414,31 +3517,19 @@ func init() { s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) }, - sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) addF("runtime/internal/atomic", "Xchg64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) }, - sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) - - addF("runtime/internal/atomic", "Xadd", - func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], args[1], s.mem()) - s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) - return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) - }, - sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) - addF("runtime/internal/atomic", "Xadd64", - func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem()) - s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) - return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) - }, sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) - makeXaddARM64 := func(op0 ssa.Op, op1 ssa.Op, ty types.EType) func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + type atomicOpEmitter func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) + + makeAtomicGuardedIntrinsicARM64 := func(op0, op1 ssa.Op, typ, rtyp types.EType, emit atomicOpEmitter) intrinsicBuilder { + return func(s *state, n *Node, args []*ssa.Value) *ssa.Value { // Target Atomic feature is identified by dynamic detection addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), arm64HasATOMICS, s.sb) @@ -3451,33 +3542,60 @@ func init() { bEnd := s.f.NewBlock(ssa.BlockPlain) b.AddEdgeTo(bTrue) b.AddEdgeTo(bFalse) - b.Likely = ssa.BranchUnlikely // most machines don't have Atomics nowadays + b.Likely = ssa.BranchLikely // We have atomic instructions - use it directly. s.startBlock(bTrue) - v0 := s.newValue3(op1, types.NewTuple(types.Types[ty], types.TypeMem), args[0], args[1], s.mem()) - s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v0) - s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[ty], v0) + emit(s, n, args, op1, typ) s.endBlock().AddEdgeTo(bEnd) // Use original instruction sequence. s.startBlock(bFalse) - v1 := s.newValue3(op0, types.NewTuple(types.Types[ty], types.TypeMem), args[0], args[1], s.mem()) - s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v1) - s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[ty], v1) + emit(s, n, args, op0, typ) s.endBlock().AddEdgeTo(bEnd) // Merge results. s.startBlock(bEnd) - return s.variable(n, types.Types[ty]) + if rtyp == TNIL { + return nil + } else { + return s.variable(n, types.Types[rtyp]) + } } } + atomicXchgXaddEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) { + v := s.newValue3(op, types.NewTuple(types.Types[typ], types.TypeMem), args[0], args[1], s.mem()) + s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v) + } + addF("runtime/internal/atomic", "Xchg", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange32, ssa.OpAtomicExchange32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "Xchg64", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange64, ssa.OpAtomicExchange64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "Xadd", - makeXaddARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, TUINT32), + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], args[1], s.mem()) + s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) + }, + sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + addF("runtime/internal/atomic", "Xadd64", + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem()) + s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) + }, + sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + + addF("runtime/internal/atomic", "Xadd", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64), sys.ARM64) addF("runtime/internal/atomic", "Xadd64", - makeXaddARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, TUINT64), + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64), sys.ARM64) addF("runtime/internal/atomic", "Cas", @@ -3486,14 +3604,14 @@ func init() { s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v) }, - sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) addF("runtime/internal/atomic", "Cas64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { v := s.newValue4(ssa.OpAtomicCompareAndSwap64, types.NewTuple(types.Types[TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v) }, - sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) addF("runtime/internal/atomic", "CasRel", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.Types[TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem()) @@ -3502,18 +3620,60 @@ func init() { }, sys.PPC64) + atomicCasEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) { + v := s.newValue4(op, types.NewTuple(types.Types[TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem()) + s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v) + } + + addF("runtime/internal/atomic", "Cas", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap32, ssa.OpAtomicCompareAndSwap32Variant, TUINT32, TBOOL, atomicCasEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "Cas64", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap64, ssa.OpAtomicCompareAndSwap64Variant, TUINT64, TBOOL, atomicCasEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "And8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { s.vars[&memVar] = s.newValue3(ssa.OpAtomicAnd8, types.TypeMem, args[0], args[1], s.mem()) return nil }, - sys.AMD64, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X) + sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X) + addF("runtime/internal/atomic", "And", + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + s.vars[&memVar] = s.newValue3(ssa.OpAtomicAnd32, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, + sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X) addF("runtime/internal/atomic", "Or8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { s.vars[&memVar] = s.newValue3(ssa.OpAtomicOr8, types.TypeMem, args[0], args[1], s.mem()) return nil }, sys.AMD64, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X) + addF("runtime/internal/atomic", "Or", + func(s *state, n *Node, args []*ssa.Value) *ssa.Value { + s.vars[&memVar] = s.newValue3(ssa.OpAtomicOr32, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, + sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X) + + atomicAndOrEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) { + s.vars[&memVar] = s.newValue3(op, types.TypeMem, args[0], args[1], s.mem()) + } + + addF("runtime/internal/atomic", "And8", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd8, ssa.OpAtomicAnd8Variant, TNIL, TNIL, atomicAndOrEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "And", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd32, ssa.OpAtomicAnd32Variant, TNIL, TNIL, atomicAndOrEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "Or8", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr8, ssa.OpAtomicOr8Variant, TNIL, TNIL, atomicAndOrEmitterARM64), + sys.ARM64) + addF("runtime/internal/atomic", "Or", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr32, ssa.OpAtomicOr32Variant, TNIL, TNIL, atomicAndOrEmitterARM64), + sys.ARM64) alias("runtime/internal/atomic", "Loadint64", "runtime/internal/atomic", "Load64", all...) alias("runtime/internal/atomic", "Xaddint64", "runtime/internal/atomic", "Xadd64", all...) @@ -3522,9 +3682,19 @@ func init() { alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load", p4...) alias("runtime/internal/atomic", "Loaduintptr", "runtime/internal/atomic", "Load64", p8...) alias("runtime/internal/atomic", "LoadAcq", "runtime/internal/atomic", "Load", lwatomics...) + alias("runtime/internal/atomic", "LoadAcq64", "runtime/internal/atomic", "Load64", lwatomics...) + alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...) + alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq", p4...) // linknamed + alias("runtime/internal/atomic", "LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...) + alias("sync", "runtime_LoadAcquintptr", "runtime/internal/atomic", "LoadAcq64", p8...) // linknamed alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store", p4...) alias("runtime/internal/atomic", "Storeuintptr", "runtime/internal/atomic", "Store64", p8...) alias("runtime/internal/atomic", "StoreRel", "runtime/internal/atomic", "Store", lwatomics...) + alias("runtime/internal/atomic", "StoreRel64", "runtime/internal/atomic", "Store64", lwatomics...) + alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...) + alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel", p4...) // linknamed + alias("runtime/internal/atomic", "StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...) + alias("sync", "runtime_StoreReluintptr", "runtime/internal/atomic", "StoreRel64", p8...) // linknamed alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg", p4...) alias("runtime/internal/atomic", "Xchguintptr", "runtime/internal/atomic", "Xchg64", p8...) alias("runtime/internal/atomic", "Xadduintptr", "runtime/internal/atomic", "Xadd", p4...) @@ -3584,8 +3754,7 @@ func init() { addF("math", "FMA", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if !s.config.UseFMA { - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TFLOAT64], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64] return s.variable(n, types.Types[TFLOAT64]) } v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasFMA) @@ -3606,8 +3775,7 @@ func init() { // Call the pure Go version. s.startBlock(bFalse) - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TFLOAT64], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64] s.endBlock().AddEdgeTo(bEnd) // Merge results. @@ -3618,8 +3786,7 @@ func init() { addF("math", "FMA", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if !s.config.UseFMA { - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TFLOAT64], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64] return s.variable(n, types.Types[TFLOAT64]) } addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), armHasVFPv4, s.sb) @@ -3641,8 +3808,7 @@ func init() { // Call the pure Go version. s.startBlock(bFalse) - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TFLOAT64], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64] s.endBlock().AddEdgeTo(bEnd) // Merge results. @@ -3671,8 +3837,7 @@ func init() { // Call the pure Go version. s.startBlock(bFalse) - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TFLOAT64], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64] s.endBlock().AddEdgeTo(bEnd) // Merge results. @@ -3882,8 +4047,7 @@ func init() { // Call the pure Go version. s.startBlock(bFalse) - a := s.call(n, callNormal) - s.vars[n] = s.load(types.Types[TINT], a) + s.vars[n] = s.callResult(n, callNormal) // types.Types[TINT] s.endBlock().AddEdgeTo(bEnd) // Merge results. @@ -4006,11 +4170,6 @@ func init() { return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1]) }, sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64LE, sys.ArchPPC64, sys.ArchS390X) - add("math/big", "divWW", - func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue3(ssa.OpDiv128u, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2]) - }, - sys.ArchAMD64) } // findIntrinsic returns a function which builds the SSA equivalent of the @@ -4240,6 +4399,7 @@ func (s *state) openDeferExit() { s.lastDeferExit = deferExit s.lastDeferCount = len(s.openDefers) zeroval := s.constInt8(types.Types[TUINT8], 0) + testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f) // Test for and run defers in reverse order for i := len(s.openDefers) - 1; i >= 0; i-- { r := s.openDefers[i] @@ -4275,21 +4435,40 @@ func (s *state) openDeferExit() { argStart := Ctxt.FixedFrameSize() fn := r.n.Left stksize := fn.Type.ArgWidth() + var ACArgs []ssa.Param + var ACResults []ssa.Param + var callArgs []*ssa.Value if r.rcvr != nil { // rcvr in case of OCALLINTER v := s.load(r.rcvr.Type.Elem(), r.rcvr) addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart) - s.store(types.Types[TUINTPTR], addr, v) + ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)}) + if testLateExpansion { + callArgs = append(callArgs, v) + } else { + s.store(types.Types[TUINTPTR], addr, v) + } } for j, argAddrVal := range r.argVals { f := getParam(r.n, j) pt := types.NewPtr(f.Type) - addr := s.constOffPtrSP(pt, argStart+f.Offset) - if !canSSAType(f.Type) { - s.move(f.Type, addr, argAddrVal) + ACArgs = append(ACArgs, ssa.Param{Type: f.Type, Offset: int32(argStart + f.Offset)}) + if testLateExpansion { + var a *ssa.Value + if !canSSAType(f.Type) { + a = s.newValue2(ssa.OpDereference, f.Type, argAddrVal, s.mem()) + } else { + a = s.load(f.Type, argAddrVal) + } + callArgs = append(callArgs, a) } else { - argVal := s.load(f.Type, argAddrVal) - s.storeType(f.Type, addr, argVal, 0, false) + addr := s.constOffPtrSP(pt, argStart+f.Offset) + if !canSSAType(f.Type) { + s.move(f.Type, addr, argAddrVal) + } else { + argVal := s.load(f.Type, argAddrVal) + s.storeType(f.Type, addr, argVal, 0, false) + } } } var call *ssa.Value @@ -4297,13 +4476,31 @@ func (s *state) openDeferExit() { v := s.load(r.closure.Type.Elem(), r.closure) s.maybeNilCheckClosure(v, callDefer) codeptr := s.rawLoad(types.Types[TUINTPTR], v) - call = s.newValue3(ssa.OpClosureCall, types.TypeMem, codeptr, v, s.mem()) + aux := ssa.ClosureAuxCall(ACArgs, ACResults) + if testLateExpansion { + callArgs = append(callArgs, s.mem()) + call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, v) + call.AddArgs(callArgs...) + } else { + call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, aux, codeptr, v, s.mem()) + } } else { - // Do a static call if the original call was a static function or method - call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, fn.Sym.Linksym(), s.mem()) + aux := ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults) + if testLateExpansion { + callArgs = append(callArgs, s.mem()) + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + } else { + // Do a static call if the original call was a static function or method + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem()) + } } call.AuxInt = stksize - s.vars[&memVar] = call + if testLateExpansion { + s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call) + } else { + s.vars[&memVar] = call + } // Make sure that the stack slots with pointers are kept live // through the call (which is a pre-emption point). Also, we will // use the first call of the last defer exit to compute liveness @@ -4327,16 +4524,40 @@ func (s *state) openDeferExit() { } } +func (s *state) callResult(n *Node, k callKind) *ssa.Value { + return s.call(n, k, false) +} + +func (s *state) callAddr(n *Node, k callKind) *ssa.Value { + return s.call(n, k, true) +} + // Calls the function n using the specified call type. // Returns the address of the return value (or nil if none). -func (s *state) call(n *Node, k callKind) *ssa.Value { +func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value { + s.prevCall = nil var sym *types.Sym // target symbol (if static) var closure *ssa.Value // ptr to closure to run (if dynamic) var codeptr *ssa.Value // ptr to target code (if dynamic) var rcvr *ssa.Value // receiver to set fn := n.Left + var ACArgs []ssa.Param + var ACResults []ssa.Param + var callArgs []*ssa.Value + res := n.Left.Type.Results() + if k == callNormal { + nf := res.NumFields() + for i := 0; i < nf; i++ { + fp := res.Field(i) + ACResults = append(ACResults, ssa.Param{Type: fp.Type, Offset: int32(fp.Offset + Ctxt.FixedFrameSize())}) + } + } + + testLateExpansion := false + switch n.Op { case OCALLFUNC: + testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) if k == callNormal && fn.Op == ONAME && fn.Class() == PFUNC { sym = fn.Sym break @@ -4351,6 +4572,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { if fn.Op != ODOTMETH { s.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn) } + testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) if k == callNormal { sym = fn.Sym break @@ -4362,6 +4584,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { if fn.Op != ODOTINTER { s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op) } + testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) var iclosure *ssa.Value iclosure, rcvr = s.getClosureAndRcvr(fn) if k == callNormal { @@ -4380,6 +4603,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { var call *ssa.Value if k == callDeferStack { + testLateExpansion = ssa.LateCallExpansionEnabledWithin(s.f) // Make a defer struct d on the stack. t := deferstruct(stksize) d := tempAt(n.Pos, s.curfn, t) @@ -4430,12 +4654,21 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { } // Call runtime.deferprocStack with pointer to _defer record. - arg0 := s.constOffPtrSP(types.Types[TUINTPTR], Ctxt.FixedFrameSize()) - s.store(types.Types[TUINTPTR], arg0, addr) - call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, deferprocStack, s.mem()) + ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(Ctxt.FixedFrameSize())}) + aux := ssa.StaticAuxCall(deferprocStack, ACArgs, ACResults) + if testLateExpansion { + callArgs = append(callArgs, addr, s.mem()) + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + } else { + arg0 := s.constOffPtrSP(types.Types[TUINTPTR], Ctxt.FixedFrameSize()) + s.store(types.Types[TUINTPTR], arg0, addr) + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem()) + } if stksize < int64(Widthptr) { // We need room for both the call to deferprocStack and the call to // the deferred function. + // TODO Revisit this if/when we pass args in registers. stksize = int64(Widthptr) } call.AuxInt = stksize @@ -4447,10 +4680,20 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { if k != callNormal { // Write argsize and closure (args to newproc/deferproc). argsize := s.constInt32(types.Types[TUINT32], int32(stksize)) - addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart) - s.store(types.Types[TUINT32], addr, argsize) - addr = s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(Widthptr)) - s.store(types.Types[TUINTPTR], addr, closure) + ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINT32], Offset: int32(argStart)}) + if testLateExpansion { + callArgs = append(callArgs, argsize) + } else { + addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart) + s.store(types.Types[TUINT32], addr, argsize) + } + ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart) + int32(Widthptr)}) + if testLateExpansion { + callArgs = append(callArgs, closure) + } else { + addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(Widthptr)) + s.store(types.Types[TUINTPTR], addr, closure) + } stksize += 2 * int64(Widthptr) argStart += 2 * int64(Widthptr) } @@ -4458,7 +4701,12 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { // Set receiver (for interface calls). if rcvr != nil { addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart) - s.store(types.Types[TUINTPTR], addr, rcvr) + ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)}) + if testLateExpansion { + callArgs = append(callArgs, rcvr) + } else { + s.store(types.Types[TUINTPTR], addr, rcvr) + } } // Write args. @@ -4466,20 +4714,38 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { args := n.Rlist.Slice() if n.Op == OCALLMETH { f := t.Recv() - s.storeArg(args[0], f.Type, argStart+f.Offset) + ACArg, arg := s.putArg(args[0], f.Type, argStart+f.Offset, testLateExpansion) + ACArgs = append(ACArgs, ACArg) + callArgs = append(callArgs, arg) args = args[1:] } for i, n := range args { f := t.Params().Field(i) - s.storeArg(n, f.Type, argStart+f.Offset) + ACArg, arg := s.putArg(n, f.Type, argStart+f.Offset, testLateExpansion) + ACArgs = append(ACArgs, ACArg) + callArgs = append(callArgs, arg) } + callArgs = append(callArgs, s.mem()) + // call target switch { case k == callDefer: - call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, deferproc, s.mem()) + aux := ssa.StaticAuxCall(deferproc, ACArgs, ACResults) + if testLateExpansion { + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + } else { + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem()) + } case k == callGo: - call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, newproc, s.mem()) + aux := ssa.StaticAuxCall(newproc, ACArgs, ACResults) + if testLateExpansion { + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + } else { + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem()) + } case closure != nil: // rawLoad because loading the code pointer from a // closure is always safe, but IsSanitizerSafeAddr @@ -4487,17 +4753,42 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { // critical that we not clobber any arguments already // stored onto the stack. codeptr = s.rawLoad(types.Types[TUINTPTR], closure) - call = s.newValue3(ssa.OpClosureCall, types.TypeMem, codeptr, closure, s.mem()) + if testLateExpansion { + aux := ssa.ClosureAuxCall(ACArgs, ACResults) + call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, closure) + call.AddArgs(callArgs...) + } else { + call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, ssa.ClosureAuxCall(ACArgs, ACResults), codeptr, closure, s.mem()) + } case codeptr != nil: - call = s.newValue2(ssa.OpInterCall, types.TypeMem, codeptr, s.mem()) + if testLateExpansion { + aux := ssa.InterfaceAuxCall(ACArgs, ACResults) + call = s.newValue1A(ssa.OpInterLECall, aux.LateExpansionResultType(), aux, codeptr) + call.AddArgs(callArgs...) + } else { + call = s.newValue2A(ssa.OpInterCall, types.TypeMem, ssa.InterfaceAuxCall(ACArgs, ACResults), codeptr, s.mem()) + } case sym != nil: - call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, sym.Linksym(), s.mem()) + if testLateExpansion { + aux := ssa.StaticAuxCall(sym.Linksym(), ACArgs, ACResults) + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + } else { + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(sym.Linksym(), ACArgs, ACResults), s.mem()) + } default: s.Fatalf("bad call type %v %v", n.Op, n) } call.AuxInt = stksize // Call operations carry the argsize of the callee along with them } - s.vars[&memVar] = call + if testLateExpansion { + s.prevCall = call + s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call) + } else { + s.vars[&memVar] = call + } + // Insert OVARLIVE nodes + s.stmtList(n.Nbody) // Finish block for defers if k == callDefer || k == callDeferStack { @@ -4515,13 +4806,23 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { s.startBlock(bNext) } - res := n.Left.Type.Results() if res.NumFields() == 0 || k != callNormal { // call has no return value. Continue with the next statement. return nil } fp := res.Field(0) - return s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize()) + if returnResultAddr { + pt := types.NewPtr(fp.Type) + if testLateExpansion { + return s.newValue1I(ssa.OpSelectNAddr, pt, 0, call) + } + return s.constOffPtrSP(pt, fp.Offset+Ctxt.FixedFrameSize()) + } + + if testLateExpansion { + return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call) + } + return s.load(n.Type, s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize())) } // maybeNilCheckClosure checks if a nil check of a closure is needed in some @@ -4558,7 +4859,7 @@ func (s *state) getClosureAndRcvr(fn *Node) (*ssa.Value, *ssa.Value) { s.nilCheck(itab) itabidx := fn.Xoffset + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab) - rcvr := s.newValue1(ssa.OpIData, types.Types[TUINTPTR], i) + rcvr := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, i) return closure, rcvr } @@ -4619,7 +4920,17 @@ func (s *state) addr(n *Node) *ssa.Value { } case ORESULT: // load return from callee - return s.constOffPtrSP(t, n.Xoffset) + if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall { + return s.constOffPtrSP(t, n.Xoffset) + } + which := s.prevCall.Aux.(*ssa.AuxCall).ResultForOffset(n.Xoffset) + if which == -1 { + // Do the old thing // TODO: Panic instead. + return s.constOffPtrSP(t, n.Xoffset) + } + x := s.newValue1I(ssa.OpSelectNAddr, t, which, s.prevCall) + return x + case OINDEX: if n.Left.Type.IsSlice() { a := s.expr(n.Left) @@ -4650,7 +4961,7 @@ func (s *state) addr(n *Node) *ssa.Value { addr := s.addr(n.Left) return s.newValue1(ssa.OpCopy, t, addr) // ensure that addr has the right type case OCALLFUNC, OCALLINTER, OCALLMETH: - return s.call(n, callNormal) + return s.callAddr(n, callNormal) case ODOTTYPE: v, _ := s.dottype(n, false) if v.Op != ssa.OpLoad { @@ -4669,7 +4980,7 @@ func (s *state) addr(n *Node) *ssa.Value { // canSSA reports whether n is SSA-able. // n must be an ONAME (or an ODOT sequence with an ONAME base). func (s *state) canSSA(n *Node) bool { - if Debug['N'] != 0 { + if Debug.N != 0 { return false } for n.Op == ODOT || (n.Op == OINDEX && n.Left.Type.IsArray()) { @@ -4708,7 +5019,7 @@ func (s *state) canSSA(n *Node) bool { if n.Class() == PPARAM && n.Sym != nil && n.Sym.Name == ".this" { // wrappers generated by genwrapper need to update // the .this pointer in place. - // TODO: treat as a PPARMOUT? + // TODO: treat as a PPARAMOUT? return false } return canSSAType(n.Type) @@ -4780,7 +5091,7 @@ func (s *state) nilCheck(ptr *ssa.Value) { func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value { idx = s.extendIndex(idx, len, kind, bounded) - if bounded || Debug['B'] != 0 { + if bounded || Debug.B != 0 { // If bounded or bounds checking is flag-disabled, then no check necessary, // just return the extended index. // @@ -4909,21 +5220,49 @@ func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value { // The call is added to the end of the current block. // If returns is false, the block is marked as an exit block. func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value { + s.prevCall = nil // Write args to the stack off := Ctxt.FixedFrameSize() + testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f) + var ACArgs []ssa.Param + var ACResults []ssa.Param + var callArgs []*ssa.Value + for _, arg := range args { t := arg.Type off = Rnd(off, t.Alignment()) - ptr := s.constOffPtrSP(t.PtrTo(), off) size := t.Size() - s.store(t, ptr, arg) + ACArgs = append(ACArgs, ssa.Param{Type: t, Offset: int32(off)}) + if testLateExpansion { + callArgs = append(callArgs, arg) + } else { + ptr := s.constOffPtrSP(t.PtrTo(), off) + s.store(t, ptr, arg) + } off += size } off = Rnd(off, int64(Widthreg)) + // Accumulate results types and offsets + offR := off + for _, t := range results { + offR = Rnd(offR, t.Alignment()) + ACResults = append(ACResults, ssa.Param{Type: t, Offset: int32(offR)}) + offR += t.Size() + } + // Issue call - call := s.newValue1A(ssa.OpStaticCall, types.TypeMem, fn, s.mem()) - s.vars[&memVar] = call + var call *ssa.Value + aux := ssa.StaticAuxCall(fn, ACArgs, ACResults) + if testLateExpansion { + callArgs = append(callArgs, s.mem()) + call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux) + call.AddArgs(callArgs...) + s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call) + } else { + call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem()) + s.vars[&memVar] = call + } if !returns { // Finish block @@ -4939,11 +5278,24 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args . // Load results res := make([]*ssa.Value, len(results)) - for i, t := range results { - off = Rnd(off, t.Alignment()) - ptr := s.constOffPtrSP(types.NewPtr(t), off) - res[i] = s.load(t, ptr) - off += t.Size() + if testLateExpansion { + for i, t := range results { + off = Rnd(off, t.Alignment()) + if canSSAType(t) { + res[i] = s.newValue1I(ssa.OpSelectN, t, int64(i), call) + } else { + addr := s.newValue1I(ssa.OpSelectNAddr, types.NewPtr(t), int64(i), call) + res[i] = s.rawLoad(t, addr) + } + off += t.Size() + } + } else { + for i, t := range results { + off = Rnd(off, t.Alignment()) + ptr := s.constOffPtrSP(types.NewPtr(t), off) + res[i] = s.load(t, ptr) + off += t.Size() + } } off = Rnd(off, int64(Widthptr)) @@ -4955,7 +5307,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args . // do *left = right for type t. func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask, leftIsStmt bool) { - s.instrument(t, left, true) + s.instrument(t, left, instrumentWrite) if skip == 0 && (!t.HasPointers() || ssa.IsStackAddr(left)) { // Known to not have write barrier. Store the whole type. @@ -4980,7 +5332,10 @@ func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip ski case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex(): s.store(t, left, right) case t.IsPtrShaped(): - // no scalar fields. + if t.IsPtr() && t.Elem().NotInHeap() { + s.store(t, left, right) // see issue 42032 + } + // otherwise, no scalar fields. case t.IsString(): if skip&skipLen != 0 { return @@ -5024,6 +5379,9 @@ func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip ski func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) { switch { case t.IsPtrShaped(): + if t.IsPtr() && t.Elem().NotInHeap() { + break // see issue 42032 + } s.store(t, left, right) case t.IsString(): ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right) @@ -5057,8 +5415,21 @@ func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) { } } -func (s *state) storeArg(n *Node, t *types.Type, off int64) { - s.storeArgWithBase(n, t, s.sp, off) +// putArg evaluates n for the purpose of passing it as an argument to a function and returns the corresponding Param for the call. +// If forLateExpandedCall is true, it returns the argument value to pass to the call operation. +// If forLateExpandedCall is false, then the value is stored at the specified stack offset, and the returned value is nil. +func (s *state) putArg(n *Node, t *types.Type, off int64, forLateExpandedCall bool) (ssa.Param, *ssa.Value) { + var a *ssa.Value + if forLateExpandedCall { + if !canSSAType(t) { + a = s.newValue2(ssa.OpDereference, t, s.addr(n), s.mem()) + } else { + a = s.expr(n) + } + } else { + s.storeArgWithBase(n, t, s.sp, off) + } + return ssa.Param{Type: t, Offset: int32(off)}, a } func (s *state) storeArgWithBase(n *Node, t *types.Type, base *ssa.Value, off int64) { @@ -5554,7 +5925,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { // Load type out of itab, build interface with existing idata. off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab) typ := s.load(byteptr, off) - idata := s.newValue1(ssa.OpIData, n.Type, iface) + idata := s.newValue1(ssa.OpIData, byteptr, iface) res = s.newValue2(ssa.OpIMake, n.Type, typ, idata) return } @@ -5576,7 +5947,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { bOk.AddEdgeTo(bEnd) bFail.AddEdgeTo(bEnd) s.startBlock(bEnd) - idata := s.newValue1(ssa.OpIData, n.Type, iface) + idata := s.newValue1(ssa.OpIData, byteptr, iface) res = s.newValue2(ssa.OpIMake, n.Type, s.variable(&typVar, byteptr), idata) resok = cond delete(s.vars, &typVar) @@ -5787,9 +6158,7 @@ type SSAGenState struct { // bstart remembers where each block starts (indexed by block ID) bstart []*obj.Prog - // 387 port: maps from SSE registers (REG_X?) to 387 registers (REG_F?) - SSEto387 map[int16]int16 - // Some architectures require a 64-bit temporary for FP-related register shuffling. Examples include x86-387, PPC, and Sparc V8. + // Some architectures require a 64-bit temporary for FP-related register shuffling. Examples include PPC and Sparc V8. ScratchFpMem *Node maxarg int64 // largest frame size for arguments to calls made by the function @@ -5895,7 +6264,7 @@ func emitStackObjects(e *ssafn, pp *Progs) { // Populate the stack object data. // Format must match runtime/stack.go:stackObjectRecord. - x := e.curfn.Func.lsym.Func.StackObjects + x := e.curfn.Func.lsym.Func().StackObjects off := 0 off = duintptr(x, off, uint64(len(vars))) for _, v := range vars { @@ -5932,7 +6301,7 @@ func genssa(f *ssa.Func, pp *Progs) { s.livenessMap = liveness(e, f, pp) emitStackObjects(e, pp) - openDeferInfo := e.curfn.Func.lsym.Func.OpenCodedDeferInfo + openDeferInfo := e.curfn.Func.lsym.Func().OpenCodedDeferInfo if openDeferInfo != nil { // This function uses open-coded defers -- write out the funcdata // info that we computed at the end of genssa. @@ -5956,10 +6325,6 @@ func genssa(f *ssa.Func, pp *Progs) { progToBlock[s.pp.next] = f.Blocks[0] } - if thearch.Use387 { - s.SSEto387 = map[int16]int16{} - } - s.ScratchFpMem = e.scratchFpMem if Ctxt.Flag_locationlists { @@ -6004,7 +6369,7 @@ func genssa(f *ssa.Func, pp *Progs) { // instruction. We won't use the actual liveness map on a // control instruction. Just mark it something that is // preemptible, unless this function is "all unsafe". - s.pp.nextLive = LivenessIndex{-1, -1, allUnsafe(f)} + s.pp.nextLive = LivenessIndex{-1, allUnsafe(f)} // Emit values in block thearch.SSAMarkMoves(&s, b) @@ -6082,7 +6447,7 @@ func genssa(f *ssa.Func, pp *Progs) { } // Emit control flow instructions for block var next *ssa.Block - if i < len(f.Blocks)-1 && Debug['N'] == 0 { + if i < len(f.Blocks)-1 && Debug.N == 0 { // If -N, leave next==nil so every block with successors // ends in a JMP (except call blocks - plive doesn't like // select{send,recv} followed by a JMP call). Helps keep @@ -6141,7 +6506,7 @@ func genssa(f *ssa.Func, pp *Progs) { // some of the inline marks. // Use this instruction instead. p.Pos = p.Pos.WithIsStmt() // promote position to a statement - pp.curfn.Func.lsym.Func.AddInlMark(p, inlMarks[m]) + pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[m]) // Make the inline mark a real nop, so it doesn't generate any code. m.As = obj.ANOP m.Pos = src.NoXPos @@ -6153,7 +6518,7 @@ func genssa(f *ssa.Func, pp *Progs) { // Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction). for _, p := range inlMarkList { if p.As != obj.ANOP { - pp.curfn.Func.lsym.Func.AddInlMark(p, inlMarks[p]) + pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[p]) } } } @@ -6353,6 +6718,9 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) { } // Add symbol's offset from its base register. switch n := v.Aux.(type) { + case *ssa.AuxCall: + a.Name = obj.NAME_EXTERN + a.Sym = n.Fn case *obj.LSym: a.Name = obj.NAME_EXTERN a.Sym = n @@ -6387,7 +6755,7 @@ func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo } else { lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx) } - if bounded || Debug['B'] != 0 { + if bounded || Debug.B != 0 { return lo } bNext := s.f.NewBlock(ssa.BlockPlain) @@ -6539,10 +6907,10 @@ func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog { } else { p.Pos = v.Pos.WithNotStmt() } - if sym, ok := v.Aux.(*obj.LSym); ok { + if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil { p.To.Type = obj.TYPE_MEM p.To.Name = obj.NAME_EXTERN - p.To.Sym = sym + p.To.Sym = sym.Fn } else { // TODO(mdempsky): Can these differences be eliminated? switch thearch.LinkArch.Family { @@ -6565,12 +6933,14 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) { idx := s.livenessMap.Get(v) if !idx.StackMapValid() { // See Liveness.hasStackMap. - if sym, _ := v.Aux.(*obj.LSym); !(sym == typedmemclr || sym == typedmemmove) { + if sym, ok := v.Aux.(*ssa.AuxCall); !ok || !(sym.Fn == typedmemclr || sym.Fn == typedmemmove) { Fatalf("missing stack map index for %v", v.LongString()) } } - if sym, _ := v.Aux.(*obj.LSym); sym == Deferreturn { + call, ok := v.Aux.(*ssa.AuxCall) + + if ok && call.Fn == Deferreturn { // Deferred calls will appear to be returning to // the CALL deferreturn(SB) that we are about to emit. // However, the stack trace code will show the line @@ -6582,11 +6952,11 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) { thearch.Ginsnopdefer(s.pp) } - if sym, ok := v.Aux.(*obj.LSym); ok { + if ok { // Record call graph information for nowritebarrierrec // analysis. if nowritebarrierrecCheck != nil { - nowritebarrierrecCheck.recordCall(s.pp.curfn, sym, v.Pos) + nowritebarrierrecCheck.recordCall(s.pp.curfn, call.Fn, v.Pos) } } @@ -6659,56 +7029,38 @@ func (e *ssafn) Auto(pos src.XPos, t *types.Type) ssa.GCNode { } func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { - n := name.N.(*Node) ptrType := types.NewPtr(types.Types[TUINT8]) lenType := types.Types[TINT] - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Split this string up into two separate variables. - p := e.splitSlot(&name, ".ptr", 0, ptrType) - l := e.splitSlot(&name, ".len", ptrType.Size(), lenType) - return p, l - } - // Return the two parts of the larger variable. - return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)} + // Split this string up into two separate variables. + p := e.SplitSlot(&name, ".ptr", 0, ptrType) + l := e.SplitSlot(&name, ".len", ptrType.Size(), lenType) + return p, l } func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) u := types.Types[TUINTPTR] t := types.NewPtr(types.Types[TUINT8]) - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Split this interface up into two separate variables. - f := ".itab" - if n.Type.IsEmptyInterface() { - f = ".type" - } - c := e.splitSlot(&name, f, 0, u) // see comment in plive.go:onebitwalktype1. - d := e.splitSlot(&name, ".data", u.Size(), t) - return c, d + // Split this interface up into two separate variables. + f := ".itab" + if n.Type.IsEmptyInterface() { + f = ".type" } - // Return the two parts of the larger variable. - return ssa.LocalSlot{N: n, Type: u, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + int64(Widthptr)} + c := e.SplitSlot(&name, f, 0, u) // see comment in plive.go:onebitwalktype1. + d := e.SplitSlot(&name, ".data", u.Size(), t) + return c, d } func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) { - n := name.N.(*Node) ptrType := types.NewPtr(name.Type.Elem()) lenType := types.Types[TINT] - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Split this slice up into three separate variables. - p := e.splitSlot(&name, ".ptr", 0, ptrType) - l := e.splitSlot(&name, ".len", ptrType.Size(), lenType) - c := e.splitSlot(&name, ".cap", ptrType.Size()+lenType.Size(), lenType) - return p, l, c - } - // Return the three parts of the larger variable. - return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, - ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)}, - ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(2*Widthptr)} + p := e.SplitSlot(&name, ".ptr", 0, ptrType) + l := e.SplitSlot(&name, ".len", ptrType.Size(), lenType) + c := e.SplitSlot(&name, ".cap", ptrType.Size()+lenType.Size(), lenType) + return p, l, c } func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { - n := name.N.(*Node) s := name.Type.Size() / 2 var t *types.Type if s == 8 { @@ -6716,53 +7068,30 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) } else { t = types.Types[TFLOAT32] } - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Split this complex up into two separate variables. - r := e.splitSlot(&name, ".real", 0, t) - i := e.splitSlot(&name, ".imag", t.Size(), t) - return r, i - } - // Return the two parts of the larger variable. - return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + s} + r := e.SplitSlot(&name, ".real", 0, t) + i := e.SplitSlot(&name, ".imag", t.Size(), t) + return r, i } func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { - n := name.N.(*Node) var t *types.Type if name.Type.IsSigned() { t = types.Types[TINT32] } else { t = types.Types[TUINT32] } - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Split this int64 up into two separate variables. - if thearch.LinkArch.ByteOrder == binary.BigEndian { - return e.splitSlot(&name, ".hi", 0, t), e.splitSlot(&name, ".lo", t.Size(), types.Types[TUINT32]) - } - return e.splitSlot(&name, ".hi", t.Size(), t), e.splitSlot(&name, ".lo", 0, types.Types[TUINT32]) - } - // Return the two parts of the larger variable. if thearch.LinkArch.ByteOrder == binary.BigEndian { - return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: types.Types[TUINT32], Off: name.Off + 4} + return e.SplitSlot(&name, ".hi", 0, t), e.SplitSlot(&name, ".lo", t.Size(), types.Types[TUINT32]) } - return ssa.LocalSlot{N: n, Type: t, Off: name.Off + 4}, ssa.LocalSlot{N: n, Type: types.Types[TUINT32], Off: name.Off} + return e.SplitSlot(&name, ".hi", t.Size(), t), e.SplitSlot(&name, ".lo", 0, types.Types[TUINT32]) } func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot { - n := name.N.(*Node) st := name.Type - ft := st.FieldType(i) - var offset int64 - for f := 0; f < i; f++ { - offset += st.FieldType(f).Size() - } - if n.Class() == PAUTO && !n.Name.Addrtaken() { - // Note: the _ field may appear several times. But - // have no fear, identically-named but distinct Autos are - // ok, albeit maybe confusing for a debugger. - return e.splitSlot(&name, "."+st.FieldName(i), offset, ft) - } - return ssa.LocalSlot{N: n, Type: ft, Off: name.Off + st.FieldOff(i)} + // Note: the _ field may appear several times. But + // have no fear, identically-named but distinct Autos are + // ok, albeit maybe confusing for a debugger. + return e.SplitSlot(&name, "."+st.FieldName(i), st.FieldOff(i), st.FieldType(i)) } func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot { @@ -6772,19 +7101,23 @@ func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot { e.Fatalf(n.Pos, "bad array size") } et := at.Elem() - if n.Class() == PAUTO && !n.Name.Addrtaken() { - return e.splitSlot(&name, "[0]", 0, et) - } - return ssa.LocalSlot{N: n, Type: et, Off: name.Off} + return e.SplitSlot(&name, "[0]", 0, et) } func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym { return itabsym(it, offset) } -// splitSlot returns a slot representing the data of parent starting at offset. -func (e *ssafn) splitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot { - s := &types.Sym{Name: parent.N.(*Node).Sym.Name + suffix, Pkg: localpkg} +// SplitSlot returns a slot representing the data of parent starting at offset. +func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot { + node := parent.N.(*Node) + + if node.Class() != PAUTO || node.Name.Addrtaken() { + // addressed things and non-autos retain their parents (i.e., cannot truly be split) + return ssa.LocalSlot{N: node, Type: t, Off: parent.Off + offset} + } + + s := &types.Sym{Name: node.Sym.Name + suffix, Pkg: localpkg} n := &Node{ Name: new(Name), diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 8fa3fca50f..defefd76b3 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -96,7 +96,7 @@ func flusherrors() { } func hcrash() { - if Debug['h'] != 0 { + if Debug.h != 0 { flusherrors() if outfile != "" { os.Remove(outfile) @@ -107,7 +107,7 @@ func hcrash() { } func linestr(pos src.XPos) string { - return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1) + return Ctxt.OutermostPos(pos).Format(Debug.C == 0, Debug.L == 1) } // lasterror keeps track of the most recently issued error. @@ -153,7 +153,7 @@ func yyerrorl(pos src.XPos, format string, args ...interface{}) { hcrash() nerrors++ - if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { + if nsavederrors+nerrors >= 10 && Debug.e == 0 { flusherrors() fmt.Printf("%v: too many errors\n", linestr(pos)) errorexit() @@ -175,7 +175,7 @@ func Warn(fmt_ string, args ...interface{}) { func Warnl(line src.XPos, fmt_ string, args ...interface{}) { adderr(line, fmt_, args...) - if Debug['m'] != 0 { + if Debug.m != 0 { flusherrors() } } @@ -222,7 +222,7 @@ func hasUniquePos(n *Node) bool { } if !n.Pos.IsKnown() { - if Debug['K'] != 0 { + if Debug.K != 0 { Warn("setlineno: unknown position (line 0)") } return false @@ -348,7 +348,7 @@ func newname(s *types.Sym) *Node { return n } -// newname returns a new ONAME Node associated with symbol s at position pos. +// newnamel returns a new ONAME Node associated with symbol s at position pos. // The caller is responsible for setting n.Name.Curfn. func newnamel(pos src.XPos, s *types.Sym) *Node { if s == nil { @@ -546,22 +546,19 @@ func methtype(t *types.Type) *types.Type { // Is type src assignment compatible to type dst? // If so, return op code to use in conversion. -// If not, return OXXX. -func assignop(src, dst *types.Type, why *string) Op { - if why != nil { - *why = "" - } - +// If not, return OXXX. In this case, the string return parameter may +// hold a reason why. In all other cases, it'll be the empty string. +func assignop(src, dst *types.Type) (Op, string) { if src == dst { - return OCONVNOP + return OCONVNOP, "" } if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { - return OXXX + return OXXX, "" } // 1. src type is identical to dst. if types.Identical(src, dst) { - return OCONVNOP + return OCONVNOP, "" } // 2. src and dst have identical underlying types @@ -575,13 +572,13 @@ func assignop(src, dst *types.Type, why *string) Op { if src.IsEmptyInterface() { // Conversion between two empty interfaces // requires no code. - return OCONVNOP + return OCONVNOP, "" } if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() { // Conversion between two types, at least one unnamed, // needs no conversion. The exception is nonempty interfaces // which need to have their itab updated. - return OCONVNOP + return OCONVNOP, "" } } @@ -590,49 +587,47 @@ func assignop(src, dst *types.Type, why *string) Op { var missing, have *types.Field var ptr int if implements(src, dst, &missing, &have, &ptr) { - return OCONVIFACE + return OCONVIFACE, "" } // we'll have complained about this method anyway, suppress spurious messages. if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) { - return OCONVIFACE + return OCONVIFACE, "" } - if why != nil { - if isptrto(src, TINTER) { - *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) - } else if have != nil && have.Sym == missing.Sym && have.Nointerface() { - *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) - } else if have != nil && have.Sym == missing.Sym { - *why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+ - "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) - } else if ptr != 0 { - *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) - } else if have != nil { - *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+ - "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) - } else { - *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) - } + var why string + if isptrto(src, TINTER) { + why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) + } else if have != nil && have.Sym == missing.Sym && have.Nointerface() { + why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) + } else if have != nil && have.Sym == missing.Sym { + why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+ + "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) + } else if ptr != 0 { + why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) + } else if have != nil { + why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+ + "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) + } else { + why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) } - return OXXX + return OXXX, why } if isptrto(dst, TINTER) { - if why != nil { - *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) - } - return OXXX + why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) + return OXXX, why } if src.IsInterface() && dst.Etype != TBLANK { var missing, have *types.Field var ptr int - if why != nil && implements(dst, src, &missing, &have, &ptr) { - *why = ": need type assertion" + var why string + if implements(dst, src, &missing, &have, &ptr) { + why = ": need type assertion" } - return OXXX + return OXXX, why } // 4. src is a bidirectional channel value, dst is a channel type, @@ -640,7 +635,7 @@ func assignop(src, dst *types.Type, why *string) Op { // either src or dst is not a named type. if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() { if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) { - return OCONVNOP + return OCONVNOP, "" } } @@ -653,7 +648,7 @@ func assignop(src, dst *types.Type, why *string) Op { TCHAN, TINTER, TSLICE: - return OCONVNOP + return OCONVNOP, "" } } @@ -661,26 +656,23 @@ func assignop(src, dst *types.Type, why *string) Op { // 7. Any typed value can be assigned to the blank identifier. if dst.Etype == TBLANK { - return OCONVNOP + return OCONVNOP, "" } - return OXXX + return OXXX, "" } // Can we convert a value of type src to a value of type dst? // If so, return op code to use in conversion (maybe OCONVNOP). -// If not, return OXXX. +// If not, return OXXX. In this case, the string return parameter may +// hold a reason why. In all other cases, it'll be the empty string. // srcConstant indicates whether the value of type src is a constant. -func convertop(srcConstant bool, src, dst *types.Type, why *string) Op { - if why != nil { - *why = "" - } - +func convertop(srcConstant bool, src, dst *types.Type) (Op, string) { if src == dst { - return OCONVNOP + return OCONVNOP, "" } if src == nil || dst == nil { - return OXXX + return OXXX, "" } // Conversions from regular to go:notinheap are not allowed @@ -688,23 +680,19 @@ func convertop(srcConstant bool, src, dst *types.Type, why *string) Op { // rules. // (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't. if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() { - if why != nil { - *why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem()) - } - return OXXX + why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem()) + return OXXX, why } // (b) Disallow string to []T where T is go:notinheap. if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) { - if why != nil { - *why = fmt.Sprintf(":\n\t%v is go:notinheap", dst.Elem()) - } - return OXXX + why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem()) + return OXXX, why } // 1. src can be assigned to dst. - op := assignop(src, dst, why) + op, why := assignop(src, dst) if op != OXXX { - return op + return op, why } // The rules for interfaces are no different in conversions @@ -712,60 +700,57 @@ func convertop(srcConstant bool, src, dst *types.Type, why *string) Op { // with the good message from assignop. // Otherwise clear the error. if src.IsInterface() || dst.IsInterface() { - return OXXX - } - if why != nil { - *why = "" + return OXXX, why } // 2. Ignoring struct tags, src and dst have identical underlying types. if types.IdenticalIgnoreTags(src.Orig, dst.Orig) { - return OCONVNOP + return OCONVNOP, "" } // 3. src and dst are unnamed pointer types and, ignoring struct tags, // their base types have identical underlying types. if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil { if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) { - return OCONVNOP + return OCONVNOP, "" } } // 4. src and dst are both integer or floating point types. if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) { if simtype[src.Etype] == simtype[dst.Etype] { - return OCONVNOP + return OCONVNOP, "" } - return OCONV + return OCONV, "" } // 5. src and dst are both complex types. if src.IsComplex() && dst.IsComplex() { if simtype[src.Etype] == simtype[dst.Etype] { - return OCONVNOP + return OCONVNOP, "" } - return OCONV + return OCONV, "" } // Special case for constant conversions: any numeric // conversion is potentially okay. We'll validate further // within evconst. See #38117. if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) { - return OCONV + return OCONV, "" } // 6. src is an integer or has type []byte or []rune // and dst is a string type. if src.IsInteger() && dst.IsString() { - return ORUNESTR + return ORUNESTR, "" } if src.IsSlice() && dst.IsString() { if src.Elem().Etype == types.Bytetype.Etype { - return OBYTES2STR + return OBYTES2STR, "" } if src.Elem().Etype == types.Runetype.Etype { - return ORUNES2STR + return ORUNES2STR, "" } } @@ -773,21 +758,21 @@ func convertop(srcConstant bool, src, dst *types.Type, why *string) Op { // String to slice. if src.IsString() && dst.IsSlice() { if dst.Elem().Etype == types.Bytetype.Etype { - return OSTR2BYTES + return OSTR2BYTES, "" } if dst.Elem().Etype == types.Runetype.Etype { - return OSTR2RUNES + return OSTR2RUNES, "" } } // 8. src is a pointer or uintptr and dst is unsafe.Pointer. - if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { - return OCONVNOP + if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() { + return OCONVNOP, "" } // 9. src is unsafe.Pointer and dst is a pointer or uintptr. - if src.Etype == TUNSAFEPTR && (dst.IsPtr() || dst.Etype == TUINTPTR) { - return OCONVNOP + if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) { + return OCONVNOP, "" } // src is map and dst is a pointer to corresponding hmap. @@ -795,10 +780,10 @@ func convertop(srcConstant bool, src, dst *types.Type, why *string) Op { // go gc maps are implemented as a pointer to a hmap struct. if src.Etype == TMAP && dst.IsPtr() && src.MapType().Hmap == dst.Elem() { - return OCONVNOP + return OCONVNOP, "" } - return OXXX + return OXXX, "" } func assignconv(n *Node, t *types.Type, context string) *Node { @@ -825,7 +810,7 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node { // Convert ideal bool from comparison to plain bool // if the next step is non-bool (like interface{}). - if n.Type == types.Idealbool && !t.IsBoolean() { + if n.Type == types.UntypedBool && !t.IsBoolean() { if n.Op == ONAME || n.Op == OLITERAL { r := nod(OCONVNOP, n, nil) r.Type = types.Types[TBOOL] @@ -839,8 +824,7 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node { return n } - var why string - op := assignop(n.Type, t, &why) + op, why := assignop(n.Type, t) if op == OXXX { yyerror("cannot use %L as type %v in %s%s", n, t, context(), why) op = OCONV @@ -928,16 +912,20 @@ func (o Op) IsSlice3() bool { return false } -// slicePtrLen extracts the pointer and length from a slice. +// backingArrayPtrLen extracts the pointer and length from a slice or string. // This constructs two nodes referring to n, so n must be a cheapexpr. -func (n *Node) slicePtrLen() (ptr, len *Node) { +func (n *Node) backingArrayPtrLen() (ptr, len *Node) { var init Nodes c := cheapexpr(n, &init) if c != n || init.Len() != 0 { - Fatalf("slicePtrLen not cheap: %v", n) + Fatalf("backingArrayPtrLen not cheap: %v", n) } ptr = nod(OSPTR, n, nil) - ptr.Type = n.Type.Elem().PtrTo() + if n.Type.IsString() { + ptr.Type = types.Types[TUINT8].PtrTo() + } else { + ptr.Type = n.Type.Elem().PtrTo() + } len = nod(OLEN, n, nil) len.Type = types.Types[TINT] return ptr, len @@ -1036,25 +1024,24 @@ func calcHasCall(n *Node) bool { return false } -func badtype(op Op, tl *types.Type, tr *types.Type) { - fmt_ := "" +func badtype(op Op, tl, tr *types.Type) { + var s string if tl != nil { - fmt_ += fmt.Sprintf("\n\t%v", tl) + s += fmt.Sprintf("\n\t%v", tl) } if tr != nil { - fmt_ += fmt.Sprintf("\n\t%v", tr) + s += fmt.Sprintf("\n\t%v", tr) } // common mistake: *struct and *interface. if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() { if tl.Elem().IsStruct() && tr.Elem().IsInterface() { - fmt_ += "\n\t(*struct vs *interface)" + s += "\n\t(*struct vs *interface)" } else if tl.Elem().IsInterface() && tr.Elem().IsStruct() { - fmt_ += "\n\t(*interface vs *struct)" + s += "\n\t(*interface vs *struct)" } } - s := fmt_ yyerror("illegal types for operand: %v%s", op, s) } @@ -1519,7 +1506,7 @@ func structargs(tl *types.Type, mustname bool) []*Node { // method - M func (t T)(), a TFIELD type struct // newnam - the eventual mangled name of this function func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { - if false && Debug['r'] != 0 { + if false && Debug.r != 0 { fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) } @@ -1592,7 +1579,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { fn.Nbody.Append(call) } - if false && Debug['r'] != 0 { + if false && Debug.r != 0 { dumplist("genwrapper body", fn.Nbody) } @@ -1615,7 +1602,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { escapeFuncs([]*Node{fn}, false) Curfn = nil - funccompile(fn) + xtop = append(xtop, fn) } func paramNnames(ft *types.Type) []*Node { @@ -1733,7 +1720,7 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool // the method does not exist for value types. rcvr := tm.Type.Recv().Type if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) { - if false && Debug['r'] != 0 { + if false && Debug.r != 0 { yyerror("interface pointer mismatch") } @@ -1867,8 +1854,10 @@ func isdirectiface(t *types.Type) bool { } switch t.Etype { - case TPTR, - TCHAN, + case TPTR: + // Pointers to notinheap types must be stored indirectly. See issue 42076. + return !t.Elem().NotInHeap() + case TCHAN, TMAP, TFUNC, TUNSAFEPTR: @@ -1917,3 +1906,13 @@ func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node { ind.SetBounded(true) return ind } + +// typePos returns the position associated with t. +// This is where t was declared or where it appeared as a type expression. +func typePos(t *types.Type) src.XPos { + n := asNode(t.Nod) + if n == nil || !n.Pos.IsKnown() { + Fatalf("bad type: %v", t) + } + return n.Pos +} diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 138b0acc53..8d9fbe300e 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -189,16 +189,19 @@ func typecheckExprSwitch(n *Node) { continue } - switch { - case nilonly != "" && !n1.isNil(): + if nilonly != "" && !n1.isNil() { yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left) - case t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type): + } else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) { yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1) - case assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0: - if n.Left != nil { - yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t) - } else { - yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type) + } else { + op1, _ := assignop(n1.Type, t) + op2, _ := assignop(t, n1.Type) + if op1 == OXXX && op2 == OXXX { + if n.Left != nil { + yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t) + } else { + yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type) + } } } @@ -358,8 +361,8 @@ func (s *exprSwitch) flush() { // all we need here is consistency. We respect this // sorting below. sort.Slice(cc, func(i, j int) bool { - si := strlit(cc[i].lo) - sj := strlit(cc[j].lo) + si := cc[i].lo.StringVal() + sj := cc[j].lo.StringVal() if len(si) != len(sj) { return len(si) < len(sj) } @@ -368,7 +371,7 @@ func (s *exprSwitch) flush() { // runLen returns the string length associated with a // particular run of exprClauses. - runLen := func(run []exprClause) int64 { return int64(len(strlit(run[0].lo))) } + runLen := func(run []exprClause) int64 { return int64(len(run[0].lo.StringVal())) } // Collapse runs of consecutive strings with the same length. var runs [][]exprClause @@ -405,7 +408,7 @@ func (s *exprSwitch) flush() { merged := cc[:1] for _, c := range cc[1:] { last := &merged[len(merged)-1] - if last.jmp == c.jmp && last.hi.Int64()+1 == c.lo.Int64() { + if last.jmp == c.jmp && last.hi.Int64Val()+1 == c.lo.Int64Val() { last.hi = c.lo } else { merged = append(merged, c) @@ -440,7 +443,7 @@ func (c *exprClause) test(exprname *Node) *Node { // Optimize "switch true { ...}" and "switch false { ... }". if Isconst(exprname, CTBOOL) && !c.lo.Type.IsInterface() { - if exprname.Val().U.(bool) { + if exprname.BoolVal() { return c.lo } else { return nodl(c.pos, ONOT, c.lo, nil) diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index 47e5e59156..43358333b8 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -142,7 +142,7 @@ const ( _, _ // second nodeInitorder bit _, nodeHasBreak _, nodeNoInline // used internally by inliner to indicate that a function call should not be inlined; set for OCALLFUNC and OCALLMETH only - _, nodeImplicit // implicit OADDR or ODEREF; ++/-- statement represented as OASOP; or ANDNOT lowered to OAND + _, nodeImplicit // implicit OADDR or ODEREF; ++/-- statement represented as OASOP _, nodeIsDDD // is the argument variadic _, nodeDiag // already printed error about this _, nodeColas // OAS resulting from := @@ -247,7 +247,7 @@ func (n *Node) Val() Val { // SetVal sets the Val for the node, which must not have been used with SetOpt. func (n *Node) SetVal(v Val) { if n.HasOpt() { - Debug['h'] = 1 + Debug.h = 1 Dump("have Opt", n) Fatalf("have Opt") } @@ -270,7 +270,7 @@ func (n *Node) SetOpt(x interface{}) { return } if n.HasVal() { - Debug['h'] = 1 + Debug.h = 1 Dump("have Val", n) Fatalf("have Val") } @@ -344,14 +344,22 @@ func (n *Node) CanBeAnSSASym() { // Name holds Node fields used only by named nodes (ONAME, OTYPE, OPACK, OLABEL, some OLITERAL). type Name struct { - Pack *Node // real package for import . names - Pkg *types.Pkg // pkg for OPACK nodes - Defn *Node // initializing assignment - Curfn *Node // function for local variables - Param *Param // additional fields for ONAME, OTYPE - Decldepth int32 // declaration loop depth, increased for every loop or label - Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. - flags bitset16 + Pack *Node // real package for import . names + Pkg *types.Pkg // pkg for OPACK nodes + // For a local variable (not param) or extern, the initializing assignment (OAS or OAS2). + // For a closure var, the ONAME node of the outer captured variable + Defn *Node + // The ODCLFUNC node (for a static function/method or a closure) in which + // local variable or param is declared. + Curfn *Node + Param *Param // additional fields for ONAME, OTYPE + Decldepth int32 // declaration loop depth, increased for every loop or label + // Unique number for ONAME nodes within a function. Function outputs + // (results) are numbered starting at one, followed by function inputs + // (parameters), and then local variables. Vargen is used to distinguish + // local variables/params with the same name. + Vargen int32 + flags bitset16 } const ( @@ -359,7 +367,6 @@ const ( nameReadonly nameByval // is the variable captured by value or by reference nameNeedzero // if it contains pointers, needs to be zeroed on function entry - nameKeepalive // mark value live across unknown assembly call nameAutoTemp // is the variable a temporary (implies no dwarf info. reset if escapes to heap) nameUsed // for variable declared and not used error nameIsClosureVar // PAUTOHEAP closure pseudo-variable; original at n.Name.Defn @@ -376,7 +383,6 @@ func (n *Name) Captured() bool { return n.flags&nameCaptured != 0 } func (n *Name) Readonly() bool { return n.flags&nameReadonly != 0 } func (n *Name) Byval() bool { return n.flags&nameByval != 0 } func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 } -func (n *Name) Keepalive() bool { return n.flags&nameKeepalive != 0 } func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 } func (n *Name) Used() bool { return n.flags&nameUsed != 0 } func (n *Name) IsClosureVar() bool { return n.flags&nameIsClosureVar != 0 } @@ -392,7 +398,6 @@ func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) } func (n *Name) SetReadonly(b bool) { n.flags.set(nameReadonly, b) } func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) } func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) } -func (n *Name) SetKeepalive(b bool) { n.flags.set(nameKeepalive, b) } func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) } func (n *Name) SetUsed(b bool) { n.flags.set(nameUsed, b) } func (n *Name) SetIsClosureVar(b bool) { n.flags.set(nameIsClosureVar, b) } @@ -463,14 +468,14 @@ type Param struct { // x1 := xN.Defn // x1.Innermost = xN.Outer // - // We leave xN.Innermost set so that we can still get to the original + // We leave x1.Innermost set so that we can still get to the original // variable quickly. Not shown here, but once we're // done parsing a function and no longer need xN.Outer for the - // lexical x reference links as described above, closurebody + // lexical x reference links as described above, funcLit // recomputes xN.Outer as the semantic x reference link tree, // even filling in x in intermediate closures that might not // have mentioned it along the way to inner closures that did. - // See closurebody for details. + // See funcLit for details. // // During the eventual compilation, then, for closure variables we have: // @@ -483,11 +488,87 @@ type Param struct { Innermost *Node Outer *Node - // OTYPE - // - // TODO: Should Func pragmas also be stored on the Name? - Pragma PragmaFlag - Alias bool // node is alias for Ntype (only used when type-checking ODCLTYPE) + // OTYPE & ONAME //go:embed info, + // sharing storage to reduce gc.Param size. + // Extra is nil, or else *Extra is a *paramType or an *embedFileList. + Extra *interface{} +} + +type paramType struct { + flag PragmaFlag + alias bool +} + +type embedFileList []string + +// Pragma returns the PragmaFlag for p, which must be for an OTYPE. +func (p *Param) Pragma() PragmaFlag { + if p.Extra == nil { + return 0 + } + return (*p.Extra).(*paramType).flag +} + +// SetPragma sets the PragmaFlag for p, which must be for an OTYPE. +func (p *Param) SetPragma(flag PragmaFlag) { + if p.Extra == nil { + if flag == 0 { + return + } + p.Extra = new(interface{}) + *p.Extra = ¶mType{flag: flag} + return + } + (*p.Extra).(*paramType).flag = flag +} + +// Alias reports whether p, which must be for an OTYPE, is a type alias. +func (p *Param) Alias() bool { + if p.Extra == nil { + return false + } + t, ok := (*p.Extra).(*paramType) + if !ok { + return false + } + return t.alias +} + +// SetAlias sets whether p, which must be for an OTYPE, is a type alias. +func (p *Param) SetAlias(alias bool) { + if p.Extra == nil { + if !alias { + return + } + p.Extra = new(interface{}) + *p.Extra = ¶mType{alias: alias} + return + } + (*p.Extra).(*paramType).alias = alias +} + +// EmbedFiles returns the list of embedded files for p, +// which must be for an ONAME var. +func (p *Param) EmbedFiles() []string { + if p.Extra == nil { + return nil + } + return *(*p.Extra).(*embedFileList) +} + +// SetEmbedFiles sets the list of embedded files for p, +// which must be for an ONAME var. +func (p *Param) SetEmbedFiles(list []string) { + if p.Extra == nil { + if len(list) == 0 { + return + } + f := embedFileList(list) + p.Extra = new(interface{}) + *p.Extra = &f + return + } + *(*p.Extra).(*embedFileList) = list } // Functions @@ -535,10 +616,16 @@ type Param struct { // Func holds Node fields used only with function-like nodes. type Func struct { Shortname *types.Sym - Enter Nodes // for example, allocate and initialize memory for escaping parameters - Exit Nodes - Cvars Nodes // closure params - Dcl []*Node // autodcl for this func/closure + // Extra entry code for the function. For example, allocate and initialize + // memory for escaping parameters. However, just for OCLOSURE, Enter is a + // list of ONAME nodes of captured variables + Enter Nodes + Exit Nodes + // ONAME nodes for closure params, each should have closurevar set + Cvars Nodes + // ONAME nodes for all params/locals for this func/closure, does NOT + // include closurevars until transformclosure runs. + Dcl []*Node // Parents records the parent scope of each scope within a // function. The root scope (0) has no parent, so the i'th @@ -557,8 +644,8 @@ type Func struct { DebugInfo *ssa.FuncDebug Ntype *Node // signature Top int // top context (ctxCallee, etc) - Closure *Node // OCLOSURE <-> ODCLFUNC - Nname *Node + Closure *Node // OCLOSURE <-> ODCLFUNC (see header comment above) + Nname *Node // The ONAME node associated with an ODCLFUNC (both have same Type) lsym *obj.LSym Inl *Inline @@ -607,6 +694,8 @@ const ( funcWrapper // is method wrapper funcNeedctxt // function uses context register (has closure variables) funcReflectMethod // function calls reflect.Type.Method or MethodByName + // true if closure inside a function; false if a simple function or a + // closure in a global variable initialization funcIsHiddenClosure funcHasDefer // contains a defer statement funcNilCheckDisabled // disable nil checks when compiling this function @@ -658,8 +747,10 @@ const ( OXXX Op = iota // names - ONAME // var or func name - ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc } + ONAME // var or func name + // Unnamed arg or return value: f(int, string) (int, error) { etc } + // Also used for a qualified package identifier that hasn't been resolved yet. + ONONAME OTYPE // type name OPACK // import OLITERAL // literal @@ -679,19 +770,24 @@ const ( OSTR2BYTES // Type(Left) (Type is []byte, Left is a string) OSTR2BYTESTMP // Type(Left) (Type is []byte, Left is a string, ephemeral) OSTR2RUNES // Type(Left) (Type is []rune, Left is a string) - OAS // Left = Right or (if Colas=true) Left := Right - OAS2 // List = Rlist (x, y, z = a, b, c) - OAS2DOTTYPE // List = Right (x, ok = I.(int)) - OAS2FUNC // List = Right (x, y = f()) - OAS2MAPR // List = Right (x, ok = m["foo"]) - OAS2RECV // List = Right (x, ok = <-c) - OASOP // Left Etype= Right (x += y) - OCALL // Left(List) (function call, method call or type conversion) + // Left = Right or (if Colas=true) Left := Right + // If Colas, then Ninit includes a DCL node for Left. + OAS + // List = Rlist (x, y, z = a, b, c) or (if Colas=true) List := Rlist + // If Colas, then Ninit includes DCL nodes for List + OAS2 + OAS2DOTTYPE // List = Right (x, ok = I.(int)) + OAS2FUNC // List = Right (x, y = f()) + OAS2MAPR // List = Right (x, ok = m["foo"]) + OAS2RECV // List = Right (x, ok = <-c) + OASOP // Left Etype= Right (x += y) + OCALL // Left(List) (function call, method call or type conversion) // OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure. // Prior to walk, they are: Left(List), where List is all regular arguments. // After walk, List is a series of assignments to temporaries, // and Rlist is an updated set of arguments. + // Nbody is all OVARLIVE nodes that are attached to OCALLxxx. // TODO(josharian/khr): Use Ninit instead of List for the assignments to temporaries. See CL 114797. OCALLFUNC // Left(List/Rlist) (function call f(args)) OCALLMETH // Left(List/Rlist) (direct method call x.Method(args)) @@ -699,7 +795,7 @@ const ( OCALLPART // Left.Right (method expression x.Method, not called) OCAP // cap(Left) OCLOSE // close(Left) - OCLOSURE // func Type { Body } (func literal) + OCLOSURE // func Type { Func.Closure.Nbody } (func literal) OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) OMAPLIT // Type{List} (composite literal, Type is map) OSTRUCTLIT // Type{List} (composite literal, Type is struct) @@ -718,7 +814,7 @@ const ( ODCLCONST // const pi = 3.14 ODCLTYPE // type Int int or type Int = int - ODELETE // delete(Left, Right) + ODELETE // delete(List) ODOT // Left.Sym (Left is of struct type) ODOTPTR // Left.Sym (Left is of pointer to struct type) ODOTMETH // Left.Sym (Left is non-interface, Right is method name) @@ -789,9 +885,14 @@ const ( OSIZEOF // unsafe.Sizeof(Left) // statements - OBLOCK // { List } (block of code) - OBREAK // break [Sym] - OCASE // case List: Nbody (List==nil means default) + OBLOCK // { List } (block of code) + OBREAK // break [Sym] + // OCASE: case List: Nbody (List==nil means default) + // For OTYPESW, List is a OTYPE node for the specified type (or OLITERAL + // for nil), and, if a type-switch variable is specified, Rlist is an + // ONAME for the version of the type-switch variable with the specified + // type. + OCASE OCONTINUE // continue [Sym] ODEFER // defer Left (Left must be call) OEMPTY // no-op (empty statement) @@ -815,15 +916,19 @@ const ( ORETURN // return List OSELECT // select { List } (List is list of OCASE) OSWITCH // switch Ninit; Left { List } (List is a list of OCASE) - OTYPESW // Left = Right.(type) (appears as .Left of OSWITCH) + // OTYPESW: Left := Right.(type) (appears as .Left of OSWITCH) + // Left is nil if there is no type-switch variable + OTYPESW // types OTCHAN // chan int OTMAP // map[string]int OTSTRUCT // struct{} OTINTER // interface{} - OTFUNC // func() - OTARRAY // []int, [8]int, [N]int or [...]int + // OTFUNC: func() - Left is receiver field, List is list of param fields, Rlist is + // list of result fields. + OTFUNC + OTARRAY // []int, [8]int, [N]int or [...]int // misc ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index dec4b96fc4..c0b05035f0 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -6,7 +6,6 @@ package gc import ( "cmd/compile/internal/types" - "cmd/internal/objabi" "fmt" "strings" ) @@ -151,8 +150,8 @@ var _typekind = []string{ } func typekind(t *types.Type) string { - if t.IsSlice() { - return "slice" + if t.IsUntyped() { + return fmt.Sprintf("%v", t) } et := t.Etype if int(et) < len(_typekind) { @@ -257,12 +256,12 @@ func typecheck(n *Node, top int) (res *Node) { // are substituted. cycle := cycleFor(n) for _, n1 := range cycle { - if n1.Name != nil && !n1.Name.Param.Alias { + if n1.Name != nil && !n1.Name.Param.Alias() { // Cycle is ok. But if n is an alias type and doesn't // have a type yet, we have a recursive type declaration // with aliases that we can't handle properly yet. // Report an error rather than crashing later. - if n.Name != nil && n.Name.Param.Alias && n.Type == nil { + if n.Name != nil && n.Name.Param.Alias() && n.Type == nil { lineno = n.Pos Fatalf("cannot handle alias type declaration (issue #25838): %v", n) } @@ -361,7 +360,7 @@ func typecheck1(n *Node, top int) (res *Node) { ok |= ctxExpr if n.Type == nil && n.Val().Ctype() == CTSTR { - n.Type = types.Idealstring + n.Type = types.UntypedString } case ONONAME: @@ -471,10 +470,10 @@ func typecheck1(n *Node, top int) (res *Node) { return n } if l.Type.NotInHeap() { - yyerror("go:notinheap map key not allowed") + yyerror("incomplete (or unallocatable) map key not allowed") } if r.Type.NotInHeap() { - yyerror("go:notinheap map value not allowed") + yyerror("incomplete (or unallocatable) map value not allowed") } setTypeNode(n, types.NewMap(l.Type, r.Type)) @@ -491,7 +490,7 @@ func typecheck1(n *Node, top int) (res *Node) { return n } if l.Type.NotInHeap() { - yyerror("chan of go:notinheap type not allowed") + yyerror("chan of incomplete (or unallocatable) type not allowed") } setTypeNode(n, types.NewChan(l.Type, n.TChanDir())) @@ -623,10 +622,29 @@ func typecheck1(n *Node, top int) (res *Node) { // no defaultlit for left // the outer context gives the type n.Type = l.Type + if (l.Type == types.UntypedFloat || l.Type == types.UntypedComplex) && r.Op == OLITERAL { + n.Type = types.UntypedInt + } break } + // For "x == x && len(s)", it's better to report that "len(s)" (type int) + // can't be used with "&&" than to report that "x == x" (type untyped bool) + // can't be converted to int (see issue #41500). + if n.Op == OANDAND || n.Op == OOROR { + if !n.Left.Type.IsBoolean() { + yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Left.Type)) + n.Type = nil + return n + } + if !n.Right.Type.IsBoolean() { + yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Right.Type)) + n.Type = nil + return n + } + } + // ideal mixed with non-ideal l, r = defaultlit2(l, r, false) @@ -655,8 +673,8 @@ func typecheck1(n *Node, top int) (res *Node) { // The conversion allocates, so only do it if the concrete type is huge. converted := false if r.Type.Etype != TBLANK { - aop = assignop(l.Type, r.Type, nil) - if aop != 0 { + aop, _ = assignop(l.Type, r.Type) + if aop != OXXX { if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) { yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type)) n.Type = nil @@ -677,8 +695,8 @@ func typecheck1(n *Node, top int) (res *Node) { } if !converted && l.Type.Etype != TBLANK { - aop = assignop(r.Type, l.Type, nil) - if aop != 0 { + aop, _ = assignop(r.Type, l.Type) + if aop != OXXX { if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) { yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type)) n.Type = nil @@ -713,7 +731,10 @@ func typecheck1(n *Node, top int) (res *Node) { } } - if !okfor[op][et] { + if t.Etype == TIDEAL { + t = mixUntyped(l.Type, r.Type) + } + if dt := defaultType(t); !okfor[op][dt.Etype] { yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t)) n.Type = nil return n @@ -753,17 +774,9 @@ func typecheck1(n *Node, top int) (res *Node) { } } - t = l.Type if iscmp[n.Op] { - // TIDEAL includes complex constant, but only OEQ and ONE are defined for complex, - // so check that the n.op is available for complex here before doing evconst. - if !okfor[n.Op][TCOMPLEX128] && (Isconst(l, CTCPLX) || Isconst(r, CTCPLX)) { - yyerror("invalid operation: %v (operator %v not defined on untyped complex)", n, n.Op) - n.Type = nil - return n - } evconst(n) - t = types.Idealbool + t = types.UntypedBool if n.Op != OLITERAL { l, r = defaultlit2(l, r, true) n.Left = l @@ -808,8 +821,8 @@ func typecheck1(n *Node, top int) (res *Node) { n.Type = nil return n } - if !okfor[n.Op][t.Etype] { - yyerror("invalid operation: %v %v", n.Op, t) + if !okfor[n.Op][defaultType(t).Etype] { + yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(t)) n.Type = nil return n } @@ -1032,13 +1045,13 @@ func typecheck1(n *Node, top int) (res *Node) { } if !n.Bounded() && Isconst(n.Right, CTINT) { - x := n.Right.Int64() + x := n.Right.Int64Val() if x < 0 { yyerror("invalid %s index %v (index must be non-negative)", why, n.Right) } else if t.IsArray() && x >= t.NumElem() { yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem()) - } else if Isconst(n.Left, CTSTR) && x >= int64(len(strlit(n.Left))) { - yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(strlit(n.Left))) + } else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.StringVal())) { + yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal())) } else if n.Right.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { yyerror("invalid %s index %v (index too large)", why, n.Right) } @@ -1134,11 +1147,11 @@ func typecheck1(n *Node, top int) (res *Node) { l = defaultlit(l, types.Types[TINT]) c = defaultlit(c, types.Types[TINT]) - if Isconst(l, CTINT) && l.Int64() < 0 { + if Isconst(l, CTINT) && l.Int64Val() < 0 { Fatalf("len for OSLICEHEADER must be non-negative") } - if Isconst(c, CTINT) && c.Int64() < 0 { + if Isconst(c, CTINT) && c.Int64Val() < 0 { Fatalf("cap for OSLICEHEADER must be non-negative") } @@ -1187,7 +1200,7 @@ func typecheck1(n *Node, top int) (res *Node) { if n.Left.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { Fatalf("len for OMAKESLICECOPY too large") } - if n.Left.Int64() < 0 { + if n.Left.Int64Val() < 0 { Fatalf("len for OMAKESLICECOPY must be non-negative") } } @@ -1444,7 +1457,7 @@ func typecheck1(n *Node, top int) (res *Node) { // Determine result type. switch t.Etype { case TIDEAL: - n.Type = types.Idealfloat + n.Type = types.UntypedFloat case TCOMPLEX64: n.Type = types.Types[TFLOAT32] case TCOMPLEX128: @@ -1490,7 +1503,7 @@ func typecheck1(n *Node, top int) (res *Node) { return n case TIDEAL: - t = types.Idealcomplex + t = types.UntypedComplex case TFLOAT32: t = types.Types[TCOMPLEX64] @@ -1677,8 +1690,8 @@ func typecheck1(n *Node, top int) (res *Node) { return n } var why string - n.Op = convertop(n.Left.Op == OLITERAL, t, n.Type, &why) - if n.Op == 0 { + n.Op, why = convertop(n.Left.Op == OLITERAL, t, n.Type) + if n.Op == OXXX { if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() { yyerror("cannot convert %L to type %v%s", n.Left, n.Type, why) n.SetDiag(true) @@ -1756,7 +1769,7 @@ func typecheck1(n *Node, top int) (res *Node) { n.Type = nil return n } - if !checkmake(t, "len", l) || r != nil && !checkmake(t, "cap", r) { + if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) { n.Type = nil return n } @@ -1780,7 +1793,7 @@ func typecheck1(n *Node, top int) (res *Node) { n.Type = nil return n } - if !checkmake(t, "size", l) { + if !checkmake(t, "size", &l) { n.Type = nil return n } @@ -1801,7 +1814,7 @@ func typecheck1(n *Node, top int) (res *Node) { n.Type = nil return n } - if !checkmake(t, "buffer", l) { + if !checkmake(t, "buffer", &l) { n.Type = nil return n } @@ -2051,11 +2064,6 @@ func typecheck1(n *Node, top int) (res *Node) { n.Type = nil return n - case OCASE: - ok |= ctxStmt - typecheckslice(n.List.Slice(), ctxExpr) - typecheckslice(n.Nbody.Slice(), ctxStmt) - case ODCLFUNC: ok |= ctxStmt typecheckfunc(n) @@ -2068,12 +2076,6 @@ func typecheck1(n *Node, top int) (res *Node) { ok |= ctxStmt n.Left = typecheck(n.Left, ctxType) checkwidth(n.Left.Type) - if n.Left.Type != nil && n.Left.Type.NotInHeap() && n.Left.Name.Param.Pragma&NotInHeap == 0 { - // The type contains go:notinheap types, so it - // must be marked as such (alternatively, we - // could silently propagate go:notinheap). - yyerror("type %v must be go:notinheap", n.Left.Type) - } } t := n.Type @@ -2179,14 +2181,14 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool { } if r.Op == OLITERAL { - if r.Int64() < 0 { + if r.Int64Val() < 0 { yyerror("invalid slice index %v (index must be non-negative)", r) return false - } else if tp != nil && tp.NumElem() >= 0 && r.Int64() > tp.NumElem() { + } else if tp != nil && tp.NumElem() >= 0 && r.Int64Val() > tp.NumElem() { yyerror("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem()) return false - } else if Isconst(l, CTSTR) && r.Int64() > int64(len(strlit(l))) { - yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(strlit(l))) + } else if Isconst(l, CTSTR) && r.Int64Val() > int64(len(l.StringVal())) { + yyerror("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.StringVal())) return false } else if r.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { yyerror("invalid slice index %v (index too large)", r) @@ -2439,15 +2441,6 @@ func derefall(t *types.Type) *types.Type { return t } -type typeSymKey struct { - t *types.Type - s *types.Sym -} - -// dotField maps (*types.Type, *types.Sym) pairs to the corresponding struct field (*types.Type with Etype==TFIELD). -// It is a cache for use during usefield in walk.go, only enabled when field tracking. -var dotField = map[typeSymKey]*types.Field{} - func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { s := n.Sym @@ -2478,9 +2471,6 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { } n.Xoffset = f1.Offset n.Type = f1.Type - if objabi.Fieldtrack_enabled > 0 { - dotField[typeSymKey{t.Orig, s}] = f1 - } if t.IsInterface() { if n.Left.Type.IsPtr() { n.Left = nod(ODEREF, n.Left, nil) // implicitstar @@ -2489,6 +2479,8 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { } n.Op = ODOTINTER + } else { + n.SetOpt(f1) } return f1 @@ -2508,7 +2500,7 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { n.Left = nod(OADDR, n.Left, nil) n.Left.SetImplicit(true) n.Left = typecheck(n.Left, ctxType|ctxExpr) - } else if tt.IsPtr() && !rcvr.IsPtr() && types.Identical(tt.Elem(), rcvr) { + } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) { n.Left = nod(ODEREF, n.Left, nil) n.Left.SetImplicit(true) n.Left = typecheck(n.Left, ctxType|ctxExpr) @@ -2667,7 +2659,7 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, return notenough: - if n == nil || !n.Diag() { + if n == nil || (!n.Diag() && n.Type != nil) { details := errorDetails(nl, tstruct, isddd) if call != nil { // call is the expression being called, not the overall call. @@ -2708,17 +2700,17 @@ func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string { return "" } } - return fmt.Sprintf("\n\thave %s\n\twant %v", nl.retsigerr(isddd), tstruct) + return fmt.Sprintf("\n\thave %s\n\twant %v", nl.sigerr(isddd), tstruct) } // sigrepr is a type's representation to the outside world, // in string representations of return signatures // e.g in error messages about wrong arguments to return. -func sigrepr(t *types.Type) string { +func sigrepr(t *types.Type, isddd bool) string { switch t { - case types.Idealstring: + case types.UntypedString: return "string" - case types.Idealbool: + case types.UntypedBool: return "bool" } @@ -2729,26 +2721,29 @@ func sigrepr(t *types.Type) string { return "number" } + // Turn []T... argument to ...T for clearer error message. + if isddd { + if !t.IsSlice() { + Fatalf("bad type for ... argument: %v", t) + } + return "..." + t.Elem().String() + } return t.String() } -// retsigerr returns the signature of the types -// at the respective return call site of a function. -func (nl Nodes) retsigerr(isddd bool) string { +// sigerr returns the signature of the types at the call or return. +func (nl Nodes) sigerr(isddd bool) string { if nl.Len() < 1 { return "()" } var typeStrings []string - for _, n := range nl.Slice() { - typeStrings = append(typeStrings, sigrepr(n.Type)) + for i, n := range nl.Slice() { + isdddArg := isddd && i == nl.Len()-1 + typeStrings = append(typeStrings, sigrepr(n.Type, isdddArg)) } - ddd := "" - if isddd { - ddd = "..." - } - return fmt.Sprintf("(%s%s)", strings.Join(typeStrings, ", "), ddd) + return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", ")) } // type check composite @@ -3135,9 +3130,14 @@ func checkassign(stmt *Node, n *Node) { return } - if n.Op == ODOT && n.Left.Op == OINDEXMAP { + switch { + case n.Op == ODOT && n.Left.Op == OINDEXMAP: yyerror("cannot assign to struct field %v in map", n) - } else { + case (n.Op == OINDEX && n.Left.Type.IsString()) || n.Op == OSLICESTR: + yyerror("cannot assign to %v (strings are immutable)", n) + case n.Op == OLITERAL && n.Sym != nil && n.isGoConst(): + yyerror("cannot assign to %v (declared const)", n) + default: yyerror("cannot assign to %v", n) } n.Type = nil @@ -3251,9 +3251,7 @@ func typecheckas(n *Node) { } func checkassignto(src *types.Type, dst *Node) { - var why string - - if assignop(src, dst.Type, &why) == 0 { + if op, why := assignop(src, dst.Type); op == OXXX { yyerror("cannot assign %v to %L in multiple assignment%s", src, dst, why) return } @@ -3434,9 +3432,8 @@ func stringtoruneslit(n *Node) *Node { } var l []*Node - s := strlit(n.Left) i := 0 - for _, r := range s { + for _, r := range n.Left.StringVal() { l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r)))) i++ } @@ -3491,7 +3488,7 @@ func setUnderlying(t, underlying *types.Type) { } // Propagate go:notinheap pragma from the Name to the Type. - if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma&NotInHeap != 0 { + if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma()&NotInHeap != 0 { t.SetNotInHeap(true) } @@ -3663,7 +3660,7 @@ func typecheckdef(n *Node) { n.Name.Defn = typecheck(n.Name.Defn, ctxStmt) // fills in n.Type case OTYPE: - if p := n.Name.Param; p.Alias { + if p := n.Name.Param; p.Alias() { // Type alias declaration: Simply use the rhs type - no need // to create a new type. // If we have a syntax error, p.Ntype may be nil. @@ -3713,7 +3710,8 @@ ret: n.SetWalkdef(1) } -func checkmake(t *types.Type, arg string, n *Node) bool { +func checkmake(t *types.Type, arg string, np **Node) bool { + n := *np if !n.Type.IsInteger() && n.Type.Etype != TIDEAL { yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type) return false @@ -3723,12 +3721,12 @@ func checkmake(t *types.Type, arg string, n *Node) bool { // to avoid redundant "constant NNN overflows int" errors. switch consttype(n) { case CTINT, CTRUNE, CTFLT, CTCPLX: - n.SetVal(toint(n.Val())) - if n.Val().U.(*Mpint).CmpInt64(0) < 0 { + v := toint(n.Val()).U.(*Mpint) + if v.CmpInt64(0) < 0 { yyerror("negative %s argument in make(%v)", arg, t) return false } - if n.Val().U.(*Mpint).Cmp(maxintval[TINT]) > 0 { + if v.Cmp(maxintval[TINT]) > 0 { yyerror("%s argument too large in make(%v)", arg, t) return false } @@ -3740,6 +3738,7 @@ func checkmake(t *types.Type, arg string, n *Node) bool { // for instance, indexlit might be called here and incorporate some // of the bounds checks done for make. n = defaultlit(n, types.Types[TINT]) + *np = n return true } @@ -3886,7 +3885,7 @@ func deadcodefn(fn *Node) { return } case OFOR: - if !Isconst(n.Left, CTBOOL) || n.Left.Bool() { + if !Isconst(n.Left, CTBOOL) || n.Left.BoolVal() { return } default: @@ -3916,7 +3915,7 @@ func deadcodeslice(nn Nodes) { n.Left = deadcodeexpr(n.Left) if Isconst(n.Left, CTBOOL) { var body Nodes - if n.Left.Bool() { + if n.Left.BoolVal() { n.Rlist = Nodes{} body = n.Nbody } else { @@ -3959,7 +3958,7 @@ func deadcodeexpr(n *Node) *Node { n.Left = deadcodeexpr(n.Left) n.Right = deadcodeexpr(n.Right) if Isconst(n.Left, CTBOOL) { - if n.Left.Bool() { + if n.Left.BoolVal() { return n.Right // true && x => x } else { return n.Left // false && x => false @@ -3969,7 +3968,7 @@ func deadcodeexpr(n *Node) *Node { n.Left = deadcodeexpr(n.Left) n.Right = deadcodeexpr(n.Right) if Isconst(n.Left, CTBOOL) { - if n.Left.Bool() { + if n.Left.BoolVal() { return n.Left // true || x => true } else { return n.Right // false || x => x diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go index 04861c8dd4..ff8cabd8e3 100644 --- a/src/cmd/compile/internal/gc/universe.go +++ b/src/cmd/compile/internal/gc/universe.go @@ -123,21 +123,21 @@ func lexinit() { asNode(s2.Def).SetSubOp(s.op) } - types.Idealstring = types.New(TSTRING) - types.Idealbool = types.New(TBOOL) + types.UntypedString = types.New(TSTRING) + types.UntypedBool = types.New(TBOOL) types.Types[TANY] = types.New(TANY) s := builtinpkg.Lookup("true") s.Def = asTypesNode(nodbool(true)) asNode(s.Def).Sym = lookup("true") asNode(s.Def).Name = new(Name) - asNode(s.Def).Type = types.Idealbool + asNode(s.Def).Type = types.UntypedBool s = builtinpkg.Lookup("false") s.Def = asTypesNode(nodbool(false)) asNode(s.Def).Sym = lookup("false") asNode(s.Def).Name = new(Name) - asNode(s.Def).Type = types.Idealbool + asNode(s.Def).Type = types.UntypedBool s = lookup("_") s.Block = -100 @@ -351,7 +351,7 @@ func typeinit() { sizeofString = Rnd(sliceLenOffset+int64(Widthptr), int64(Widthptr)) dowidth(types.Types[TSTRING]) - dowidth(types.Idealstring) + dowidth(types.UntypedString) } func makeErrorInterface() *types.Type { diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 0158af8700..a7b6e7fcb3 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -21,7 +21,7 @@ const zeroValSize = 1024 // must match value of runtime/map.go:maxZero func walk(fn *Node) { Curfn = fn - if Debug['W'] != 0 { + if Debug.W != 0 { s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym) dumplist(s, Curfn.Nbody) } @@ -63,14 +63,14 @@ func walk(fn *Node) { return } walkstmtlist(Curfn.Nbody.Slice()) - if Debug['W'] != 0 { + if Debug.W != 0 { s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym) dumplist(s, Curfn.Nbody) } zeroResults() heapmoves() - if Debug['W'] != 0 && Curfn.Func.Enter.Len() > 0 { + if Debug.W != 0 && Curfn.Func.Enter.Len() > 0 { s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym) dumplist(s, Curfn.Func.Enter) } @@ -231,6 +231,13 @@ func walkstmt(n *Node) *Node { case OCOPY: n.Left = copyany(n.Left, &n.Ninit, true) + case OCALLFUNC, OCALLMETH, OCALLINTER: + if n.Left.Nbody.Len() > 0 { + n.Left = wrapCall(n.Left, &n.Ninit) + } else { + n.Left = walkexpr(n.Left, &n.Ninit) + } + default: n.Left = walkexpr(n.Left, &n.Ninit) } @@ -329,19 +336,6 @@ func walkstmt(n *Node) *Node { return n } -func isSmallMakeSlice(n *Node) bool { - if n.Op != OMAKESLICE { - return false - } - r := n.Right - if r == nil { - r = n.Left - } - t := n.Type - - return smallintconst(r) && (t.Elem().Width == 0 || r.Int64() < maxImplicitStackVarSize/t.Elem().Width) -} - // walk the whole tree of the body of an // expression or simple statement. // the types expressions are calculated. @@ -442,7 +436,7 @@ func walkexpr(n *Node, init *Nodes) *Node { lno := setlineno(n) - if Debug['w'] > 1 { + if Debug.w > 1 { Dump("before walk expr", n) } @@ -480,7 +474,7 @@ opswitch: ODEREF, OSPTR, OITAB, OIDATA, OADDR: n.Left = walkexpr(n.Left, init) - case OEFACE, OAND, OSUB, OMUL, OADD, OOR, OXOR, OLSH, ORSH: + case OEFACE, OAND, OANDNOT, OSUB, OMUL, OADD, OOR, OXOR, OLSH, ORSH: n.Left = walkexpr(n.Left, init) n.Right = walkexpr(n.Right, init) @@ -558,6 +552,7 @@ opswitch: case OCALLINTER, OCALLFUNC, OCALLMETH: if n.Op == OCALLINTER { usemethod(n) + markUsedIfaceMethod(n) } if n.Op == OCALLFUNC && n.Left.Op == OCLOSURE { @@ -641,7 +636,7 @@ opswitch: // x = append(...) r := n.Right if r.Type.Elem().NotInHeap() { - yyerror("%v is go:notinheap; heap allocation disallowed", r.Type.Elem()) + yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type.Elem()) } switch { case isAppendOfMake(r): @@ -798,8 +793,8 @@ opswitch: fromType := n.Left.Type toType := n.Type - if !fromType.IsInterface() { - markTypeUsedInInterface(fromType) + if !fromType.IsInterface() && !Curfn.Func.Nname.isBlank() { // skip unnamed functions (func _()) + markTypeUsedInInterface(fromType, Curfn.Func.lsym) } // typeword generates the type word of the interface value. @@ -954,11 +949,11 @@ opswitch: case OCONV, OCONVNOP: n.Left = walkexpr(n.Left, init) if n.Op == OCONVNOP && checkPtr(Curfn, 1) { - if n.Type.IsPtr() && n.Left.Type.Etype == TUNSAFEPTR { // unsafe.Pointer to *T + if n.Type.IsPtr() && n.Left.Type.IsUnsafePtr() { // unsafe.Pointer to *T n = walkCheckPtrAlignment(n, init, nil) break } - if n.Type.Etype == TUNSAFEPTR && n.Left.Type.Etype == TUINTPTR { // uintptr to unsafe.Pointer + if n.Type.IsUnsafePtr() && n.Left.Type.IsUintptr() { // uintptr to unsafe.Pointer n = walkCheckPtrArithmetic(n, init) break } @@ -970,14 +965,6 @@ opswitch: fn := basicnames[param] + "to" + basicnames[result] n = conv(mkcall(fn, types.Types[result], init, conv(n.Left, types.Types[param])), n.Type) - case OANDNOT: - n.Left = walkexpr(n.Left, init) - n.Op = OAND - n.SetImplicit(true) // for walkCheckPtrArithmetic - n.Right = nod(OBITNOT, n.Right, nil) - n.Right = typecheck(n.Right, ctxExpr) - n.Right = walkexpr(n.Right, init) - case ODIV, OMOD: n.Left = walkexpr(n.Left, init) n.Right = walkexpr(n.Right, init) @@ -1002,11 +989,11 @@ opswitch: // runtime calls late in SSA processing. if Widthreg < 8 && (et == TINT64 || et == TUINT64) { if n.Right.Op == OLITERAL { - // Leave div/mod by constant powers of 2. + // Leave div/mod by constant powers of 2 or small 16-bit constants. // The SSA backend will handle those. switch et { case TINT64: - c := n.Right.Int64() + c := n.Right.Int64Val() if c < 0 { c = -c } @@ -1014,7 +1001,10 @@ opswitch: break opswitch } case TUINT64: - c := uint64(n.Right.Int64()) + c := uint64(n.Right.Int64Val()) + if c < 1<<16 { + break opswitch + } if c != 0 && c&(c-1) == 0 { break opswitch } @@ -1054,15 +1044,15 @@ opswitch: } if t.IsArray() { n.SetBounded(bounded(r, t.NumElem())) - if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { + if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { Warn("index bounds check elided") } if smallintconst(n.Right) && !n.Bounded() { yyerror("index out of bounds") } } else if Isconst(n.Left, CTSTR) { - n.SetBounded(bounded(r, int64(len(strlit(n.Left))))) - if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { + n.SetBounded(bounded(r, int64(len(n.Left.StringVal())))) + if Debug.m != 0 && n.Bounded() && !Isconst(n.Right, CTINT) { Warn("index bounds check elided") } if smallintconst(n.Right) && !n.Bounded() { @@ -1123,7 +1113,7 @@ opswitch: n.List.SetSecond(walkexpr(n.List.Second(), init)) case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR: - checkSlice := checkPtr(Curfn, 1) && n.Op == OSLICE3ARR && n.Left.Op == OCONVNOP && n.Left.Left.Type.Etype == TUNSAFEPTR + checkSlice := checkPtr(Curfn, 1) && n.Op == OSLICE3ARR && n.Left.Op == OCONVNOP && n.Left.Left.Type.IsUnsafePtr() if checkSlice { n.Left.Left = walkexpr(n.Left.Left, init) } else { @@ -1157,7 +1147,7 @@ opswitch: case ONEW: if n.Type.Elem().NotInHeap() { - yyerror("%v is go:notinheap; heap allocation disallowed", n.Type.Elem()) + yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem()) } if n.Esc == EscNone { if n.Type.Elem().Width >= maxImplicitStackVarSize { @@ -1328,11 +1318,11 @@ opswitch: } t := n.Type if t.Elem().NotInHeap() { - yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem()) + yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem()) } if n.Esc == EscNone { - if !isSmallMakeSlice(n) { - Fatalf("non-small OMAKESLICE with EscNone: %v", n) + if why := heapAllocReason(n); why != "" { + Fatalf("%v has EscNone, but %v", n, why) } // var arr [r]T // n = arr[:l] @@ -1405,7 +1395,7 @@ opswitch: t := n.Type if t.Elem().NotInHeap() { - yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem()) + yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem()) } length := conv(n.Left, types.Types[TINT]) @@ -1477,7 +1467,7 @@ opswitch: } else { // slicebytetostring(*[32]byte, ptr *byte, n int) string n.Left = cheapexpr(n.Left, init) - ptr, len := n.Left.slicePtrLen() + ptr, len := n.Left.backingArrayPtrLen() n = mkcall("slicebytetostring", n.Type, init, a, ptr, len) } @@ -1490,13 +1480,13 @@ opswitch: } // slicebytetostringtmp(ptr *byte, n int) string n.Left = cheapexpr(n.Left, init) - ptr, len := n.Left.slicePtrLen() + ptr, len := n.Left.backingArrayPtrLen() n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len) case OSTR2BYTES: s := n.Left if Isconst(s, CTSTR) { - sc := strlit(s) + sc := s.StringVal() // Allocate a [n]byte of the right size. t := types.NewArray(types.Types[TUINT8], int64(len(sc))) @@ -1604,7 +1594,7 @@ opswitch: updateHasCall(n) - if Debug['w'] != 0 && n != nil { + if Debug.w != 0 && n != nil { Dump("after walk expr", n) } @@ -1614,8 +1604,27 @@ opswitch: // markTypeUsedInInterface marks that type t is converted to an interface. // This information is used in the linker in dead method elimination. -func markTypeUsedInInterface(t *types.Type) { - typenamesym(t).Linksym().Set(obj.AttrUsedInIface, true) +func markTypeUsedInInterface(t *types.Type, from *obj.LSym) { + tsym := typenamesym(t).Linksym() + // Emit a marker relocation. The linker will know the type is converted + // to an interface if "from" is reachable. + r := obj.Addrel(from) + r.Sym = tsym + r.Type = objabi.R_USEIFACE +} + +// markUsedIfaceMethod marks that an interface method is used in the current +// function. n is OCALLINTER node. +func markUsedIfaceMethod(n *Node) { + ityp := n.Left.Left.Type + tsym := typenamesym(ityp).Linksym() + r := obj.Addrel(Curfn.Func.lsym) + r.Sym = tsym + // n.Left.Xoffset is the method index * Widthptr (the offset of code pointer + // in itab). + midx := n.Left.Xoffset / int64(Widthptr) + r.Add = ifaceMethodOffset(ityp, midx) + r.Type = objabi.R_USEIFACEMETHOD } // rtconvfn returns the parameter and result types that will be used by a @@ -1905,7 +1914,7 @@ func walkprint(nn *Node, init *Nodes) *Node { for i := 0; i < len(s); { var strs []string for i < len(s) && Isconst(s[i], CTSTR) { - strs = append(strs, strlit(s[i])) + strs = append(strs, s[i].StringVal()) i++ } if len(strs) > 0 { @@ -1951,7 +1960,17 @@ func walkprint(nn *Node, init *Nodes) *Node { on = syslook("printiface") } on = substArgTypes(on, n.Type) // any-1 - case TPTR, TCHAN, TMAP, TFUNC, TUNSAFEPTR: + case TPTR: + if n.Type.Elem().NotInHeap() { + on = syslook("printuintptr") + n = nod(OCONV, n, nil) + n.Type = types.Types[TUNSAFEPTR] + n = nod(OCONV, n, nil) + n.Type = types.Types[TUINTPTR] + break + } + fallthrough + case TCHAN, TMAP, TFUNC, TUNSAFEPTR: on = syslook("printpointer") on = substArgTypes(on, n.Type) // any-1 case TSLICE: @@ -1974,7 +1993,7 @@ func walkprint(nn *Node, init *Nodes) *Node { case TSTRING: cs := "" if Isconst(n, CTSTR) { - cs = strlit(n) + cs = n.StringVal() } switch cs { case " ": @@ -2143,7 +2162,7 @@ func reorder3(all []*Node) []*Node { // The result of reorder3save MUST be assigned back to n, e.g. // n.Left = reorder3save(n.Left, all, i, early) func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node { - if !aliased(n, all, i) { + if !aliased(n, all[:i]) { return n } @@ -2175,73 +2194,75 @@ func outervalue(n *Node) *Node { } } -// Is it possible that the computation of n might be -// affected by writes in as up to but not including the ith element? -func aliased(n *Node, all []*Node, i int) bool { - if n == nil { +// Is it possible that the computation of r might be +// affected by assignments in all? +func aliased(r *Node, all []*Node) bool { + if r == nil { return false } // Treat all fields of a struct as referring to the whole struct. // We could do better but we would have to keep track of the fields. - for n.Op == ODOT { - n = n.Left + for r.Op == ODOT { + r = r.Left } // Look for obvious aliasing: a variable being assigned // during the all list and appearing in n. - // Also record whether there are any writes to main memory. - // Also record whether there are any writes to variables - // whose addresses have been taken. + // Also record whether there are any writes to addressable + // memory (either main memory or variables whose addresses + // have been taken). memwrite := false - varwrite := false - for _, an := range all[:i] { - a := outervalue(an.Left) - - for a.Op == ODOT { - a = a.Left + for _, as := range all { + // We can ignore assignments to blank. + if as.Left.isBlank() { + continue } - if a.Op != ONAME { + l := outervalue(as.Left) + if l.Op != ONAME { memwrite = true continue } - switch n.Class() { + switch l.Class() { default: - varwrite = true + Fatalf("unexpected class: %v, %v", l, l.Class()) + + case PAUTOHEAP, PEXTERN: + memwrite = true continue case PAUTO, PPARAM, PPARAMOUT: - if n.Name.Addrtaken() { - varwrite = true + if l.Name.Addrtaken() { + memwrite = true continue } - if vmatch2(a, n) { - // Direct hit. + if vmatch2(l, r) { + // Direct hit: l appears in r. return true } } } - // The variables being written do not appear in n. - // However, n might refer to computed addresses + // The variables being written do not appear in r. + // However, r might refer to computed addresses // that are being written. // If no computed addresses are affected by the writes, no aliasing. - if !memwrite && !varwrite { + if !memwrite { return false } - // If n does not refer to computed addresses - // (that is, if n only refers to variables whose addresses + // If r does not refer to computed addresses + // (that is, if r only refers to variables whose addresses // have not been taken), no aliasing. - if varexpr(n) { + if varexpr(r) { return false } - // Otherwise, both the writes and n refer to computed memory addresses. + // Otherwise, both the writes and r refer to computed memory addresses. // Assume that they might conflict. return true } @@ -2629,7 +2650,7 @@ func addstr(n *Node, init *Nodes) *Node { sz := int64(0) for _, n1 := range n.List.Slice() { if n1.Op == OLITERAL { - sz += int64(len(strlit(n1))) + sz += int64(len(n1.StringVal())) } } @@ -2757,36 +2778,25 @@ func appendslice(n *Node, init *Nodes) *Node { // instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int fn := syslook("typedslicecopy") fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem()) - ptr1, len1 := nptr1.slicePtrLen() - ptr2, len2 := nptr2.slicePtrLen() + ptr1, len1 := nptr1.backingArrayPtrLen() + ptr2, len2 := nptr2.backingArrayPtrLen() ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2) - } else if instrumenting && !compiling_runtime { - // rely on runtime to instrument copy. - // copy(s[len(l1):], l2) + // rely on runtime to instrument: + // copy(s[len(l1):], l2) + // l2 can be a slice or string. nptr1 := nod(OSLICE, s, nil) nptr1.Type = s.Type nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil) nptr1 = cheapexpr(nptr1, &nodes) - nptr2 := l2 - if l2.Type.IsString() { - // instantiate func slicestringcopy(toPtr *byte, toLen int, fr string) int - fn := syslook("slicestringcopy") - ptr, len := nptr1.slicePtrLen() - str := nod(OCONVNOP, nptr2, nil) - str.Type = types.Types[TSTRING] - ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr, len, str) - } else { - // instantiate func slicecopy(to any, fr any, wid uintptr) int - fn := syslook("slicecopy") - fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem()) - ptr1, len1 := nptr1.slicePtrLen() - ptr2, len2 := nptr2.slicePtrLen() - ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width)) - } + ptr1, len1 := nptr1.backingArrayPtrLen() + ptr2, len2 := nptr2.backingArrayPtrLen() + fn := syslook("slicecopy") + fn = substArgTypes(fn, ptr1.Type.Elem(), ptr2.Type.Elem()) + ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width)) } else { // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil)) @@ -2814,7 +2824,7 @@ func appendslice(n *Node, init *Nodes) *Node { // isAppendOfMake reports whether n is of the form append(x , make([]T, y)...). // isAppendOfMake assumes n has already been typechecked. func isAppendOfMake(n *Node) bool { - if Debug['N'] != 0 || instrumenting { + if Debug.N != 0 || instrumenting { return false } @@ -3085,28 +3095,25 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node { Curfn.Func.setWBPos(n.Pos) fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem()) n.Left = cheapexpr(n.Left, init) - ptrL, lenL := n.Left.slicePtrLen() + ptrL, lenL := n.Left.backingArrayPtrLen() n.Right = cheapexpr(n.Right, init) - ptrR, lenR := n.Right.slicePtrLen() + ptrR, lenR := n.Right.backingArrayPtrLen() return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR) } if runtimecall { - if n.Right.Type.IsString() { - fn := syslook("slicestringcopy") - n.Left = cheapexpr(n.Left, init) - ptr, len := n.Left.slicePtrLen() - str := nod(OCONVNOP, n.Right, nil) - str.Type = types.Types[TSTRING] - return mkcall1(fn, n.Type, init, ptr, len, str) - } + // rely on runtime to instrument: + // copy(n.Left, n.Right) + // n.Right can be a slice or string. - fn := syslook("slicecopy") - fn = substArgTypes(fn, n.Left.Type.Elem(), n.Right.Type.Elem()) n.Left = cheapexpr(n.Left, init) - ptrL, lenL := n.Left.slicePtrLen() + ptrL, lenL := n.Left.backingArrayPtrLen() n.Right = cheapexpr(n.Right, init) - ptrR, lenR := n.Right.slicePtrLen() + ptrR, lenR := n.Right.backingArrayPtrLen() + + fn := syslook("slicecopy") + fn = substArgTypes(fn, ptrL.Type.Elem(), ptrR.Type.Elem()) + return mkcall1(fn, n.Type, init, ptrL, lenL, ptrR, lenR, nodintconst(n.Left.Type.Elem().Width)) } @@ -3437,7 +3444,7 @@ func walkcompare(n *Node, init *Nodes) *Node { func tracecmpArg(n *Node, t *types.Type, init *Nodes) *Node { // Ugly hack to avoid "constant -1 overflows uintptr" errors, etc. - if n.Op == OLITERAL && n.Type.IsSigned() && n.Int64() < 0 { + if n.Op == OLITERAL && n.Type.IsSigned() && n.Int64Val() < 0 { n = copyexpr(n, n.Type, init) } @@ -3507,7 +3514,7 @@ func walkcompareString(n *Node, init *Nodes) *Node { // Length-only checks are ok, though. maxRewriteLen = 0 } - if s := strlit(cs); len(s) <= maxRewriteLen { + if s := cs.StringVal(); len(s) <= maxRewriteLen { if len(s) > 0 { ncs = safeexpr(ncs, init) } @@ -3602,26 +3609,32 @@ func bounded(n *Node, max int64) bool { bits := int32(8 * n.Type.Width) if smallintconst(n) { - v := n.Int64() + v := n.Int64Val() return 0 <= v && v < max } switch n.Op { - case OAND: + case OAND, OANDNOT: v := int64(-1) - if smallintconst(n.Left) { - v = n.Left.Int64() - } else if smallintconst(n.Right) { - v = n.Right.Int64() + switch { + case smallintconst(n.Left): + v = n.Left.Int64Val() + case smallintconst(n.Right): + v = n.Right.Int64Val() + if n.Op == OANDNOT { + v = ^v + if !sign { + v &= 1<<uint(bits) - 1 + } + } } - if 0 <= v && v < max { return true } case OMOD: if !sign && smallintconst(n.Right) { - v := n.Right.Int64() + v := n.Right.Int64Val() if 0 <= v && v <= max { return true } @@ -3629,7 +3642,7 @@ func bounded(n *Node, max int64) bool { case ODIV: if !sign && smallintconst(n.Right) { - v := n.Right.Int64() + v := n.Right.Int64Val() for bits > 0 && v >= 2 { bits-- v >>= 1 @@ -3638,7 +3651,7 @@ func bounded(n *Node, max int64) bool { case ORSH: if !sign && smallintconst(n.Right) { - v := n.Right.Int64() + v := n.Right.Int64Val() if v > int64(bits) { return true } @@ -3694,6 +3707,8 @@ func usemethod(n *Node) { // Also need to check for reflect package itself (see Issue #38515). if s := res0.Type.Sym; s != nil && s.Name == "Method" && isReflectPkg(s.Pkg) { Curfn.Func.SetReflectMethod(true) + // The LSym is initialized at this point. We need to set the attribute on the LSym. + Curfn.Func.lsym.Set(obj.AttrReflectMethod, true) } } @@ -3719,10 +3734,13 @@ func usefield(n *Node) { if t.IsPtr() { t = t.Elem() } - field := dotField[typeSymKey{t.Orig, n.Sym}] + field := n.Opt().(*types.Field) if field == nil { Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym) } + if field.Sym != n.Sym || field.Offset != n.Xoffset { + Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym, n.Xoffset) + } if !strings.Contains(field.Note, "go:\"track\"") { return } @@ -3857,6 +3875,14 @@ func candiscard(n *Node) bool { // builtin(a1, a2, a3) // }(x, y, z) // for print, println, and delete. +// +// Rewrite +// go f(x, y, uintptr(unsafe.Pointer(z))) +// into +// go func(a1, a2, a3) { +// builtin(a1, a2, uintptr(a3)) +// }(x, y, unsafe.Pointer(z)) +// for function contains unsafe-uintptr arguments. var wrapCall_prgen int @@ -3868,9 +3894,27 @@ func wrapCall(n *Node, init *Nodes) *Node { init.AppendNodes(&n.Ninit) } + isBuiltinCall := n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER + + // Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e). + if !isBuiltinCall && n.IsDDD() { + last := n.List.Len() - 1 + if va := n.List.Index(last); va.Op == OSLICELIT { + n.List.Set(append(n.List.Slice()[:last], va.List.Slice()...)) + n.SetIsDDD(false) + } + } + + // origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion. + origArgs := make([]*Node, n.List.Len()) t := nod(OTFUNC, nil, nil) for i, arg := range n.List.Slice() { s := lookupN("a", i) + if !isBuiltinCall && arg.Op == OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() { + origArgs[i] = arg + arg = arg.Left + n.List.SetIndex(i, arg) + } t.List.Append(symfield(s, arg.Type)) } @@ -3878,10 +3922,23 @@ func wrapCall(n *Node, init *Nodes) *Node { sym := lookupN("wrap·", wrapCall_prgen) fn := dclfunc(sym, t) - a := nod(n.Op, nil, nil) - a.List.Set(paramNnames(t.Type)) - a = typecheck(a, ctxStmt) - fn.Nbody.Set1(a) + args := paramNnames(t.Type) + for i, origArg := range origArgs { + if origArg == nil { + continue + } + arg := nod(origArg.Op, args[i], nil) + arg.Type = origArg.Type + args[i] = arg + } + call := nod(n.Op, nil, nil) + if !isBuiltinCall { + call.Op = OCALL + call.Left = n.Left + call.SetIsDDD(n.IsDDD()) + } + call.List.Set(args) + fn.Nbody.Set1(call) funcbody() @@ -3889,12 +3946,12 @@ func wrapCall(n *Node, init *Nodes) *Node { typecheckslice(fn.Nbody.Slice(), ctxStmt) xtop = append(xtop, fn) - a = nod(OCALL, nil, nil) - a.Left = fn.Func.Nname - a.List.Set(n.List.Slice()) - a = typecheck(a, ctxStmt) - a = walkexpr(a, init) - return a + call = nod(OCALL, nil, nil) + call.Left = fn.Func.Nname + call.List.Set(n.List.Slice()) + call = typecheck(call, ctxStmt) + call = walkexpr(call, init) + return call } // substArgTypes substitutes the given list of types for @@ -3933,7 +3990,7 @@ func canMergeLoads() bool { // isRuneCount reports whether n is of the form len([]rune(string)). // These are optimized into a call to runtime.countrunes. func isRuneCount(n *Node) bool { - return Debug['N'] == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES + return Debug.N == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES } func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node { @@ -4002,14 +4059,10 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node { case OADD: walk(n.Left) walk(n.Right) - case OSUB: + case OSUB, OANDNOT: walk(n.Left) - case OAND: - if n.Implicit() { // was OANDNOT - walk(n.Left) - } case OCONVNOP: - if n.Left.Type.Etype == TUNSAFEPTR { + if n.Left.Type.IsUnsafePtr() { n.Left = cheapexpr(n.Left, init) originals = append(originals, convnop(n.Left, types.Types[TUNSAFEPTR])) } diff --git a/src/cmd/compile/internal/logopt/log_opts.go b/src/cmd/compile/internal/logopt/log_opts.go index 22a94b0f2d..37a049d640 100644 --- a/src/cmd/compile/internal/logopt/log_opts.go +++ b/src/cmd/compile/internal/logopt/log_opts.go @@ -19,6 +19,7 @@ import ( "strconv" "strings" "sync" + "unicode" ) // This implements (non)optimization logging for -json option to the Go compiler @@ -223,11 +224,11 @@ type Diagnostic struct { // A LoggedOpt is what the compiler produces and accumulates, // to be converted to JSON for human or IDE consumption. type LoggedOpt struct { - pos src.XPos // Source code position at which the event occurred. If it is inlined, outer and all inlined locations will appear in JSON. - pass string // For human/adhoc consumption; does not appear in JSON (yet) - fname string // For human/adhoc consumption; does not appear in JSON (yet) - what string // The (non) optimization; "nilcheck", "boundsCheck", "inline", "noInline" - target []interface{} // Optional target(s) or parameter(s) of "what" -- what was inlined, why it was not, size of copy, etc. 1st is most important/relevant. + pos src.XPos // Source code position at which the event occurred. If it is inlined, outer and all inlined locations will appear in JSON. + compilerPass string // Compiler pass. For human/adhoc consumption; does not appear in JSON (yet) + functionName string // Function name. For human/adhoc consumption; does not appear in JSON (yet) + what string // The (non) optimization; "nilcheck", "boundsCheck", "inline", "noInline" + target []interface{} // Optional target(s) or parameter(s) of "what" -- what was inlined, why it was not, size of copy, etc. 1st is most important/relevant. } type logFormat uint8 @@ -240,12 +241,13 @@ const ( var Format = None var dest string +// LogJsonOption parses and validates the version,directory value attached to the -json compiler flag. func LogJsonOption(flagValue string) { version, directory := parseLogFlag("json", flagValue) if version != 0 { log.Fatal("-json version must be 0") } - checkLogPath("json", directory) + dest = checkLogPath(directory) Format = Json0 } @@ -268,51 +270,80 @@ func parseLogFlag(flag, value string) (version int, directory string) { return } -// checkLogPath does superficial early checking of the string specifying -// the directory to which optimizer logging is directed, and if -// it passes the test, stores the string in LO_dir -func checkLogPath(flag, destination string) { - sep := string(os.PathSeparator) - if strings.HasPrefix(destination, "/") || strings.HasPrefix(destination, sep) { - err := os.MkdirAll(destination, 0755) - if err != nil { - log.Fatalf("optimizer logging destination '<version>,<directory>' but could not create <directory>: err=%v", err) - } - } else if strings.HasPrefix(destination, "file://") { // IKWIAD, or Windows C:\foo\bar\baz +// isWindowsDriveURI returns true if the file URI is of the format used by +// Windows URIs. The url.Parse package does not specially handle Windows paths +// (see golang/go#6027), so we check if the URI path has a drive prefix (e.g. "/C:"). +// (copied from tools/internal/span/uri.go) +// this is less comprehensive that the processing in filepath.IsAbs on Windows. +func isWindowsDriveURIPath(uri string) bool { + if len(uri) < 4 { + return false + } + return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':' +} + +func parseLogPath(destination string) (string, string) { + if filepath.IsAbs(destination) { + return filepath.Clean(destination), "" + } + if strings.HasPrefix(destination, "file://") { // IKWIAD, or Windows C:\foo\bar\baz uri, err := url.Parse(destination) if err != nil { - log.Fatalf("optimizer logging destination looked like file:// URI but failed to parse: err=%v", err) + return "", fmt.Sprintf("optimizer logging destination looked like file:// URI but failed to parse: err=%v", err) } destination = uri.Host + uri.Path - err = os.MkdirAll(destination, 0755) - if err != nil { - log.Fatalf("optimizer logging destination '<version>,<directory>' but could not create %s: err=%v", destination, err) + if isWindowsDriveURIPath(destination) { + // strip leading / from /C: + // unlike tools/internal/span/uri.go, do not uppercase the drive letter -- let filepath.Clean do what it does. + destination = destination[1:] } - } else { - log.Fatalf("optimizer logging destination %s was neither %s-prefixed directory nor file://-prefixed file URI", destination, sep) + return filepath.Clean(destination), "" + } + return "", fmt.Sprintf("optimizer logging destination %s was neither %s-prefixed directory nor file://-prefixed file URI", destination, string(filepath.Separator)) +} + +// checkLogPath does superficial early checking of the string specifying +// the directory to which optimizer logging is directed, and if +// it passes the test, stores the string in LO_dir +func checkLogPath(destination string) string { + path, complaint := parseLogPath(destination) + if complaint != "" { + log.Fatalf(complaint) + } + err := os.MkdirAll(path, 0755) + if err != nil { + log.Fatalf("optimizer logging destination '<version>,<directory>' but could not create <directory>: err=%v", err) } - dest = destination + return path } var loggedOpts []*LoggedOpt var mu = sync.Mutex{} // mu protects loggedOpts. -func NewLoggedOpt(pos src.XPos, what, pass, fname string, args ...interface{}) *LoggedOpt { +// NewLoggedOpt allocates a new LoggedOpt, to later be passed to either NewLoggedOpt or LogOpt as "args". +// Pos is the source position (including inlining), what is the message, pass is which pass created the message, +// funcName is the name of the function +// A typical use for this to accumulate an explanation for a missed optimization, for example, why did something escape? +func NewLoggedOpt(pos src.XPos, what, pass, funcName string, args ...interface{}) *LoggedOpt { pass = strings.Replace(pass, " ", "_", -1) - return &LoggedOpt{pos, pass, fname, what, args} + return &LoggedOpt{pos, pass, funcName, what, args} } -func LogOpt(pos src.XPos, what, pass, fname string, args ...interface{}) { +// Logopt logs information about a (usually missed) optimization performed by the compiler. +// Pos is the source position (including inlining), what is the message, pass is which pass created the message, +// funcName is the name of the function +func LogOpt(pos src.XPos, what, pass, funcName string, args ...interface{}) { if Format == None { return } - lo := NewLoggedOpt(pos, what, pass, fname, args...) + lo := NewLoggedOpt(pos, what, pass, funcName, args...) mu.Lock() defer mu.Unlock() // Because of concurrent calls from back end, no telling what the order will be, but is stable-sorted by outer Pos before use. loggedOpts = append(loggedOpts, lo) } +// Enabled returns whether optimization logging is enabled. func Enabled() bool { switch Format { case None: @@ -459,11 +490,13 @@ func FlushLoggedOpts(ctxt *obj.Link, slashPkgPath string) { } } +// newPointRange returns a single-position Range for the compiler source location p. func newPointRange(p src.Pos) Range { return Range{Start: Position{p.Line(), p.Col()}, End: Position{p.Line(), p.Col()}} } +// newLocation returns the Location for the compiler source location p func newLocation(p src.Pos) Location { loc := Location{URI: uriIfy(uprootedPath(p.Filename())), Range: newPointRange(p)} return loc diff --git a/src/cmd/compile/internal/logopt/logopt_test.go b/src/cmd/compile/internal/logopt/logopt_test.go index df3e70a614..e121c1abd2 100644 --- a/src/cmd/compile/internal/logopt/logopt_test.go +++ b/src/cmd/compile/internal/logopt/logopt_test.go @@ -51,7 +51,35 @@ func want(t *testing.T, out string, desired string) { func wantN(t *testing.T, out string, desired string, n int) { if strings.Count(out, desired) != n { - t.Errorf("expected exactly %d occurences of %s in \n%s", n, desired, out) + t.Errorf("expected exactly %d occurrences of %s in \n%s", n, desired, out) + } +} + +func TestPathStuff(t *testing.T) { + sep := string(filepath.Separator) + if path, whine := parseLogPath("file:///c:foo"); path != "c:foo" || whine != "" { // good path + t.Errorf("path='%s', whine='%s'", path, whine) + } + if path, whine := parseLogPath("file:///foo"); path != sep+"foo" || whine != "" { // good path + t.Errorf("path='%s', whine='%s'", path, whine) + } + if path, whine := parseLogPath("foo"); path != "" || whine == "" { // BAD path + t.Errorf("path='%s', whine='%s'", path, whine) + } + if sep == "\\" { // On WINDOWS ONLY + if path, whine := parseLogPath("C:/foo"); path != "C:\\foo" || whine != "" { // good path + t.Errorf("path='%s', whine='%s'", path, whine) + } + if path, whine := parseLogPath("c:foo"); path != "" || whine == "" { // BAD path + t.Errorf("path='%s', whine='%s'", path, whine) + } + if path, whine := parseLogPath("/foo"); path != "" || whine == "" { // BAD path + t.Errorf("path='%s', whine='%s'", path, whine) + } + } else { // ON UNIX ONLY + if path, whine := parseLogPath("/foo"); path != sep+"foo" || whine != "" { // good path + t.Errorf("path='%s', whine='%s'", path, whine) + } } } @@ -180,21 +208,20 @@ func s15a8(x *[15]int64) [15]int64 { `"relatedInformation":[{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"}]}`) want(t, slogged, `{"range":{"start":{"line":11,"character":6},"end":{"line":11,"character":6}},"severity":3,"code":"isInBounds","source":"go compiler","message":""}`) want(t, slogged, `{"range":{"start":{"line":7,"character":6},"end":{"line":7,"character":6}},"severity":3,"code":"canInlineFunction","source":"go compiler","message":"cost: 35"}`) - want(t, slogged, `{"range":{"start":{"line":21,"character":21},"end":{"line":21,"character":21}},"severity":3,"code":"cannotInlineCall","source":"go compiler","message":"foo cannot be inlined (escaping closure variable)"}`) // escape analysis explanation want(t, slogged, `{"range":{"start":{"line":7,"character":13},"end":{"line":7,"character":13}},"severity":3,"code":"leak","source":"go compiler","message":"parameter z leaks to ~r2 with derefs=0",`+ `"relatedInformation":[`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: flow: y = z:"},`+ - `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from y = \u003cN\u003e (assign-pair)"},`+ - `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: flow: ~r1 = y:"},`+ + `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from y := z (assign-pair)"},`+ + `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: flow: ~R0 = y:"},`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"},`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from y.b (dot of pointer)"},`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"},`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from \u0026y.b (address-of)"},`+ `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":9},"end":{"line":4,"character":9}}},"message":"inlineLoc"},`+ - `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from ~r1 = \u003cN\u003e (assign-pair)"},`+ - `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: flow: ~r2 = ~r1:"},`+ - `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: from return (*int)(~r1) (return)"}]}`) + `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}}},"message":"escflow: from ~R0 = \u003cN\u003e (assign-pair)"},`+ + `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: flow: ~r2 = ~R0:"},`+ + `{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":9,"character":3},"end":{"line":9,"character":3}}},"message":"escflow: from return (*int)(~R0) (return)"}]}`) }) } diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go index f8d9ac2379..3e20c44a4c 100644 --- a/src/cmd/compile/internal/ppc64/ssa.go +++ b/src/cmd/compile/internal/ppc64/ssa.go @@ -166,34 +166,46 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p2.To.Reg = v.Reg1() case ssa.OpPPC64LoweredAtomicAnd8, - ssa.OpPPC64LoweredAtomicOr8: + ssa.OpPPC64LoweredAtomicAnd32, + ssa.OpPPC64LoweredAtomicOr8, + ssa.OpPPC64LoweredAtomicOr32: // LWSYNC - // LBAR (Rarg0), Rtmp + // LBAR/LWAR (Rarg0), Rtmp // AND/OR Rarg1, Rtmp - // STBCCC Rtmp, (Rarg0) + // STBCCC/STWCCC Rtmp, (Rarg0) // BNE -3(PC) + ld := ppc64.ALBAR + st := ppc64.ASTBCCC + if v.Op == ssa.OpPPC64LoweredAtomicAnd32 || v.Op == ssa.OpPPC64LoweredAtomicOr32 { + ld = ppc64.ALWAR + st = ppc64.ASTWCCC + } r0 := v.Args[0].Reg() r1 := v.Args[1].Reg() // LWSYNC - Assuming shared data not write-through-required nor // caching-inhibited. See Appendix B.2.2.2 in the ISA 2.07b. plwsync := s.Prog(ppc64.ALWSYNC) plwsync.To.Type = obj.TYPE_NONE - p := s.Prog(ppc64.ALBAR) + // LBAR or LWAR + p := s.Prog(ld) p.From.Type = obj.TYPE_MEM p.From.Reg = r0 p.To.Type = obj.TYPE_REG p.To.Reg = ppc64.REGTMP + // AND/OR reg1,out p1 := s.Prog(v.Op.Asm()) p1.From.Type = obj.TYPE_REG p1.From.Reg = r1 p1.To.Type = obj.TYPE_REG p1.To.Reg = ppc64.REGTMP - p2 := s.Prog(ppc64.ASTBCCC) + // STBCCC or STWCCC + p2 := s.Prog(st) p2.From.Type = obj.TYPE_REG p2.From.Reg = ppc64.REGTMP p2.To.Type = obj.TYPE_MEM p2.To.Reg = r0 p2.RegTo2 = ppc64.REGTMP + // BNE retry p3 := s.Prog(ppc64.ABNE) p3.To.Type = obj.TYPE_BRANCH gc.Patch(p3, p) @@ -565,6 +577,42 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p = s.Prog(obj.ANOP) gc.Patch(pbover, p) + case ssa.OpPPC64CLRLSLWI: + r := v.Reg() + r1 := v.Args[0].Reg() + shifts := v.AuxInt + p := s.Prog(v.Op.Asm()) + // clrlslwi ra,rs,mb,sh will become rlwinm ra,rs,sh,mb-sh,31-sh as described in ISA + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}) + p.Reg = r1 + p.To.Type = obj.TYPE_REG + p.To.Reg = r + + case ssa.OpPPC64CLRLSLDI: + r := v.Reg() + r1 := v.Args[0].Reg() + shifts := v.AuxInt + p := s.Prog(v.Op.Asm()) + // clrlsldi ra,rs,mb,sh will become rldic ra,rs,sh,mb-sh + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}) + p.Reg = r1 + p.To.Type = obj.TYPE_REG + p.To.Reg = r + + // Mask has been set as sh + case ssa.OpPPC64RLDICL: + r := v.Reg() + r1 := v.Args[0].Reg() + shifts := v.AuxInt + p := s.Prog(v.Op.Asm()) + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}) + p.Reg = r1 + p.To.Type = obj.TYPE_REG + p.To.Reg = r + case ssa.OpPPC64ADD, ssa.OpPPC64FADD, ssa.OpPPC64FADDS, ssa.OpPPC64SUB, ssa.OpPPC64FSUB, ssa.OpPPC64FSUBS, ssa.OpPPC64MULLD, ssa.OpPPC64MULLW, ssa.OpPPC64DIVDU, ssa.OpPPC64DIVWU, ssa.OpPPC64SRAD, ssa.OpPPC64SRAW, ssa.OpPPC64SRD, ssa.OpPPC64SRW, ssa.OpPPC64SLD, ssa.OpPPC64SLW, @@ -601,6 +649,24 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() + // Auxint holds encoded rotate + mask + case ssa.OpPPC64RLWINM, ssa.OpPPC64RLWMI: + rot, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt) + p := s.Prog(v.Op.Asm()) + p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()} + p.Reg = v.Args[0].Reg() + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(mask)}) + + // Auxint holds mask + case ssa.OpPPC64RLWNM: + _, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt) + p := s.Prog(v.Op.Asm()) + p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()} + p.Reg = v.Args[0].Reg() + p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(mask)}) + case ssa.OpPPC64MADDLD: r := v.Reg() r1 := v.Args[0].Reg() @@ -641,7 +707,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Reg = v.Args[0].Reg() case ssa.OpPPC64ADDconst, ssa.OpPPC64ANDconst, ssa.OpPPC64ORconst, ssa.OpPPC64XORconst, - ssa.OpPPC64SRADconst, ssa.OpPPC64SRAWconst, ssa.OpPPC64SRDconst, ssa.OpPPC64SRWconst, ssa.OpPPC64SLDconst, ssa.OpPPC64SLWconst: + ssa.OpPPC64SRADconst, ssa.OpPPC64SRAWconst, ssa.OpPPC64SRDconst, ssa.OpPPC64SRWconst, + ssa.OpPPC64SLDconst, ssa.OpPPC64SLWconst, ssa.OpPPC64EXTSWSLconst, ssa.OpPPC64MULLWconst, ssa.OpPPC64MULLDconst: p := s.Prog(v.Op.Asm()) p.Reg = v.Args[0].Reg() p.From.Type = obj.TYPE_CONST @@ -1714,6 +1781,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { pp := s.Call(v) pp.To.Reg = ppc64.REG_LR + // Insert a hint this is not a subroutine return. + pp.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 1}) + if gc.Ctxt.Flag_shared { // When compiling Go into PIC, the function we just // called via pointer might have been implemented in diff --git a/src/cmd/compile/internal/riscv64/ggen.go b/src/cmd/compile/internal/riscv64/ggen.go index be31fad441..f7c03fe7c2 100644 --- a/src/cmd/compile/internal/riscv64/ggen.go +++ b/src/cmd/compile/internal/riscv64/ggen.go @@ -25,7 +25,15 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog { return p } - // TODO(jsing): Add a duff zero implementation for medium sized ranges. + if cnt <= int64(128*gc.Widthptr) { + p = pp.Appendpp(p, riscv.AADDI, obj.TYPE_CONST, 0, off, obj.TYPE_REG, riscv.REG_A0, 0) + p.Reg = riscv.REG_SP + p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) + p.To.Name = obj.NAME_EXTERN + p.To.Sym = gc.Duffzero + p.To.Offset = 8 * (128 - cnt/int64(gc.Widthptr)) + return p + } // Loop, zeroing pointer width bytes at a time. // ADD $(off), SP, T0 diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go index 73f0dbc195..0beb5b4bd1 100644 --- a/src/cmd/compile/internal/riscv64/ssa.go +++ b/src/cmd/compile/internal/riscv64/ssa.go @@ -190,7 +190,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { // input args need no code case ssa.OpPhi: gc.CheckLoweredPhi(v) - case ssa.OpCopy, ssa.OpRISCV64MOVconvert: + case ssa.OpCopy, ssa.OpRISCV64MOVconvert, ssa.OpRISCV64MOVDreg: if v.Type.IsMemory() { return } @@ -208,6 +208,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Reg = rs p.To.Type = obj.TYPE_REG p.To.Reg = rd + case ssa.OpRISCV64MOVDnop: + if v.Reg() != v.Args[0].Reg() { + v.Fatalf("input[0] and output not in same register %s", v.LongString()) + } + // nothing to do case ssa.OpLoadReg: if v.Type.IsFlags() { v.Fatalf("load flags not implemented: %v", v.LongString()) @@ -228,6 +233,37 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { gc.AddrAuto(&p.To, v) case ssa.OpSP, ssa.OpSB, ssa.OpGetG: // nothing to do + case ssa.OpRISCV64MOVBreg, ssa.OpRISCV64MOVHreg, ssa.OpRISCV64MOVWreg, + ssa.OpRISCV64MOVBUreg, ssa.OpRISCV64MOVHUreg, ssa.OpRISCV64MOVWUreg: + a := v.Args[0] + for a.Op == ssa.OpCopy || a.Op == ssa.OpRISCV64MOVDreg { + a = a.Args[0] + } + as := v.Op.Asm() + rs := v.Args[0].Reg() + rd := v.Reg() + if a.Op == ssa.OpLoadReg { + t := a.Type + switch { + case v.Op == ssa.OpRISCV64MOVBreg && t.Size() == 1 && t.IsSigned(), + v.Op == ssa.OpRISCV64MOVHreg && t.Size() == 2 && t.IsSigned(), + v.Op == ssa.OpRISCV64MOVWreg && t.Size() == 4 && t.IsSigned(), + v.Op == ssa.OpRISCV64MOVBUreg && t.Size() == 1 && !t.IsSigned(), + v.Op == ssa.OpRISCV64MOVHUreg && t.Size() == 2 && !t.IsSigned(), + v.Op == ssa.OpRISCV64MOVWUreg && t.Size() == 4 && !t.IsSigned(): + // arg is a proper-typed load and already sign/zero-extended + if rs == rd { + return + } + as = riscv.AMOV + default: + } + } + p := s.Prog(as) + p.From.Type = obj.TYPE_REG + p.From.Reg = rs + p.To.Type = obj.TYPE_REG + p.To.Reg = rd case ssa.OpRISCV64ADD, ssa.OpRISCV64SUB, ssa.OpRISCV64SUBW, ssa.OpRISCV64XOR, ssa.OpRISCV64OR, ssa.OpRISCV64AND, ssa.OpRISCV64SLL, ssa.OpRISCV64SRA, ssa.OpRISCV64SRL, ssa.OpRISCV64SLT, ssa.OpRISCV64SLTU, ssa.OpRISCV64MUL, ssa.OpRISCV64MULW, ssa.OpRISCV64MULH, @@ -572,6 +608,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() + case ssa.OpRISCV64DUFFZERO: + p := s.Prog(obj.ADUFFZERO) + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_EXTERN + p.To.Sym = gc.Duffzero + p.To.Offset = v.AuxInt + + case ssa.OpRISCV64DUFFCOPY: + p := s.Prog(obj.ADUFFCOPY) + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_EXTERN + p.To.Sym = gc.Duffcopy + p.To.Offset = v.AuxInt + default: v.Fatalf("Unhandled op %v", v.Op) } diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go index 00d253c95a..8037357131 100644 --- a/src/cmd/compile/internal/s390x/ssa.go +++ b/src/cmd/compile/internal/s390x/ssa.go @@ -182,11 +182,23 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { i := v.Aux.(s390x.RotateParams) p := s.Prog(v.Op.Asm()) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)} - p.RestArgs = []obj.Addr{ + p.SetRestArgs([]obj.Addr{ {Type: obj.TYPE_CONST, Offset: int64(i.End)}, {Type: obj.TYPE_CONST, Offset: int64(i.Amount)}, {Type: obj.TYPE_REG, Reg: r2}, - } + }) + p.To = obj.Addr{Type: obj.TYPE_REG, Reg: r1} + case ssa.OpS390XRISBGZ: + r1 := v.Reg() + r2 := v.Args[0].Reg() + i := v.Aux.(s390x.RotateParams) + p := s.Prog(v.Op.Asm()) + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(i.Start)} + p.SetRestArgs([]obj.Addr{ + {Type: obj.TYPE_CONST, Offset: int64(i.End)}, + {Type: obj.TYPE_CONST, Offset: int64(i.Amount)}, + {Type: obj.TYPE_REG, Reg: r2}, + }) p.To = obj.Addr{Type: obj.TYPE_REG, Reg: r1} case ssa.OpS390XADD, ssa.OpS390XADDW, ssa.OpS390XSUB, ssa.OpS390XSUBW, @@ -360,7 +372,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { case ssa.OpS390XSLDconst, ssa.OpS390XSLWconst, ssa.OpS390XSRDconst, ssa.OpS390XSRWconst, ssa.OpS390XSRADconst, ssa.OpS390XSRAWconst, - ssa.OpS390XRLLGconst, ssa.OpS390XRLLconst: + ssa.OpS390XRLLconst: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_CONST p.From.Offset = v.AuxInt @@ -761,6 +773,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_MEM p.To.Reg = v.Args[0].Reg() gc.AddAux(&p.To, v) + case ssa.OpS390XLAN, ssa.OpS390XLAO: + // LA(N|O) Ry, TMP, 0(Rx) + op := s.Prog(v.Op.Asm()) + op.From.Type = obj.TYPE_REG + op.From.Reg = v.Args[1].Reg() + op.Reg = s390x.REGTMP + op.To.Type = obj.TYPE_MEM + op.To.Reg = v.Args[0].Reg() case ssa.OpS390XLANfloor, ssa.OpS390XLAOfloor: r := v.Args[0].Reg() // clobbered, assumed R1 in comments @@ -905,7 +925,7 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) { p.From.Type = obj.TYPE_CONST p.From.Offset = int64(s390x.NotEqual & s390x.NotUnordered) // unordered is not possible p.Reg = s390x.REG_R3 - p.RestArgs = []obj.Addr{{Type: obj.TYPE_CONST, Offset: 0}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 0}) if b.Succs[0].Block() != next { s.Br(s390x.ABR, b.Succs[0].Block()) } @@ -948,17 +968,17 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) { p.From.Type = obj.TYPE_CONST p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible p.Reg = b.Controls[0].Reg() - p.RestArgs = []obj.Addr{{Type: obj.TYPE_REG, Reg: b.Controls[1].Reg()}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: b.Controls[1].Reg()}) case ssa.BlockS390XCGIJ, ssa.BlockS390XCIJ: p.From.Type = obj.TYPE_CONST p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible p.Reg = b.Controls[0].Reg() - p.RestArgs = []obj.Addr{{Type: obj.TYPE_CONST, Offset: int64(int8(b.AuxInt))}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(int8(b.AuxInt))}) case ssa.BlockS390XCLGIJ, ssa.BlockS390XCLIJ: p.From.Type = obj.TYPE_CONST p.From.Offset = int64(mask & s390x.NotUnordered) // unordered is not possible p.Reg = b.Controls[0].Reg() - p.RestArgs = []obj.Addr{{Type: obj.TYPE_CONST, Offset: int64(uint8(b.AuxInt))}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: int64(uint8(b.AuxInt))}) default: b.Fatalf("branch not implemented: %s", b.LongString()) } diff --git a/src/cmd/compile/internal/ssa/addressingmodes.go b/src/cmd/compile/internal/ssa/addressingmodes.go index aae0def27f..1baf143869 100644 --- a/src/cmd/compile/internal/ssa/addressingmodes.go +++ b/src/cmd/compile/internal/ssa/addressingmodes.go @@ -59,22 +59,22 @@ func addressingModes(f *Func) { v.AuxInt += p.AuxInt case [2]auxType{auxSymValAndOff, auxInt32}: vo := ValAndOff(v.AuxInt) - if !vo.canAdd(p.AuxInt) { + if !vo.canAdd64(p.AuxInt) { continue } - v.AuxInt = vo.add(p.AuxInt) + v.AuxInt = int64(vo.addOffset64(p.AuxInt)) case [2]auxType{auxSymValAndOff, auxSymOff}: vo := ValAndOff(v.AuxInt) if v.Aux != nil && p.Aux != nil { continue } - if !vo.canAdd(p.AuxInt) { + if !vo.canAdd64(p.AuxInt) { continue } if p.Aux != nil { v.Aux = p.Aux } - v.AuxInt = vo.add(p.AuxInt) + v.AuxInt = int64(vo.addOffset64(p.AuxInt)) case [2]auxType{auxSymOff, auxNone}: // nothing to do case [2]auxType{auxSymValAndOff, auxNone}: diff --git a/src/cmd/compile/internal/ssa/branchelim.go b/src/cmd/compile/internal/ssa/branchelim.go index 4f9fd8e22e..1d34f8160b 100644 --- a/src/cmd/compile/internal/ssa/branchelim.go +++ b/src/cmd/compile/internal/ssa/branchelim.go @@ -35,7 +35,7 @@ func branchelim(f *Func) { for _, b := range f.Blocks { for _, v := range b.Values { switch v.Op { - case OpLoad, OpAtomicLoad8, OpAtomicLoad32, OpAtomicLoad64, OpAtomicLoadPtr, OpAtomicLoadAcq32: + case OpLoad, OpAtomicLoad8, OpAtomicLoad32, OpAtomicLoad64, OpAtomicLoadPtr, OpAtomicLoadAcq32, OpAtomicLoadAcq64: loadAddr.add(v.Args[0].ID) case OpMove: loadAddr.add(v.Args[1].ID) diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go index 828f645b39..5f5dfc328a 100644 --- a/src/cmd/compile/internal/ssa/check.go +++ b/src/cmd/compile/internal/ssa/check.go @@ -165,6 +165,18 @@ func checkFunc(f *Func) { f.Fatalf("value %v has Aux type %T, want string", v, v.Aux) } canHaveAux = true + case auxCallOff: + canHaveAuxInt = true + fallthrough + case auxCall: + if ac, ok := v.Aux.(*AuxCall); ok { + if v.Op == OpStaticCall && ac.Fn == nil { + f.Fatalf("value %v has *AuxCall with nil Fn", v) + } + } else { + f.Fatalf("value %v has Aux type %T, want *AuxCall", v, v.Aux) + } + canHaveAux = true case auxSym, auxTyp: canHaveAux = true case auxSymOff, auxSymValAndOff, auxTypSize: @@ -257,6 +269,38 @@ func checkFunc(f *Func) { f.Fatalf("bad %s type: want uintptr, have %s", v.Op, v.Type.String()) } + case OpStringLen: + if v.Type != c.Types.Int { + f.Fatalf("bad %s type: want int, have %s", + v.Op, v.Type.String()) + } + case OpLoad: + if !v.Args[1].Type.IsMemory() { + f.Fatalf("bad arg 1 type to %s: want mem, have %s", + v.Op, v.Args[1].Type.String()) + } + case OpStore: + if !v.Type.IsMemory() { + f.Fatalf("bad %s type: want mem, have %s", + v.Op, v.Type.String()) + } + if !v.Args[2].Type.IsMemory() { + f.Fatalf("bad arg 2 type to %s: want mem, have %s", + v.Op, v.Args[2].Type.String()) + } + case OpCondSelect: + if !v.Args[2].Type.IsBoolean() { + f.Fatalf("bad arg 2 type to %s: want boolean, have %s", + v.Op, v.Args[2].Type.String()) + } + case OpAddPtr: + if !v.Args[0].Type.IsPtrShaped() && v.Args[0].Type != c.Types.Uintptr { + f.Fatalf("bad arg 0 type to %s: want ptr, have %s", v.Op, v.Args[0].LongString()) + } + if !v.Args[1].Type.IsInteger() { + f.Fatalf("bad arg 1 type to %s: want integer, have %s", v.Op, v.Args[1].LongString()) + } + } // TODO: check for cycles in values diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index 444475d67a..63994d1778 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -47,6 +47,9 @@ func Compile(f *Func) { stack := make([]byte, 16384) n := runtime.Stack(stack, false) stack = stack[:n] + if f.HTMLWriter != nil { + f.HTMLWriter.flushPhases() + } f.Fatalf("panic during %s while compiling %s:\n\n%v\n\n%s\n", phaseName, f.Name, err, stack) } }() @@ -201,6 +204,13 @@ func (p *pass) addDump(s string) { p.dump[s] = true } +func (p *pass) String() string { + if p == nil { + return "nil pass" + } + return p.name +} + // Run consistency checker between each phase var ( checkEnabled = false @@ -294,37 +304,39 @@ commas. For example: ` } - if phase == "check" && flag == "on" { - checkEnabled = val != 0 - debugPoset = checkEnabled // also turn on advanced self-checking in prove's datastructure - return "" - } - if phase == "check" && flag == "off" { - checkEnabled = val == 0 - debugPoset = checkEnabled - return "" - } - if phase == "check" && flag == "seed" { - checkEnabled = true - checkRandSeed = val - debugPoset = checkEnabled - return "" + if phase == "check" { + switch flag { + case "on": + checkEnabled = val != 0 + debugPoset = checkEnabled // also turn on advanced self-checking in prove's datastructure + return "" + case "off": + checkEnabled = val == 0 + debugPoset = checkEnabled + return "" + case "seed": + checkEnabled = true + checkRandSeed = val + debugPoset = checkEnabled + return "" + } } alltime := false allmem := false alldump := false if phase == "all" { - if flag == "time" { + switch flag { + case "time": alltime = val != 0 - } else if flag == "mem" { + case "mem": allmem = val != 0 - } else if flag == "dump" { + case "dump": alldump = val != 0 if alldump { BuildDump = valString } - } else { + default: return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase) } } @@ -419,7 +431,7 @@ var passes = [...]pass{ {name: "early copyelim", fn: copyelim}, {name: "early deadcode", fn: deadcode}, // remove generated dead code to avoid doing pointless work during opt {name: "short circuit", fn: shortcircuit}, - {name: "decompose args", fn: decomposeArgs, required: true}, + {name: "decompose args", fn: decomposeArgs, required: !go116lateCallExpansion, disabled: go116lateCallExpansion}, // handled by late call lowering {name: "decompose user", fn: decomposeUser, required: true}, {name: "pre-opt deadcode", fn: deadcode}, {name: "opt", fn: opt, required: true}, // NB: some generic rules know the name of the opt pass. TODO: split required rules and optimizing rules @@ -432,6 +444,7 @@ var passes = [...]pass{ {name: "prove", fn: prove}, {name: "early fuse", fn: fuseEarly}, {name: "decompose builtin", fn: decomposeBuiltIn, required: true}, + {name: "expand calls", fn: expandCalls, required: true}, {name: "softfloat", fn: softfloat, required: true}, {name: "late opt", fn: opt, required: true}, // TODO: split required rules and optimizing rules {name: "dead auto elim", fn: elimDeadAutosGeneric}, diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go index 4b2f06def1..0fe0337ddf 100644 --- a/src/cmd/compile/internal/ssa/config.go +++ b/src/cmd/compile/internal/ssa/config.go @@ -38,7 +38,6 @@ type Config struct { useSSE bool // Use SSE for non-float operations useAvg bool // Use optimizations that need Avg* operations useHmul bool // Use optimizations that need Hmul* operations - use387 bool // GO386=387 SoftFloat bool // Race bool // race detector enabled NeedsFpScratch bool // No direct move between GP and FP register sets @@ -150,6 +149,7 @@ type Frontend interface { SplitStruct(LocalSlot, int) LocalSlot SplitArray(LocalSlot) LocalSlot // array must be length 1 SplitInt64(LocalSlot) (LocalSlot, LocalSlot) // returns (hi, lo) + SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot // DerefItab dereferences an itab function // entry, given the symbol of the itab and @@ -196,6 +196,14 @@ const ( ClassParamOut // return value ) +const go116lateCallExpansion = true + +// LateCallExpansionEnabledWithin returns true if late call expansion should be tested +// within compilation of a function/method. +func LateCallExpansionEnabledWithin(f *Func) bool { + return go116lateCallExpansion +} + // NewConfig returns a new configuration object for the given architecture. func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config { c := &Config{arch: arch, Types: types} @@ -248,7 +256,7 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config c.FPReg = framepointerRegARM64 c.LinkReg = linkRegARM64 c.hasGReg = true - c.noDuffDevice = objabi.GOOS == "darwin" // darwin linker cannot handle BR26 reloc with non-zero addend + c.noDuffDevice = objabi.GOOS == "darwin" || objabi.GOOS == "ios" // darwin linker cannot handle BR26 reloc with non-zero addend case "ppc64": c.BigEndian = true fallthrough @@ -379,9 +387,4 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config return c } -func (c *Config) Set387(b bool) { - c.NeedsFpScratch = b - c.use387 = b -} - func (c *Config) Ctxt() *obj.Link { return c.ctxt } diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go index ab27ba85ae..bf7f1e826b 100644 --- a/src/cmd/compile/internal/ssa/decompose.go +++ b/src/cmd/compile/internal/ssa/decompose.go @@ -6,6 +6,7 @@ package ssa import ( "cmd/compile/internal/types" + "sort" ) // decompose converts phi ops on compound builtin types into phi @@ -31,77 +32,79 @@ func decomposeBuiltIn(f *Func) { } // Split up named values into their components. + // accumulate old names for aggregates (that are decomposed) in toDelete for efficient bulk deletion, + // accumulate new LocalSlots in newNames for addition after the iteration. This decomposition is for + // builtin types with leaf components, and thus there is no need to reprocess the newly create LocalSlots. + var toDelete []namedVal var newNames []LocalSlot - for _, name := range f.Names { + for i, name := range f.Names { t := name.Type switch { case t.IsInteger() && t.Size() > f.Config.RegSize: hiName, loName := f.fe.SplitInt64(name) newNames = append(newNames, hiName, loName) - for _, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[name] { if v.Op != OpInt64Make { continue } f.NamedValues[hiName] = append(f.NamedValues[hiName], v.Args[0]) f.NamedValues[loName] = append(f.NamedValues[loName], v.Args[1]) + toDelete = append(toDelete, namedVal{i, j}) } - delete(f.NamedValues, name) case t.IsComplex(): rName, iName := f.fe.SplitComplex(name) newNames = append(newNames, rName, iName) - for _, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[name] { if v.Op != OpComplexMake { continue } f.NamedValues[rName] = append(f.NamedValues[rName], v.Args[0]) f.NamedValues[iName] = append(f.NamedValues[iName], v.Args[1]) - + toDelete = append(toDelete, namedVal{i, j}) } - delete(f.NamedValues, name) case t.IsString(): ptrName, lenName := f.fe.SplitString(name) newNames = append(newNames, ptrName, lenName) - for _, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[name] { if v.Op != OpStringMake { continue } f.NamedValues[ptrName] = append(f.NamedValues[ptrName], v.Args[0]) f.NamedValues[lenName] = append(f.NamedValues[lenName], v.Args[1]) + toDelete = append(toDelete, namedVal{i, j}) } - delete(f.NamedValues, name) case t.IsSlice(): ptrName, lenName, capName := f.fe.SplitSlice(name) newNames = append(newNames, ptrName, lenName, capName) - for _, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[name] { if v.Op != OpSliceMake { continue } f.NamedValues[ptrName] = append(f.NamedValues[ptrName], v.Args[0]) f.NamedValues[lenName] = append(f.NamedValues[lenName], v.Args[1]) f.NamedValues[capName] = append(f.NamedValues[capName], v.Args[2]) + toDelete = append(toDelete, namedVal{i, j}) } - delete(f.NamedValues, name) case t.IsInterface(): typeName, dataName := f.fe.SplitInterface(name) newNames = append(newNames, typeName, dataName) - for _, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[name] { if v.Op != OpIMake { continue } f.NamedValues[typeName] = append(f.NamedValues[typeName], v.Args[0]) f.NamedValues[dataName] = append(f.NamedValues[dataName], v.Args[1]) + toDelete = append(toDelete, namedVal{i, j}) } - delete(f.NamedValues, name) case t.IsFloat(): // floats are never decomposed, even ones bigger than RegSize - newNames = append(newNames, name) case t.Size() > f.Config.RegSize: f.Fatalf("undecomposed named type %s %v", name, t) - default: - newNames = append(newNames, name) } } - f.Names = newNames + + deleteNamedVals(f, toDelete) + f.Names = append(f.Names, newNames...) } func decomposeBuiltInPhi(v *Value) { @@ -263,14 +266,20 @@ func decomposeUserArrayInto(f *Func, name LocalSlot, slots []LocalSlot) []LocalS f.Fatalf("array not of size 1") } elemName := f.fe.SplitArray(name) + var keep []*Value for _, v := range f.NamedValues[name] { if v.Op != OpArrayMake1 { + keep = append(keep, v) continue } f.NamedValues[elemName] = append(f.NamedValues[elemName], v.Args[0]) } - // delete the name for the array as a whole - delete(f.NamedValues, name) + if len(keep) == 0 { + // delete the name for the array as a whole + delete(f.NamedValues, name) + } else { + f.NamedValues[name] = keep + } if t.Elem().IsArray() { return decomposeUserArrayInto(f, elemName, slots) @@ -300,17 +309,23 @@ func decomposeUserStructInto(f *Func, name LocalSlot, slots []LocalSlot) []Local } makeOp := StructMakeOp(n) + var keep []*Value // create named values for each struct field for _, v := range f.NamedValues[name] { if v.Op != makeOp { + keep = append(keep, v) continue } for i := 0; i < len(fnames); i++ { f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], v.Args[i]) } } - // remove the name of the struct as a whole - delete(f.NamedValues, name) + if len(keep) == 0 { + // delete the name for the struct as a whole + delete(f.NamedValues, name) + } else { + f.NamedValues[name] = keep + } // now that this f.NamedValues contains values for the struct // fields, recurse into nested structs @@ -400,3 +415,35 @@ func StructMakeOp(nf int) Op { } panic("too many fields in an SSAable struct") } + +type namedVal struct { + locIndex, valIndex int // f.NamedValues[f.Names[locIndex]][valIndex] = key +} + +// deleteNamedVals removes particular values with debugger names from f's naming data structures +func deleteNamedVals(f *Func, toDelete []namedVal) { + // Arrange to delete from larger indices to smaller, to ensure swap-with-end deletion does not invalid pending indices. + sort.Slice(toDelete, func(i, j int) bool { + if toDelete[i].locIndex != toDelete[j].locIndex { + return toDelete[i].locIndex > toDelete[j].locIndex + } + return toDelete[i].valIndex > toDelete[j].valIndex + + }) + + // Get rid of obsolete names + for _, d := range toDelete { + loc := f.Names[d.locIndex] + vals := f.NamedValues[loc] + l := len(vals) - 1 + if l > 0 { + vals[d.valIndex] = vals[l] + f.NamedValues[loc] = vals[:l] + } else { + delete(f.NamedValues, loc) + l = len(f.Names) - 1 + f.Names[d.locIndex] = f.Names[l] + f.Names = f.Names[:l] + } + } +} diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go new file mode 100644 index 0000000000..fbde19d94c --- /dev/null +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -0,0 +1,974 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import ( + "cmd/compile/internal/types" + "cmd/internal/src" + "fmt" + "sort" +) + +type selKey struct { + from *Value + offset int64 + size int64 + typ *types.Type +} + +type offsetKey struct { + from *Value + offset int64 + pt *types.Type +} + +// expandCalls converts LE (Late Expansion) calls that act like they receive value args into a lower-level form +// that is more oriented to a platform's ABI. The SelectN operations that extract results are rewritten into +// more appropriate forms, and any StructMake or ArrayMake inputs are decomposed until non-struct values are +// reached. On the callee side, OpArg nodes are not decomposed until this phase is run. +// TODO results should not be lowered until this phase. +func expandCalls(f *Func) { + // Calls that need lowering have some number of inputs, including a memory input, + // and produce a tuple of (value1, value2, ..., mem) where valueK may or may not be SSA-able. + + // With the current ABI those inputs need to be converted into stores to memory, + // rethreading the call's memory input to the first, and the new call now receiving the last. + + // With the current ABI, the outputs need to be converted to loads, which will all use the call's + // memory output as their input. + if !LateCallExpansionEnabledWithin(f) { + return + } + debug := f.pass.debug > 0 + + if debug { + fmt.Printf("\nexpandsCalls(%s)\n", f.Name) + } + + canSSAType := f.fe.CanSSA + regSize := f.Config.RegSize + sp, _ := f.spSb() + typ := &f.Config.Types + ptrSize := f.Config.PtrSize + + // For 32-bit, need to deal with decomposition of 64-bit integers, which depends on endianness. + var hiOffset, lowOffset int64 + if f.Config.BigEndian { + lowOffset = 4 + } else { + hiOffset = 4 + } + + namedSelects := make(map[*Value][]namedVal) + + sdom := f.Sdom() + + common := make(map[selKey]*Value) + + // intPairTypes returns the pair of 32-bit int types needed to encode a 64-bit integer type on a target + // that has no 64-bit integer registers. + intPairTypes := func(et types.EType) (tHi, tLo *types.Type) { + tHi = typ.UInt32 + if et == types.TINT64 { + tHi = typ.Int32 + } + tLo = typ.UInt32 + return + } + + // isAlreadyExpandedAggregateType returns whether a type is an SSA-able "aggregate" (multiple register) type + // that was expanded in an earlier phase (currently, expand_calls is intended to run after decomposeBuiltin, + // so this is all aggregate types -- small struct and array, complex, interface, string, slice, and 64-bit + // integer on 32-bit). + isAlreadyExpandedAggregateType := func(t *types.Type) bool { + if !canSSAType(t) { + return false + } + return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice() || + t.Size() > regSize && t.IsInteger() + } + + offsets := make(map[offsetKey]*Value) + + // offsetFrom creates an offset from a pointer, simplifying chained offsets and offsets from SP + // TODO should also optimize offsets from SB? + offsetFrom := func(from *Value, offset int64, pt *types.Type) *Value { + if offset == 0 && from.Type == pt { // this is not actually likely + return from + } + // Simplify, canonicalize + for from.Op == OpOffPtr { + offset += from.AuxInt + from = from.Args[0] + } + if from == sp { + return f.ConstOffPtrSP(pt, offset, sp) + } + key := offsetKey{from, offset, pt} + v := offsets[key] + if v != nil { + return v + } + v = from.Block.NewValue1I(from.Pos.WithNotStmt(), OpOffPtr, pt, offset, from) + offsets[key] = v + return v + } + + // splitSlots splits one "field" (specified by sfx, offset, and ty) out of the LocalSlots in ls and returns the new LocalSlots this generates. + splitSlots := func(ls []LocalSlot, sfx string, offset int64, ty *types.Type) []LocalSlot { + var locs []LocalSlot + for i := range ls { + locs = append(locs, f.fe.SplitSlot(&ls[i], sfx, offset, ty)) + } + return locs + } + + // removeTrivialWrapperTypes unwraps layers of + // struct { singleField SomeType } and [1]SomeType + // until a non-wrapper type is reached. This is useful + // for working with assignments to/from interface data + // fields (either second operand to OpIMake or OpIData) + // where the wrapping or type conversion can be elided + // because of type conversions/assertions in source code + // that do not appear in SSA. + removeTrivialWrapperTypes := func(t *types.Type) *types.Type { + for { + if t.IsStruct() && t.NumFields() == 1 { + t = t.Field(0).Type + continue + } + if t.IsArray() && t.NumElem() == 1 { + t = t.Elem() + continue + } + break + } + return t + } + + // Calls that need lowering have some number of inputs, including a memory input, + // and produce a tuple of (value1, value2, ..., mem) where valueK may or may not be SSA-able. + + // With the current ABI those inputs need to be converted into stores to memory, + // rethreading the call's memory input to the first, and the new call now receiving the last. + + // With the current ABI, the outputs need to be converted to loads, which will all use the call's + // memory output as their input. + + // rewriteSelect recursively walks from leaf selector to a root (OpSelectN, OpLoad, OpArg) + // through a chain of Struct/Array/builtin Select operations. If the chain of selectors does not + // end in an expected root, it does nothing (this can happen depending on compiler phase ordering). + // The "leaf" provides the type, the root supplies the container, and the leaf-to-root path + // accumulates the offset. + // It emits the code necessary to implement the leaf select operation that leads to the root. + // + // TODO when registers really arrive, must also decompose anything split across two registers or registers and memory. + var rewriteSelect func(leaf *Value, selector *Value, offset int64) []LocalSlot + rewriteSelect = func(leaf *Value, selector *Value, offset int64) []LocalSlot { + if debug { + fmt.Printf("rewriteSelect(%s, %s, %d)\n", leaf.LongString(), selector.LongString(), offset) + } + var locs []LocalSlot + leafType := leaf.Type + if len(selector.Args) > 0 { + w := selector.Args[0] + if w.Op == OpCopy { + for w.Op == OpCopy { + w = w.Args[0] + } + selector.SetArg(0, w) + } + } + switch selector.Op { + case OpArg: + if !isAlreadyExpandedAggregateType(selector.Type) { + if leafType == selector.Type { // OpIData leads us here, sometimes. + leaf.copyOf(selector) + } else { + f.Fatalf("Unexpected OpArg type, selector=%s, leaf=%s\n", selector.LongString(), leaf.LongString()) + } + if debug { + fmt.Printf("\tOpArg, break\n") + } + break + } + if leaf.Op == OpIData { + leafType = removeTrivialWrapperTypes(leaf.Type) + } + aux := selector.Aux + auxInt := selector.AuxInt + offset + if leaf.Block == selector.Block { + leaf.reset(OpArg) + leaf.Aux = aux + leaf.AuxInt = auxInt + leaf.Type = leafType + } else { + w := selector.Block.NewValue0IA(leaf.Pos, OpArg, leafType, auxInt, aux) + leaf.copyOf(w) + if debug { + fmt.Printf("\tnew %s\n", w.LongString()) + } + } + for _, s := range namedSelects[selector] { + locs = append(locs, f.Names[s.locIndex]) + } + + case OpLoad: // We end up here because of IData of immediate structures. + // Failure case: + // (note the failure case is very rare; w/o this case, make.bash and run.bash both pass, as well as + // the hard cases of building {syscall,math,math/cmplx,math/bits,go/constant} on ppc64le and mips-softfloat). + // + // GOSSAFUNC='(*dumper).dump' go build -gcflags=-l -tags=math_big_pure_go cmd/compile/internal/gc + // cmd/compile/internal/gc/dump.go:136:14: internal compiler error: '(*dumper).dump': not lowered: v827, StructSelect PTR PTR + // b2: ← b1 + // v20 (+142) = StaticLECall <interface {},mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v8 v1 + // v21 (142) = SelectN <mem> [1] v20 + // v22 (142) = SelectN <interface {}> [0] v20 + // b15: ← b8 + // v71 (+143) = IData <Nodes> v22 (v[Nodes]) + // v73 (+146) = StaticLECall <[]*Node,mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v71 v21 + // + // translates (w/o the "case OpLoad:" above) to: + // + // b2: ← b1 + // v20 (+142) = StaticCall <mem> {AuxCall{reflect.Value.Interface([reflect.Value,0])[interface {},24]}} [40] v715 + // v23 (142) = Load <*uintptr> v19 v20 + // v823 (142) = IsNonNil <bool> v23 + // v67 (+143) = Load <*[]*Node> v880 v20 + // b15: ← b8 + // v827 (146) = StructSelect <*[]*Node> [0] v67 + // v846 (146) = Store <mem> {*[]*Node} v769 v827 v20 + // v73 (+146) = StaticCall <mem> {AuxCall{"".Nodes.Slice([Nodes,0])[[]*Node,8]}} [32] v846 + // i.e., the struct select is generated and remains in because it is not applied to an actual structure. + // The OpLoad was created to load the single field of the IData + // This case removes that StructSelect. + if leafType != selector.Type { + f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString()) + } + leaf.copyOf(selector) + for _, s := range namedSelects[selector] { + locs = append(locs, f.Names[s.locIndex]) + } + + case OpSelectN: + // TODO these may be duplicated. Should memoize. Intermediate selectors will go dead, no worries there. + call := selector.Args[0] + aux := call.Aux.(*AuxCall) + which := selector.AuxInt + if which == aux.NResults() { // mem is after the results. + // rewrite v as a Copy of call -- the replacement call will produce a mem. + leaf.copyOf(call) + } else { + leafType := removeTrivialWrapperTypes(leaf.Type) + if canSSAType(leafType) { + pt := types.NewPtr(leafType) + off := offsetFrom(sp, offset+aux.OffsetOfResult(which), pt) + // Any selection right out of the arg area/registers has to be same Block as call, use call as mem input. + if leaf.Block == call.Block { + leaf.reset(OpLoad) + leaf.SetArgs2(off, call) + leaf.Type = leafType + } else { + w := call.Block.NewValue2(leaf.Pos, OpLoad, leafType, off, call) + leaf.copyOf(w) + if debug { + fmt.Printf("\tnew %s\n", w.LongString()) + } + } + for _, s := range namedSelects[selector] { + locs = append(locs, f.Names[s.locIndex]) + } + } else { + f.Fatalf("Should not have non-SSA-able OpSelectN, selector=%s", selector.LongString()) + } + } + + case OpStructSelect: + w := selector.Args[0] + var ls []LocalSlot + if w.Type.Etype != types.TSTRUCT { // IData artifact + ls = rewriteSelect(leaf, w, offset) + } else { + ls = rewriteSelect(leaf, w, offset+w.Type.FieldOff(int(selector.AuxInt))) + if w.Op != OpIData { + for _, l := range ls { + locs = append(locs, f.fe.SplitStruct(l, int(selector.AuxInt))) + } + } + } + + case OpArraySelect: + w := selector.Args[0] + rewriteSelect(leaf, w, offset+selector.Type.Size()*selector.AuxInt) + + case OpInt64Hi: + w := selector.Args[0] + ls := rewriteSelect(leaf, w, offset+hiOffset) + locs = splitSlots(ls, ".hi", hiOffset, leafType) + + case OpInt64Lo: + w := selector.Args[0] + ls := rewriteSelect(leaf, w, offset+lowOffset) + locs = splitSlots(ls, ".lo", lowOffset, leafType) + + case OpStringPtr: + ls := rewriteSelect(leaf, selector.Args[0], offset) + locs = splitSlots(ls, ".ptr", 0, typ.BytePtr) + + case OpSlicePtr: + w := selector.Args[0] + ls := rewriteSelect(leaf, w, offset) + locs = splitSlots(ls, ".ptr", 0, types.NewPtr(w.Type.Elem())) + + case OpITab: + w := selector.Args[0] + ls := rewriteSelect(leaf, w, offset) + sfx := ".itab" + if w.Type.IsEmptyInterface() { + sfx = ".type" + } + locs = splitSlots(ls, sfx, 0, typ.Uintptr) + + case OpComplexReal: + ls := rewriteSelect(leaf, selector.Args[0], offset) + locs = splitSlots(ls, ".real", 0, leafType) + + case OpComplexImag: + ls := rewriteSelect(leaf, selector.Args[0], offset+leafType.Width) // result is FloatNN, width of result is offset of imaginary part. + locs = splitSlots(ls, ".imag", leafType.Width, leafType) + + case OpStringLen, OpSliceLen: + ls := rewriteSelect(leaf, selector.Args[0], offset+ptrSize) + locs = splitSlots(ls, ".len", ptrSize, leafType) + + case OpIData: + ls := rewriteSelect(leaf, selector.Args[0], offset+ptrSize) + locs = splitSlots(ls, ".data", ptrSize, leafType) + + case OpSliceCap: + ls := rewriteSelect(leaf, selector.Args[0], offset+2*ptrSize) + locs = splitSlots(ls, ".cap", 2*ptrSize, leafType) + + case OpCopy: // If it's an intermediate result, recurse + locs = rewriteSelect(leaf, selector.Args[0], offset) + for _, s := range namedSelects[selector] { + // this copy may have had its own name, preserve that, too. + locs = append(locs, f.Names[s.locIndex]) + } + + default: + // Ignore dead ends. These can occur if this phase is run before decompose builtin (which is not intended, but allowed). + } + + return locs + } + + // storeArgOrLoad converts stores of SSA-able aggregate arguments (passed to a call) into a series of primitive-typed + // stores of non-aggregate types. It recursively walks up a chain of selectors until it reaches a Load or an Arg. + // If it does not reach a Load or an Arg, nothing happens; this allows a little freedom in phase ordering. + var storeArgOrLoad func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64) *Value + + // decomposeArgOrLoad is a helper for storeArgOrLoad. + // It decomposes a Load or an Arg into smaller parts, parameterized by the decomposeOne and decomposeTwo functions + // passed to it, and returns the new mem. If the type does not match one of the expected aggregate types, it returns nil instead. + decomposeArgOrLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64, + decomposeOne func(pos src.XPos, b *Block, base, source, mem *Value, t1 *types.Type, offArg, offStore int64) *Value, + decomposeTwo func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value) *Value { + u := source.Type + switch u.Etype { + case types.TARRAY: + elem := u.Elem() + for i := int64(0); i < u.NumElem(); i++ { + elemOff := i * elem.Size() + mem = decomposeOne(pos, b, base, source, mem, elem, source.AuxInt+elemOff, offset+elemOff) + pos = pos.WithNotStmt() + } + return mem + case types.TSTRUCT: + for i := 0; i < u.NumFields(); i++ { + fld := u.Field(i) + mem = decomposeOne(pos, b, base, source, mem, fld.Type, source.AuxInt+fld.Offset, offset+fld.Offset) + pos = pos.WithNotStmt() + } + return mem + case types.TINT64, types.TUINT64: + if t.Width == regSize { + break + } + tHi, tLo := intPairTypes(t.Etype) + mem = decomposeOne(pos, b, base, source, mem, tHi, source.AuxInt+hiOffset, offset+hiOffset) + pos = pos.WithNotStmt() + return decomposeOne(pos, b, base, source, mem, tLo, source.AuxInt+lowOffset, offset+lowOffset) + case types.TINTER: + return decomposeTwo(pos, b, base, source, mem, typ.Uintptr, typ.BytePtr, source.AuxInt, offset) + case types.TSTRING: + return decomposeTwo(pos, b, base, source, mem, typ.BytePtr, typ.Int, source.AuxInt, offset) + case types.TCOMPLEX64: + return decomposeTwo(pos, b, base, source, mem, typ.Float32, typ.Float32, source.AuxInt, offset) + case types.TCOMPLEX128: + return decomposeTwo(pos, b, base, source, mem, typ.Float64, typ.Float64, source.AuxInt, offset) + case types.TSLICE: + mem = decomposeTwo(pos, b, base, source, mem, typ.BytePtr, typ.Int, source.AuxInt, offset) + return decomposeOne(pos, b, base, source, mem, typ.Int, source.AuxInt+2*ptrSize, offset+2*ptrSize) + } + return nil + } + + // storeOneArg creates a decomposed (one step) arg that is then stored. + // pos and b locate the store instruction, base is the base of the store target, source is the "base" of the value input, + // mem is the input mem, t is the type in question, and offArg and offStore are the offsets from the respective bases. + storeOneArg := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offArg, offStore int64) *Value { + w := common[selKey{source, offArg, t.Width, t}] + if w == nil { + w = source.Block.NewValue0IA(source.Pos, OpArg, t, offArg, source.Aux) + common[selKey{source, offArg, t.Width, t}] = w + } + return storeArgOrLoad(pos, b, base, w, mem, t, offStore) + } + + // storeOneLoad creates a decomposed (one step) load that is then stored. + storeOneLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offArg, offStore int64) *Value { + from := offsetFrom(source.Args[0], offArg, types.NewPtr(t)) + w := source.Block.NewValue2(source.Pos, OpLoad, t, from, mem) + return storeArgOrLoad(pos, b, base, w, mem, t, offStore) + } + + storeTwoArg := func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value { + mem = storeOneArg(pos, b, base, source, mem, t1, offArg, offStore) + pos = pos.WithNotStmt() + t1Size := t1.Size() + return storeOneArg(pos, b, base, source, mem, t2, offArg+t1Size, offStore+t1Size) + } + + storeTwoLoad := func(pos src.XPos, b *Block, base, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64) *Value { + mem = storeOneLoad(pos, b, base, source, mem, t1, offArg, offStore) + pos = pos.WithNotStmt() + t1Size := t1.Size() + return storeOneLoad(pos, b, base, source, mem, t2, offArg+t1Size, offStore+t1Size) + } + + storeArgOrLoad = func(pos src.XPos, b *Block, base, source, mem *Value, t *types.Type, offset int64) *Value { + if debug { + fmt.Printf("\tstoreArgOrLoad(%s; %s; %s; %s; %d)\n", base.LongString(), source.LongString(), mem.String(), t.String(), offset) + } + + switch source.Op { + case OpCopy: + return storeArgOrLoad(pos, b, base, source.Args[0], mem, t, offset) + + case OpLoad: + ret := decomposeArgOrLoad(pos, b, base, source, mem, t, offset, storeOneLoad, storeTwoLoad) + if ret != nil { + return ret + } + + case OpArg: + ret := decomposeArgOrLoad(pos, b, base, source, mem, t, offset, storeOneArg, storeTwoArg) + if ret != nil { + return ret + } + + case OpArrayMake0, OpStructMake0: + return mem + + case OpStructMake1, OpStructMake2, OpStructMake3, OpStructMake4: + for i := 0; i < t.NumFields(); i++ { + fld := t.Field(i) + mem = storeArgOrLoad(pos, b, base, source.Args[i], mem, fld.Type, offset+fld.Offset) + pos = pos.WithNotStmt() + } + return mem + + case OpArrayMake1: + return storeArgOrLoad(pos, b, base, source.Args[0], mem, t.Elem(), offset) + + case OpInt64Make: + tHi, tLo := intPairTypes(t.Etype) + mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, tHi, offset+hiOffset) + pos = pos.WithNotStmt() + return storeArgOrLoad(pos, b, base, source.Args[1], mem, tLo, offset+lowOffset) + + case OpComplexMake: + tPart := typ.Float32 + wPart := t.Width / 2 + if wPart == 8 { + tPart = typ.Float64 + } + mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, tPart, offset) + pos = pos.WithNotStmt() + return storeArgOrLoad(pos, b, base, source.Args[1], mem, tPart, offset+wPart) + + case OpIMake: + mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.Uintptr, offset) + pos = pos.WithNotStmt() + return storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.BytePtr, offset+ptrSize) + + case OpStringMake: + mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.BytePtr, offset) + pos = pos.WithNotStmt() + return storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.Int, offset+ptrSize) + + case OpSliceMake: + mem = storeArgOrLoad(pos, b, base, source.Args[0], mem, typ.BytePtr, offset) + pos = pos.WithNotStmt() + mem = storeArgOrLoad(pos, b, base, source.Args[1], mem, typ.Int, offset+ptrSize) + return storeArgOrLoad(pos, b, base, source.Args[2], mem, typ.Int, offset+2*ptrSize) + } + + // For nodes that cannot be taken apart -- OpSelectN, other structure selectors. + switch t.Etype { + case types.TARRAY: + elt := t.Elem() + if source.Type != t && t.NumElem() == 1 && elt.Width == t.Width && t.Width == regSize { + t = removeTrivialWrapperTypes(t) + // it could be a leaf type, but the "leaf" could be complex64 (for example) + return storeArgOrLoad(pos, b, base, source, mem, t, offset) + } + for i := int64(0); i < t.NumElem(); i++ { + sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, elt, offset+i*elt.Width) + pos = pos.WithNotStmt() + } + return mem + + case types.TSTRUCT: + if source.Type != t && t.NumFields() == 1 && t.Field(0).Type.Width == t.Width && t.Width == regSize { + // This peculiar test deals with accesses to immediate interface data. + // It works okay because everything is the same size. + // Example code that triggers this can be found in go/constant/value.go, function ToComplex + // v119 (+881) = IData <intVal> v6 + // v121 (+882) = StaticLECall <floatVal,mem> {AuxCall{"".itof([intVal,0])[floatVal,8]}} [16] v119 v1 + // This corresponds to the generic rewrite rule "(StructSelect [0] (IData x)) => (IData x)" + // Guard against "struct{struct{*foo}}" + // Other rewriting phases create minor glitches when they transform IData, for instance the + // interface-typed Arg "x" of ToFloat in go/constant/value.go + // v6 (858) = Arg <Value> {x} (x[Value], x[Value]) + // is rewritten by decomposeArgs into + // v141 (858) = Arg <uintptr> {x} + // v139 (858) = Arg <*uint8> {x} [8] + // because of a type case clause on line 862 of go/constant/value.go + // case intVal: + // return itof(x) + // v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of + // of a *uint8, which does not succeed. + t = removeTrivialWrapperTypes(t) + // it could be a leaf type, but the "leaf" could be complex64 (for example) + return storeArgOrLoad(pos, b, base, source, mem, t, offset) + } + + for i := 0; i < t.NumFields(); i++ { + fld := t.Field(i) + sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source) + mem = storeArgOrLoad(pos, b, base, sel, mem, fld.Type, offset+fld.Offset) + pos = pos.WithNotStmt() + } + return mem + + case types.TINT64, types.TUINT64: + if t.Width == regSize { + break + } + tHi, tLo := intPairTypes(t.Etype) + sel := source.Block.NewValue1(pos, OpInt64Hi, tHi, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, tHi, offset+hiOffset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpInt64Lo, tLo, source) + return storeArgOrLoad(pos, b, base, sel, mem, tLo, offset+lowOffset) + + case types.TINTER: + sel := source.Block.NewValue1(pos, OpITab, typ.BytePtr, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpIData, typ.BytePtr, source) + return storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset+ptrSize) + + case types.TSTRING: + sel := source.Block.NewValue1(pos, OpStringPtr, typ.BytePtr, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, typ.BytePtr, offset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpStringLen, typ.Int, source) + return storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+ptrSize) + + case types.TSLICE: + et := types.NewPtr(t.Elem()) + sel := source.Block.NewValue1(pos, OpSlicePtr, et, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, et, offset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpSliceLen, typ.Int, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+ptrSize) + sel = source.Block.NewValue1(pos, OpSliceCap, typ.Int, source) + return storeArgOrLoad(pos, b, base, sel, mem, typ.Int, offset+2*ptrSize) + + case types.TCOMPLEX64: + sel := source.Block.NewValue1(pos, OpComplexReal, typ.Float32, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Float32, offset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpComplexImag, typ.Float32, source) + return storeArgOrLoad(pos, b, base, sel, mem, typ.Float32, offset+4) + + case types.TCOMPLEX128: + sel := source.Block.NewValue1(pos, OpComplexReal, typ.Float64, source) + mem = storeArgOrLoad(pos, b, base, sel, mem, typ.Float64, offset) + pos = pos.WithNotStmt() + sel = source.Block.NewValue1(pos, OpComplexImag, typ.Float64, source) + return storeArgOrLoad(pos, b, base, sel, mem, typ.Float64, offset+8) + } + + dst := offsetFrom(base, offset, types.NewPtr(t)) + x := b.NewValue3A(pos, OpStore, types.TypeMem, t, dst, source, mem) + if debug { + fmt.Printf("\t\tstoreArg returns %s\n", x.LongString()) + } + return x + } + + // rewriteArgs removes all the Args from a call and converts the call args into appropriate + // stores (or later, register movement). Extra args for interface and closure calls are ignored, + // but removed. + rewriteArgs := func(v *Value, firstArg int) *Value { + // Thread the stores on the memory arg + aux := v.Aux.(*AuxCall) + pos := v.Pos.WithNotStmt() + m0 := v.Args[len(v.Args)-1] + mem := m0 + for i, a := range v.Args { + if i < firstArg { + continue + } + if a == m0 { // mem is last. + break + } + auxI := int64(i - firstArg) + if a.Op == OpDereference { + if a.MemoryArg() != m0 { + f.Fatalf("Op...LECall and OpDereference have mismatched mem, %s and %s", v.LongString(), a.LongString()) + } + // "Dereference" of addressed (probably not-SSA-eligible) value becomes Move + // TODO this will be more complicated with registers in the picture. + source := a.Args[0] + dst := f.ConstOffPtrSP(source.Type, aux.OffsetOfArg(auxI), sp) + if a.Uses == 1 && a.Block == v.Block { + a.reset(OpMove) + a.Pos = pos + a.Type = types.TypeMem + a.Aux = aux.TypeOfArg(auxI) + a.AuxInt = aux.SizeOfArg(auxI) + a.SetArgs3(dst, source, mem) + mem = a + } else { + mem = v.Block.NewValue3A(pos, OpMove, types.TypeMem, aux.TypeOfArg(auxI), dst, source, mem) + mem.AuxInt = aux.SizeOfArg(auxI) + } + } else { + if debug { + fmt.Printf("storeArg %s, %v, %d\n", a.LongString(), aux.TypeOfArg(auxI), aux.OffsetOfArg(auxI)) + } + mem = storeArgOrLoad(pos, v.Block, sp, a, mem, aux.TypeOfArg(auxI), aux.OffsetOfArg(auxI)) + } + } + v.resetArgs() + return mem + } + + // TODO if too slow, whole program iteration can be replaced w/ slices of appropriate values, accumulated in first loop here. + + // Step 0: rewrite the calls to convert incoming args to stores. + for _, b := range f.Blocks { + for _, v := range b.Values { + switch v.Op { + case OpStaticLECall: + mem := rewriteArgs(v, 0) + v.SetArgs1(mem) + case OpClosureLECall: + code := v.Args[0] + context := v.Args[1] + mem := rewriteArgs(v, 2) + v.SetArgs3(code, context, mem) + case OpInterLECall: + code := v.Args[0] + mem := rewriteArgs(v, 1) + v.SetArgs2(code, mem) + } + } + } + + for i, name := range f.Names { + t := name.Type + if isAlreadyExpandedAggregateType(t) { + for j, v := range f.NamedValues[name] { + if v.Op == OpSelectN || v.Op == OpArg && isAlreadyExpandedAggregateType(v.Type) { + ns := namedSelects[v] + namedSelects[v] = append(ns, namedVal{locIndex: i, valIndex: j}) + } + } + } + } + + // Step 1: any stores of aggregates remaining are believed to be sourced from call results or args. + // Decompose those stores into a series of smaller stores, adding selection ops as necessary. + for _, b := range f.Blocks { + for _, v := range b.Values { + if v.Op == OpStore { + t := v.Aux.(*types.Type) + source := v.Args[1] + tSrc := source.Type + iAEATt := isAlreadyExpandedAggregateType(t) + + if !iAEATt { + // guarding against store immediate struct into interface data field -- store type is *uint8 + // TODO can this happen recursively? + iAEATt = isAlreadyExpandedAggregateType(tSrc) + if iAEATt { + t = tSrc + } + } + if iAEATt { + if debug { + fmt.Printf("Splitting store %s\n", v.LongString()) + } + dst, mem := v.Args[0], v.Args[2] + mem = storeArgOrLoad(v.Pos, b, dst, source, mem, t, 0) + v.copyOf(mem) + } + } + } + } + + val2Preds := make(map[*Value]int32) // Used to accumulate dependency graph of selection operations for topological ordering. + + // Step 2: transform or accumulate selection operations for rewrite in topological order. + // + // Aggregate types that have already (in earlier phases) been transformed must be lowered comprehensively to finish + // the transformation (user-defined structs and arrays, slices, strings, interfaces, complex, 64-bit on 32-bit architectures), + // + // Any select-for-addressing applied to call results can be transformed directly. + for _, b := range f.Blocks { + for _, v := range b.Values { + // Accumulate chains of selectors for processing in topological order + switch v.Op { + case OpStructSelect, OpArraySelect, + OpIData, OpITab, + OpStringPtr, OpStringLen, + OpSlicePtr, OpSliceLen, OpSliceCap, + OpComplexReal, OpComplexImag, + OpInt64Hi, OpInt64Lo: + w := v.Args[0] + switch w.Op { + case OpStructSelect, OpArraySelect, OpSelectN, OpArg: + val2Preds[w] += 1 + if debug { + fmt.Printf("v2p[%s] = %d\n", w.LongString(), val2Preds[w]) + } + } + fallthrough + + case OpSelectN: + if _, ok := val2Preds[v]; !ok { + val2Preds[v] = 0 + if debug { + fmt.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v]) + } + } + + case OpArg: + if !isAlreadyExpandedAggregateType(v.Type) { + continue + } + if _, ok := val2Preds[v]; !ok { + val2Preds[v] = 0 + if debug { + fmt.Printf("v2p[%s] = %d\n", v.LongString(), val2Preds[v]) + } + } + + case OpSelectNAddr: + // Do these directly, there are no chains of selectors. + call := v.Args[0] + which := v.AuxInt + aux := call.Aux.(*AuxCall) + pt := v.Type + off := offsetFrom(sp, aux.OffsetOfResult(which), pt) + v.copyOf(off) + } + } + } + + // Step 3: Compute topological order of selectors, + // then process it in reverse to eliminate duplicates, + // then forwards to rewrite selectors. + // + // All chains of selectors end up in same block as the call. + + // Compilation must be deterministic, so sort after extracting first zeroes from map. + // Sorting allows dominators-last order within each batch, + // so that the backwards scan for duplicates will most often find copies from dominating blocks (it is best-effort). + var toProcess []*Value + less := func(i, j int) bool { + vi, vj := toProcess[i], toProcess[j] + bi, bj := vi.Block, vj.Block + if bi == bj { + return vi.ID < vj.ID + } + return sdom.domorder(bi) > sdom.domorder(bj) // reverse the order to put dominators last. + } + + // Accumulate order in allOrdered + var allOrdered []*Value + for v, n := range val2Preds { + if n == 0 { + allOrdered = append(allOrdered, v) + } + } + last := 0 // allOrdered[0:last] has been top-sorted and processed + for len(val2Preds) > 0 { + toProcess = allOrdered[last:] + last = len(allOrdered) + sort.SliceStable(toProcess, less) + for _, v := range toProcess { + delete(val2Preds, v) + if v.Op == OpArg { + continue // no Args[0], hence done. + } + w := v.Args[0] + n, ok := val2Preds[w] + if !ok { + continue + } + if n == 1 { + allOrdered = append(allOrdered, w) + delete(val2Preds, w) + continue + } + val2Preds[w] = n - 1 + } + } + + common = make(map[selKey]*Value) + // Rewrite duplicate selectors as copies where possible. + for i := len(allOrdered) - 1; i >= 0; i-- { + v := allOrdered[i] + if v.Op == OpArg { + continue + } + w := v.Args[0] + if w.Op == OpCopy { + for w.Op == OpCopy { + w = w.Args[0] + } + v.SetArg(0, w) + } + typ := v.Type + if typ.IsMemory() { + continue // handled elsewhere, not an indexable result + } + size := typ.Width + offset := int64(0) + switch v.Op { + case OpStructSelect: + if w.Type.Etype == types.TSTRUCT { + offset = w.Type.FieldOff(int(v.AuxInt)) + } else { // Immediate interface data artifact, offset is zero. + f.Fatalf("Expand calls interface data problem, func %s, v=%s, w=%s\n", f.Name, v.LongString(), w.LongString()) + } + case OpArraySelect: + offset = size * v.AuxInt + case OpSelectN: + offset = w.Aux.(*AuxCall).OffsetOfResult(v.AuxInt) + case OpInt64Hi: + offset = hiOffset + case OpInt64Lo: + offset = lowOffset + case OpStringLen, OpSliceLen, OpIData: + offset = ptrSize + case OpSliceCap: + offset = 2 * ptrSize + case OpComplexImag: + offset = size + } + sk := selKey{from: w, size: size, offset: offset, typ: typ} + dupe := common[sk] + if dupe == nil { + common[sk] = v + } else if sdom.IsAncestorEq(dupe.Block, v.Block) { + v.copyOf(dupe) + } else { + // Because values are processed in dominator order, the old common[s] will never dominate after a miss is seen. + // Installing the new value might match some future values. + common[sk] = v + } + } + + // Indices of entries in f.Names that need to be deleted. + var toDelete []namedVal + + // Rewrite selectors. + for i, v := range allOrdered { + if debug { + b := v.Block + fmt.Printf("allOrdered[%d] = b%d, %s, uses=%d\n", i, b.ID, v.LongString(), v.Uses) + } + if v.Uses == 0 { + v.reset(OpInvalid) + continue + } + if v.Op == OpCopy { + continue + } + locs := rewriteSelect(v, v, 0) + // Install new names. + if v.Type.IsMemory() { + continue + } + // Leaf types may have debug locations + if !isAlreadyExpandedAggregateType(v.Type) { + for _, l := range locs { + f.NamedValues[l] = append(f.NamedValues[l], v) + } + f.Names = append(f.Names, locs...) + continue + } + // Not-leaf types that had debug locations need to lose them. + if ns, ok := namedSelects[v]; ok { + toDelete = append(toDelete, ns...) + } + } + + deleteNamedVals(f, toDelete) + + // Step 4: rewrite the calls themselves, correcting the type + for _, b := range f.Blocks { + for _, v := range b.Values { + switch v.Op { + case OpStaticLECall: + v.Op = OpStaticCall + v.Type = types.TypeMem + case OpClosureLECall: + v.Op = OpClosureCall + v.Type = types.TypeMem + case OpInterLECall: + v.Op = OpInterCall + v.Type = types.TypeMem + } + } + } + + // Step 5: elide any copies introduced. + for _, b := range f.Blocks { + for _, v := range b.Values { + for i, a := range v.Args { + if a.Op != OpCopy { + continue + } + aa := copySource(a) + v.SetArg(i, aa) + for a.Uses == 0 { + b := a.Args[0] + a.reset(OpInvalid) + a = b + } + } + } + } +} diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go index 51665c60e2..b4c3e5cfdf 100644 --- a/src/cmd/compile/internal/ssa/export_test.go +++ b/src/cmd/compile/internal/ssa/export_test.go @@ -125,6 +125,10 @@ func (d DummyFrontend) SplitStruct(s LocalSlot, i int) LocalSlot { func (d DummyFrontend) SplitArray(s LocalSlot) LocalSlot { return LocalSlot{N: s.N, Type: s.Type.Elem(), Off: s.Off} } + +func (d DummyFrontend) SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot { + return LocalSlot{N: parent.N, Type: t, Off: offset} +} func (DummyFrontend) Line(_ src.XPos) string { return "unknown.go:0" } diff --git a/src/cmd/compile/internal/ssa/flagalloc.go b/src/cmd/compile/internal/ssa/flagalloc.go index d50b615912..61c45a6be7 100644 --- a/src/cmd/compile/internal/ssa/flagalloc.go +++ b/src/cmd/compile/internal/ssa/flagalloc.go @@ -191,11 +191,6 @@ func flagalloc(f *Func) { b.FlagsLiveAtEnd = end[b.ID] != nil } - const go115flagallocdeadcode = true - if !go115flagallocdeadcode { - return - } - // Remove any now-dead values. // The number of values to remove is likely small, // and removing them requires processing all values in a block, diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index 32df0c06f3..e6f899a2c7 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -672,7 +672,7 @@ func (f *Func) Idom() []*Block { return f.cachedIdom } -// sdom returns a sparse tree representing the dominator relationships +// Sdom returns a sparse tree representing the dominator relationships // among the blocks of f. func (f *Func) Sdom() SparseTree { if f.cachedSdom == nil { @@ -775,3 +775,25 @@ func (f *Func) logDebugHashMatch(evname, name string) { func DebugNameMatch(evname, name string) bool { return os.Getenv(evname) == name } + +func (f *Func) spSb() (sp, sb *Value) { + initpos := f.Entry.Pos + for _, v := range f.Entry.Values { + if v.Op == OpSB { + sb = v + } + if v.Op == OpSP { + sp = v + } + if sb != nil && sp != nil { + break + } + } + if sb == nil { + sb = f.Entry.NewValue0(initpos.WithNotStmt(), OpSB, f.Config.Types.Uintptr) + } + if sp == nil { + sp = f.Entry.NewValue0(initpos.WithNotStmt(), OpSP, f.Config.Types.Uintptr) + } + return +} diff --git a/src/cmd/compile/internal/ssa/func_test.go b/src/cmd/compile/internal/ssa/func_test.go index 5f6f80f72a..568c6436f5 100644 --- a/src/cmd/compile/internal/ssa/func_test.go +++ b/src/cmd/compile/internal/ssa/func_test.go @@ -38,6 +38,7 @@ package ssa import ( "cmd/compile/internal/types" + "cmd/internal/obj" "cmd/internal/src" "fmt" "reflect" @@ -140,6 +141,12 @@ var emptyPass pass = pass{ name: "empty pass", } +// AuxCallLSym returns an AuxCall initialized with an LSym that should pass "check" +// as the Aux of a static call. +func AuxCallLSym(name string) *AuxCall { + return &AuxCall{Fn: &obj.LSym{}} +} + // Fun takes the name of an entry bloc and a series of Bloc calls, and // returns a fun containing the composed Func. entry must be a name // supplied to one of the Bloc functions. Each of the bloc names and diff --git a/src/cmd/compile/internal/ssa/fuse_test.go b/src/cmd/compile/internal/ssa/fuse_test.go index 5fe3da93ca..15190997f2 100644 --- a/src/cmd/compile/internal/ssa/fuse_test.go +++ b/src/cmd/compile/internal/ssa/fuse_test.go @@ -142,10 +142,10 @@ func TestFuseSideEffects(t *testing.T) { Valu("b", OpArg, c.config.Types.Bool, 0, nil), If("b", "then", "else")), Bloc("then", - Valu("call1", OpStaticCall, types.TypeMem, 0, nil, "mem"), + Valu("call1", OpStaticCall, types.TypeMem, 0, AuxCallLSym("_"), "mem"), Goto("empty")), Bloc("else", - Valu("call2", OpStaticCall, types.TypeMem, 0, nil, "mem"), + Valu("call2", OpStaticCall, types.TypeMem, 0, AuxCallLSym("_"), "mem"), Goto("empty")), Bloc("empty", Goto("loop")), diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules index 4a8244eb27..fbc12fd672 100644 --- a/src/cmd/compile/internal/ssa/gen/386.rules +++ b/src/cmd/compile/internal/ssa/gen/386.rules @@ -38,10 +38,8 @@ (Xor(32|16|8) ...) => (XORL ...) (Neg(32|16|8) ...) => (NEGL ...) -(Neg32F x) && !config.use387 => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))])) -(Neg64F x) && !config.use387 => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)])) -(Neg32F x) && config.use387 => (FCHS x) -(Neg64F x) && config.use387 => (FCHS x) +(Neg32F x) => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))])) +(Neg64F x) => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)])) (Com(32|16|8) ...) => (NOTL ...) @@ -312,7 +310,7 @@ (Const32 ...) => (MOVLconst ...) (Const(32|64)F ...) => (MOVS(S|D)const ...) (ConstNil) => (MOVLconst [0]) -(ConstBool [c]) => (MOVLconst [int32(b2i(c))]) +(ConstBool [c]) => (MOVLconst [b2i32(c)]) // Lowering calls (StaticCall ...) => (CALLstatic ...) @@ -533,6 +531,7 @@ // fold ADDL into LEAL (ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x) (LEAL [c] {s} (ADDLconst [d] x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x) +(ADDLconst [c] x:(SP)) => (LEAL [c] x) // so it is rematerializeable (LEAL [c] {s} (ADDL x y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y) (ADDL x (LEAL [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y) @@ -642,36 +641,36 @@ // it compiles to a thunk call). (MOV(L|W|B|SS|SD|BLSX|WLSX)load [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - (MOV(L|W|B|SS|SD|BLSX|WLSX)load [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOV(L|W|B|SS|SD|BLSX|WLSX)load [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOV(L|W|B|SS|SD)store [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - (MOV(L|W|B|SS|SD)store [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOV(L|W|B|SS|SD)store [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOV(L|W|B)storeconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOV(L|W|B)storeconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + (MOV(L|W|B)storeconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) ((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - ((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + ((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - ((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + ((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - ((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + ((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - ((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + ((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) ((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem) && valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) => - ((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {mergeSymTyped(sym1,sym2)} base mem) + ((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) // Merge load/store to op ((ADD|AND|OR|XOR|SUB|MUL)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|AND|OR|XOR|SUB|MUL)Lload x [off] {sym} ptr mem) -((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem) -((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem) +((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem) +((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem) (MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) (MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => ((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) @@ -681,37 +680,37 @@ // fold LEALs together (LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL [off1+off2] {mergeSymTyped(sym1,sym2)} x) + (LEAL [off1+off2] {mergeSym(sym1,sym2)} x) // LEAL into LEAL1 (LEAL1 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => - (LEAL1 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAL1 into LEAL (LEAL [off1] {sym1} (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL1 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAL into LEAL[248] (LEAL2 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => - (LEAL2 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y) (LEAL4 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => - (LEAL4 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y) (LEAL8 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => - (LEAL8 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAL[248] into LEAL (LEAL [off1] {sym1} (LEAL2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL2 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y) (LEAL [off1] {sym1} (LEAL4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL4 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y) (LEAL [off1] {sym1} (LEAL8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL8 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAL[1248] into LEAL[1248]. Only some such merges are possible. (LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL2 [off1+off2] {mergeSymTyped(sym1, sym2)} x y) + (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} x y) (LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (LEAL2 [off1+off2] {mergeSymTyped(sym1, sym2)} y x) + (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} y x) (LEAL2 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+2*int64(off2)) => (LEAL4 [off1+2*off2] {sym} x y) (LEAL4 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+4*int64(off2)) => @@ -995,49 +994,49 @@ && x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) - => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p mem) + => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem) (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem)) && x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) - => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p mem) + => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem) (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem)) && x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x) - => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p0 mem) + => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem) (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem)) && x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x) - => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p0 mem) + => (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem) (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem)) && x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x) - => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p mem) + => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem) (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem)) && x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x) - => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p mem) + => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem) (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem)) && x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x) - => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p0 mem) + => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem) (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem)) && x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x) - => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p0 mem) + => (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem) // Combine stores into larger (unaligned) stores. (MOVBstore [i] {s} p (SHR(W|L)const [8] w) x:(MOVBstore [i-1] {s} p w mem)) diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go index 1061e5579d..737b99c371 100644 --- a/src/cmd/compile/internal/ssa/gen/386Ops.go +++ b/src/cmd/compile/internal/ssa/gen/386Ops.go @@ -51,17 +51,6 @@ var regNames386 = []string{ "SB", } -// Notes on 387 support. -// - The 387 has a weird stack-register setup for floating-point registers. -// We use these registers when SSE registers are not available (when GO386=387). -// - We use the same register names (X0-X7) but they refer to the 387 -// floating-point registers. That way, most of the SSA backend is unchanged. -// - The instruction generation pass maintains an SSE->387 register mapping. -// This mapping is updated whenever the FP stack is pushed or popped so that -// we can always find a given SSE register even when the TOS pointer has changed. -// - To facilitate the mapping from SSE to 387, we enforce that -// every basic block starts and ends with an empty floating-point stack. - func init() { // Make map from reg names to reg integers. if len(regNames386) > 64 { @@ -463,9 +452,9 @@ func init() { faultOnNilArg0: true, }, - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // arg0 = destination pointer // arg1 = source pointer @@ -552,9 +541,6 @@ func init() { {name: "FlagGT_UGT"}, // signed > and unsigned < {name: "FlagGT_ULT"}, // signed > and unsigned > - // Special op for -x on 387 - {name: "FCHS", argLength: 1, reg: fp11}, - // Special ops for PIC floating-point constants. // MOVSXconst1 loads the address of the constant-pool entry into a register. // MOVSXconst2 loads the constant from that address. diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 8898fe55eb..a866a967b9 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -401,38 +401,38 @@ (Const32F ...) => (MOVSSconst ...) (Const64F ...) => (MOVSDconst ...) (ConstNil ) => (MOVQconst [0]) -(ConstBool [c]) => (MOVLconst [int32(b2i(c))]) +(ConstBool [c]) => (MOVLconst [b2i32(c)]) // Lowering calls -(StaticCall ...) -> (CALLstatic ...) -(ClosureCall ...) -> (CALLclosure ...) -(InterCall ...) -> (CALLinter ...) +(StaticCall ...) => (CALLstatic ...) +(ClosureCall ...) => (CALLclosure ...) +(InterCall ...) => (CALLinter ...) // Lowering conditional moves // If the condition is a SETxx, we can just run a CMOV from the comparison that was // setting the flags. // Legend: HI=unsigned ABOVE, CS=unsigned BELOW, CC=unsigned ABOVE EQUAL, LS=unsigned BELOW EQUAL (CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && (is64BitInt(t) || isPtr(t)) - -> (CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) + => (CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) (CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is32BitInt(t) - -> (CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) + => (CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) (CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is16BitInt(t) - -> (CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) + => (CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond) // If the condition does not set the flags, we need to generate a comparison. (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 1 - -> (CondSelect <t> x y (MOVBQZX <typ.UInt64> check)) + => (CondSelect <t> x y (MOVBQZX <typ.UInt64> check)) (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 2 - -> (CondSelect <t> x y (MOVWQZX <typ.UInt64> check)) + => (CondSelect <t> x y (MOVWQZX <typ.UInt64> check)) (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 4 - -> (CondSelect <t> x y (MOVLQZX <typ.UInt64> check)) + => (CondSelect <t> x y (MOVLQZX <typ.UInt64> check)) (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && (is64BitInt(t) || isPtr(t)) - -> (CMOVQNE y x (CMPQconst [0] check)) + => (CMOVQNE y x (CMPQconst [0] check)) (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is32BitInt(t) - -> (CMOVLNE y x (CMPQconst [0] check)) + => (CMOVLNE y x (CMPQconst [0] check)) (CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is16BitInt(t) - -> (CMOVWNE y x (CMPQconst [0] check)) + => (CMOVWNE y x (CMPQconst [0] check)) // Absorb InvertFlags (CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond)) @@ -465,7 +465,7 @@ (GetCallerSP ...) => (LoweredGetCallerSP ...) (HasCPUFeature {s}) => (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s}))) -(Addr ...) -> (LEAQ ...) +(Addr {sym} base) => (LEAQ {sym} base) (LocalAddr {sym} base _) => (LEAQ {sym} base) (MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 => (SETLstore [off] {sym} ptr x mem) @@ -501,10 +501,10 @@ (If cond yes no) => (NE (TESTB cond cond) yes no) // Atomic loads. Other than preserving their ordering with respect to other loads, nothing special here. -(AtomicLoad8 ...) -> (MOVBatomicload ...) -(AtomicLoad32 ...) -> (MOVLatomicload ...) -(AtomicLoad64 ...) -> (MOVQatomicload ...) -(AtomicLoadPtr ...) -> (MOVQatomicload ...) +(AtomicLoad8 ptr mem) => (MOVBatomicload ptr mem) +(AtomicLoad32 ptr mem) => (MOVLatomicload ptr mem) +(AtomicLoad64 ptr mem) => (MOVQatomicload ptr mem) +(AtomicLoadPtr ptr mem) => (MOVQatomicload ptr mem) // Atomic stores. We use XCHG to prevent the hardware reordering a subsequent load. // TODO: most runtime uses of atomic stores don't need that property. Use normal stores for those? @@ -526,15 +526,17 @@ (Select1 (AddTupleFirst64 _ tuple)) => (Select1 tuple) // Atomic compare and swap. -(AtomicCompareAndSwap32 ...) -> (CMPXCHGLlock ...) -(AtomicCompareAndSwap64 ...) -> (CMPXCHGQlock ...) +(AtomicCompareAndSwap32 ptr old new_ mem) => (CMPXCHGLlock ptr old new_ mem) +(AtomicCompareAndSwap64 ptr old new_ mem) => (CMPXCHGQlock ptr old new_ mem) // Atomic memory updates. -(AtomicAnd8 ...) -> (ANDBlock ...) -(AtomicOr8 ...) -> (ORBlock ...) +(AtomicAnd8 ptr val mem) => (ANDBlock ptr val mem) +(AtomicAnd32 ptr val mem) => (ANDLlock ptr val mem) +(AtomicOr8 ptr val mem) => (ORBlock ptr val mem) +(AtomicOr32 ptr val mem) => (ORLlock ptr val mem) // Write barrier. -(WB ...) -> (LoweredWB ...) +(WB ...) => (LoweredWB ...) (PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem) (PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem) @@ -581,7 +583,7 @@ ((NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c)) => ((ULT|UGE) (BTQconst [int8(log32(c))] x)) ((NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c) - => ((ULT|UGE) (BTQconst [int8(log2(c))] x)) + => ((ULT|UGE) (BTQconst [int8(log64(c))] x)) (SET(NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => (SET(B|AE) (BTL x y)) (SET(NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => (SET(B|AE) (BTQ x y)) (SET(NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c)) @@ -589,7 +591,7 @@ (SET(NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c)) => (SET(B|AE) (BTQconst [int8(log32(c))] x)) (SET(NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c) - => (SET(B|AE) (BTQconst [int8(log2(c))] x)) + => (SET(B|AE) (BTQconst [int8(log64(c))] x)) // SET..store variant (SET(NE|EQ)store [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem) => (SET(B|AE)store [off] {sym} ptr (BTL x y) mem) @@ -600,7 +602,7 @@ (SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUint64PowerOfTwo(int64(c)) => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem) (SET(NE|EQ)store [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isUint64PowerOfTwo(c) - => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem) + => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem) // Handle bit-testing in the form (a>>b)&1 != 0 by building the above rules // and further combining shifts. @@ -629,7 +631,7 @@ ((ORL|XORL)const [c] x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128 => (BT(S|C)Lconst [int8(log32(c))] x) ((ORQ|XORQ) (MOVQconst [c]) x) && isUint64PowerOfTwo(c) && uint64(c) >= 128 - => (BT(S|C)Qconst [int8(log2(c))] x) + => (BT(S|C)Qconst [int8(log64(c))] x) ((ORL|XORL) (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128 => (BT(S|C)Lconst [int8(log32(c))] x) @@ -640,7 +642,7 @@ (ANDLconst [c] x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128 => (BTRLconst [int8(log32(^c))] x) (ANDQ (MOVQconst [c]) x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 128 - => (BTRQconst [int8(log2(^c))] x) + => (BTRQconst [int8(log64(^c))] x) (ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128 => (BTRLconst [int8(log32(^c))] x) @@ -853,7 +855,7 @@ (ANDL (SHRW x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16]))) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])) [16])))) && v.Type.Size() == 2 - -> (ROLW x y) + => (ROLW x y) (ORL (SHRW x (AND(Q|L)const y [15])) (SHLL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])))) && v.Type.Size() == 2 @@ -957,7 +959,7 @@ (MUL(Q|L)const [73] x) => (LEA(Q|L)8 x (LEA(Q|L)8 <v.Type> x x)) (MUL(Q|L)const [81] x) => (LEA(Q|L)8 (LEA(Q|L)8 <v.Type> x x) (LEA(Q|L)8 <v.Type> x x)) -(MUL(Q|L)const [c] x) && isPowerOfTwo(int64(c)+1) && c >= 15 => (SUB(Q|L) (SHL(Q|L)const <v.Type> [int8(log2(int64(c)+1))] x) x) +(MUL(Q|L)const [c] x) && isPowerOfTwo64(int64(c)+1) && c >= 15 => (SUB(Q|L) (SHL(Q|L)const <v.Type> [int8(log64(int64(c)+1))] x) x) (MUL(Q|L)const [c] x) && isPowerOfTwo32(c-1) && c >= 17 => (LEA(Q|L)1 (SHL(Q|L)const <v.Type> [int8(log32(c-1))] x) x) (MUL(Q|L)const [c] x) && isPowerOfTwo32(c-2) && c >= 34 => (LEA(Q|L)2 (SHL(Q|L)const <v.Type> [int8(log32(c-2))] x) x) (MUL(Q|L)const [c] x) && isPowerOfTwo32(c-4) && c >= 68 => (LEA(Q|L)4 (SHL(Q|L)const <v.Type> [int8(log32(c-4))] x) x) @@ -1134,268 +1136,270 @@ // We need to fold LEAQ into the MOVx ops so that the live variable analysis knows // what variables are being read/written by the ops. (MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOV(Q|L|W|B|SS|SD|O)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (MOV(Q|L|W|B|SS|SD|O)store [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(MOV(Q|L|W|B)storeconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) -> - (MOV(Q|L|W|B)storeconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) +(MOV(Q|L|W|B)storeconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) => + (MOV(Q|L|W|B)storeconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) (SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {mergeSym(sym1,sym2)} base val mem) ((ADD|SUB|AND|OR|XOR)Qload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|SUB|AND|OR|XOR)Lload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem) (CMP(Q|L|W|B)load [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (CMP(Q|L|W|B)load [off1+off2] {mergeSym(sym1,sym2)} base val mem) (CMP(Q|L|W|B)constload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - && ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) -> - (CMP(Q|L|W|B)constload [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + && ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) => + (CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) ((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - && ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) -> - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + && ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) => + ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - && ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) -> - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + && ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) => + ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> + && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) // fold LEAQs together -(LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ [off1+off2] {mergeSym(sym1,sym2)} x) // LEAQ into LEAQ1 -(LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB -> +(LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAQ1 into LEAQ -(LEAQ [off1] {sym1} (LEAQ1 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ [off1] {sym1} (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAQ into LEAQ[248] -(LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB -> +(LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y) -(LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB -> +(LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y) -(LEAQ8 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB -> +(LEAQ8 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAQ[248] into LEAQ -(LEAQ [off1] {sym1} (LEAQ2 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ [off1] {sym1} (LEAQ2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y) -(LEAQ [off1] {sym1} (LEAQ4 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ [off1] {sym1} (LEAQ4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y) -(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y) // LEAQ[1248] into LEAQ[1248]. Only some such merges are possible. -(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} x y) -(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} x y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> +(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} y x) -(LEAQ2 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(off1+2*off2) && sym2 == nil -> +(LEAQ2 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+2*int64(off2)) && sym2 == nil => (LEAQ4 [off1+2*off2] {sym1} x y) -(LEAQ4 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(off1+4*off2) && sym2 == nil -> +(LEAQ4 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+4*int64(off2)) && sym2 == nil => (LEAQ8 [off1+4*off2] {sym1} x y) // TODO: more? // Lower LEAQ2/4/8 when the offset is a constant -(LEAQ2 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(off+scale*2) -> - (LEAQ [off+scale*2] {sym} x) -(LEAQ4 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(off+scale*4) -> - (LEAQ [off+scale*4] {sym} x) -(LEAQ8 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(off+scale*8) -> - (LEAQ [off+scale*8] {sym} x) +(LEAQ2 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*2) => + (LEAQ [off+int32(scale)*2] {sym} x) +(LEAQ4 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*4) => + (LEAQ [off+int32(scale)*4] {sym} x) +(LEAQ8 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*8) => + (LEAQ [off+int32(scale)*8] {sym} x) // Absorb InvertFlags into branches. -(LT (InvertFlags cmp) yes no) -> (GT cmp yes no) -(GT (InvertFlags cmp) yes no) -> (LT cmp yes no) -(LE (InvertFlags cmp) yes no) -> (GE cmp yes no) -(GE (InvertFlags cmp) yes no) -> (LE cmp yes no) -(ULT (InvertFlags cmp) yes no) -> (UGT cmp yes no) -(UGT (InvertFlags cmp) yes no) -> (ULT cmp yes no) -(ULE (InvertFlags cmp) yes no) -> (UGE cmp yes no) -(UGE (InvertFlags cmp) yes no) -> (ULE cmp yes no) -(EQ (InvertFlags cmp) yes no) -> (EQ cmp yes no) -(NE (InvertFlags cmp) yes no) -> (NE cmp yes no) +(LT (InvertFlags cmp) yes no) => (GT cmp yes no) +(GT (InvertFlags cmp) yes no) => (LT cmp yes no) +(LE (InvertFlags cmp) yes no) => (GE cmp yes no) +(GE (InvertFlags cmp) yes no) => (LE cmp yes no) +(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no) +(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no) +(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no) +(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no) +(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no) +(NE (InvertFlags cmp) yes no) => (NE cmp yes no) // Constant comparisons. -(CMPQconst (MOVQconst [x]) [y]) && x==y -> (FlagEQ) -(CMPQconst (MOVQconst [x]) [y]) && x<y && uint64(x)<uint64(y) -> (FlagLT_ULT) -(CMPQconst (MOVQconst [x]) [y]) && x<y && uint64(x)>uint64(y) -> (FlagLT_UGT) -(CMPQconst (MOVQconst [x]) [y]) && x>y && uint64(x)<uint64(y) -> (FlagGT_ULT) -(CMPQconst (MOVQconst [x]) [y]) && x>y && uint64(x)>uint64(y) -> (FlagGT_UGT) -(CMPLconst (MOVLconst [x]) [y]) && int32(x)==int32(y) -> (FlagEQ) -(CMPLconst (MOVLconst [x]) [y]) && int32(x)<int32(y) && uint32(x)<uint32(y) -> (FlagLT_ULT) -(CMPLconst (MOVLconst [x]) [y]) && int32(x)<int32(y) && uint32(x)>uint32(y) -> (FlagLT_UGT) -(CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)<uint32(y) -> (FlagGT_ULT) -(CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)>uint32(y) -> (FlagGT_UGT) -(CMPWconst (MOVLconst [x]) [y]) && int16(x)==int16(y) -> (FlagEQ) -(CMPWconst (MOVLconst [x]) [y]) && int16(x)<int16(y) && uint16(x)<uint16(y) -> (FlagLT_ULT) -(CMPWconst (MOVLconst [x]) [y]) && int16(x)<int16(y) && uint16(x)>uint16(y) -> (FlagLT_UGT) -(CMPWconst (MOVLconst [x]) [y]) && int16(x)>int16(y) && uint16(x)<uint16(y) -> (FlagGT_ULT) -(CMPWconst (MOVLconst [x]) [y]) && int16(x)>int16(y) && uint16(x)>uint16(y) -> (FlagGT_UGT) -(CMPBconst (MOVLconst [x]) [y]) && int8(x)==int8(y) -> (FlagEQ) -(CMPBconst (MOVLconst [x]) [y]) && int8(x)<int8(y) && uint8(x)<uint8(y) -> (FlagLT_ULT) -(CMPBconst (MOVLconst [x]) [y]) && int8(x)<int8(y) && uint8(x)>uint8(y) -> (FlagLT_UGT) -(CMPBconst (MOVLconst [x]) [y]) && int8(x)>int8(y) && uint8(x)<uint8(y) -> (FlagGT_ULT) -(CMPBconst (MOVLconst [x]) [y]) && int8(x)>int8(y) && uint8(x)>uint8(y) -> (FlagGT_UGT) +(CMPQconst (MOVQconst [x]) [y]) && x==int64(y) => (FlagEQ) +(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)<uint64(int64(y)) => (FlagLT_ULT) +(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)>uint64(int64(y)) => (FlagLT_UGT) +(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)<uint64(int64(y)) => (FlagGT_ULT) +(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)>uint64(int64(y)) => (FlagGT_UGT) +(CMPLconst (MOVLconst [x]) [y]) && x==y => (FlagEQ) +(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)<uint32(y) => (FlagLT_ULT) +(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)>uint32(y) => (FlagLT_UGT) +(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)<uint32(y) => (FlagGT_ULT) +(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)>uint32(y) => (FlagGT_UGT) +(CMPWconst (MOVLconst [x]) [y]) && int16(x)==y => (FlagEQ) +(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)<uint16(y) => (FlagLT_ULT) +(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)>uint16(y) => (FlagLT_UGT) +(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)<uint16(y) => (FlagGT_ULT) +(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)>uint16(y) => (FlagGT_UGT) +(CMPBconst (MOVLconst [x]) [y]) && int8(x)==y => (FlagEQ) +(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)<uint8(y) => (FlagLT_ULT) +(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)>uint8(y) => (FlagLT_UGT) +(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)<uint8(y) => (FlagGT_ULT) +(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)>uint8(y) => (FlagGT_UGT) // CMPQconst requires a 32 bit const, but we can still constant-fold 64 bit consts. // In theory this applies to any of the simplifications above, // but CMPQ is the only one I've actually seen occur. -(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x==y -> (FlagEQ) -(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)<uint64(y) -> (FlagLT_ULT) -(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)>uint64(y) -> (FlagLT_UGT) -(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)<uint64(y) -> (FlagGT_ULT) -(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)>uint64(y) -> (FlagGT_UGT) +(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x==y => (FlagEQ) +(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)<uint64(y) => (FlagLT_ULT) +(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)>uint64(y) => (FlagLT_UGT) +(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)<uint64(y) => (FlagGT_ULT) +(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)>uint64(y) => (FlagGT_UGT) // Other known comparisons. -(CMPQconst (MOVBQZX _) [c]) && 0xFF < c -> (FlagLT_ULT) -(CMPQconst (MOVWQZX _) [c]) && 0xFFFF < c -> (FlagLT_ULT) -(CMPQconst (MOVLQZX _) [c]) && 0xFFFFFFFF < c -> (FlagLT_ULT) -(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) -> (FlagLT_ULT) -(CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) -> (FlagLT_ULT) -(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n -> (FlagLT_ULT) -(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n -> (FlagLT_ULT) -(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) -> (FlagLT_ULT) -(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < int16(n) -> (FlagLT_ULT) -(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < int8(n) -> (FlagLT_ULT) +(CMPQconst (MOVBQZX _) [c]) && 0xFF < c => (FlagLT_ULT) +(CMPQconst (MOVWQZX _) [c]) && 0xFFFF < c => (FlagLT_ULT) +(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) => (FlagLT_ULT) +(CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) => (FlagLT_ULT) +(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT) +(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT) +(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT) +(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT) +(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < n => (FlagLT_ULT) // TESTQ c c sets flags like CMPQ c 0. -(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c == 0 -> (FlagEQ) -(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c < 0 -> (FlagLT_UGT) -(TEST(Q|L)const [c] (MOV(Q|L)const [c])) && c > 0 -> (FlagGT_UGT) +(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c == 0 => (FlagEQ) +(TESTLconst [c] (MOVLconst [c])) && c == 0 => (FlagEQ) +(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c < 0 => (FlagLT_UGT) +(TESTLconst [c] (MOVLconst [c])) && c < 0 => (FlagLT_UGT) +(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c > 0 => (FlagGT_UGT) +(TESTLconst [c] (MOVLconst [c])) && c > 0 => (FlagGT_UGT) // TODO: DIVxU also. // Absorb flag constants into SBB ops. -(SBBQcarrymask (FlagEQ)) -> (MOVQconst [0]) -(SBBQcarrymask (FlagLT_ULT)) -> (MOVQconst [-1]) -(SBBQcarrymask (FlagLT_UGT)) -> (MOVQconst [0]) -(SBBQcarrymask (FlagGT_ULT)) -> (MOVQconst [-1]) -(SBBQcarrymask (FlagGT_UGT)) -> (MOVQconst [0]) -(SBBLcarrymask (FlagEQ)) -> (MOVLconst [0]) -(SBBLcarrymask (FlagLT_ULT)) -> (MOVLconst [-1]) -(SBBLcarrymask (FlagLT_UGT)) -> (MOVLconst [0]) -(SBBLcarrymask (FlagGT_ULT)) -> (MOVLconst [-1]) -(SBBLcarrymask (FlagGT_UGT)) -> (MOVLconst [0]) +(SBBQcarrymask (FlagEQ)) => (MOVQconst [0]) +(SBBQcarrymask (FlagLT_ULT)) => (MOVQconst [-1]) +(SBBQcarrymask (FlagLT_UGT)) => (MOVQconst [0]) +(SBBQcarrymask (FlagGT_ULT)) => (MOVQconst [-1]) +(SBBQcarrymask (FlagGT_UGT)) => (MOVQconst [0]) +(SBBLcarrymask (FlagEQ)) => (MOVLconst [0]) +(SBBLcarrymask (FlagLT_ULT)) => (MOVLconst [-1]) +(SBBLcarrymask (FlagLT_UGT)) => (MOVLconst [0]) +(SBBLcarrymask (FlagGT_ULT)) => (MOVLconst [-1]) +(SBBLcarrymask (FlagGT_UGT)) => (MOVLconst [0]) // Absorb flag constants into branches. -((EQ|LE|GE|ULE|UGE) (FlagEQ) yes no) -> (First yes no) -((NE|LT|GT|ULT|UGT) (FlagEQ) yes no) -> (First no yes) -((NE|LT|LE|ULT|ULE) (FlagLT_ULT) yes no) -> (First yes no) -((EQ|GT|GE|UGT|UGE) (FlagLT_ULT) yes no) -> (First no yes) -((NE|LT|LE|UGT|UGE) (FlagLT_UGT) yes no) -> (First yes no) -((EQ|GT|GE|ULT|ULE) (FlagLT_UGT) yes no) -> (First no yes) -((NE|GT|GE|ULT|ULE) (FlagGT_ULT) yes no) -> (First yes no) -((EQ|LT|LE|UGT|UGE) (FlagGT_ULT) yes no) -> (First no yes) -((NE|GT|GE|UGT|UGE) (FlagGT_UGT) yes no) -> (First yes no) -((EQ|LT|LE|ULT|ULE) (FlagGT_UGT) yes no) -> (First no yes) +((EQ|LE|GE|ULE|UGE) (FlagEQ) yes no) => (First yes no) +((NE|LT|GT|ULT|UGT) (FlagEQ) yes no) => (First no yes) +((NE|LT|LE|ULT|ULE) (FlagLT_ULT) yes no) => (First yes no) +((EQ|GT|GE|UGT|UGE) (FlagLT_ULT) yes no) => (First no yes) +((NE|LT|LE|UGT|UGE) (FlagLT_UGT) yes no) => (First yes no) +((EQ|GT|GE|ULT|ULE) (FlagLT_UGT) yes no) => (First no yes) +((NE|GT|GE|ULT|ULE) (FlagGT_ULT) yes no) => (First yes no) +((EQ|LT|LE|UGT|UGE) (FlagGT_ULT) yes no) => (First no yes) +((NE|GT|GE|UGT|UGE) (FlagGT_UGT) yes no) => (First yes no) +((EQ|LT|LE|ULT|ULE) (FlagGT_UGT) yes no) => (First no yes) // Absorb flag constants into SETxx ops. -((SETEQ|SETLE|SETGE|SETBE|SETAE) (FlagEQ)) -> (MOVLconst [1]) -((SETNE|SETL|SETG|SETB|SETA) (FlagEQ)) -> (MOVLconst [0]) -((SETNE|SETL|SETLE|SETB|SETBE) (FlagLT_ULT)) -> (MOVLconst [1]) -((SETEQ|SETG|SETGE|SETA|SETAE) (FlagLT_ULT)) -> (MOVLconst [0]) -((SETNE|SETL|SETLE|SETA|SETAE) (FlagLT_UGT)) -> (MOVLconst [1]) -((SETEQ|SETG|SETGE|SETB|SETBE) (FlagLT_UGT)) -> (MOVLconst [0]) -((SETNE|SETG|SETGE|SETB|SETBE) (FlagGT_ULT)) -> (MOVLconst [1]) -((SETEQ|SETL|SETLE|SETA|SETAE) (FlagGT_ULT)) -> (MOVLconst [0]) -((SETNE|SETG|SETGE|SETA|SETAE) (FlagGT_UGT)) -> (MOVLconst [1]) -((SETEQ|SETL|SETLE|SETB|SETBE) (FlagGT_UGT)) -> (MOVLconst [0]) +((SETEQ|SETLE|SETGE|SETBE|SETAE) (FlagEQ)) => (MOVLconst [1]) +((SETNE|SETL|SETG|SETB|SETA) (FlagEQ)) => (MOVLconst [0]) +((SETNE|SETL|SETLE|SETB|SETBE) (FlagLT_ULT)) => (MOVLconst [1]) +((SETEQ|SETG|SETGE|SETA|SETAE) (FlagLT_ULT)) => (MOVLconst [0]) +((SETNE|SETL|SETLE|SETA|SETAE) (FlagLT_UGT)) => (MOVLconst [1]) +((SETEQ|SETG|SETGE|SETB|SETBE) (FlagLT_UGT)) => (MOVLconst [0]) +((SETNE|SETG|SETGE|SETB|SETBE) (FlagGT_ULT)) => (MOVLconst [1]) +((SETEQ|SETL|SETLE|SETA|SETAE) (FlagGT_ULT)) => (MOVLconst [0]) +((SETNE|SETG|SETGE|SETA|SETAE) (FlagGT_UGT)) => (MOVLconst [1]) +((SETEQ|SETL|SETLE|SETB|SETBE) (FlagGT_UGT)) => (MOVLconst [0]) -(SETEQstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETEQstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETEQstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETEQstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETEQstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETEQstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETEQstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETEQstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETEQstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETEQstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETNEstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETNEstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETNEstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETNEstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETNEstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETNEstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETNEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETNEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETNEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETNEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETLstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETLstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETLstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETLstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETLstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETLstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETLstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETLEstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLEstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLEstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETLEstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETLEstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETLEstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETLEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETLEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETLEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETLEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETGstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETGstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETGstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETGstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETGstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETGstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETGEstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETGEstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGEstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETGEstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETGEstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETGEstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETGEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETGEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETGEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETGEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETBstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETBstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETBstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETBstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETBstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETBstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETBstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETBEstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBEstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBEstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETBEstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETBEstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETBEstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETBEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETBEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETBEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETBEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETAstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETAstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETAstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETAstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETAstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETAstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETAEstore [off] {sym} ptr (FlagEQ) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETAEstore [off] {sym} ptr (FlagLT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAEstore [off] {sym} ptr (FlagLT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) -(SETAEstore [off] {sym} ptr (FlagGT_ULT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) -(SETAEstore [off] {sym} ptr (FlagGT_UGT) mem) -> (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETAEstore [off] {sym} ptr (FlagEQ) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETAEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETAEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) +(SETAEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) +(SETAEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) // Remove redundant *const ops -(ADDQconst [0] x) -> x -(ADDLconst [c] x) && int32(c)==0 -> x -(SUBQconst [0] x) -> x -(SUBLconst [c] x) && int32(c) == 0 -> x -(ANDQconst [0] _) -> (MOVQconst [0]) -(ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0]) -(ANDQconst [-1] x) -> x -(ANDLconst [c] x) && int32(c)==-1 -> x -(ORQconst [0] x) -> x -(ORLconst [c] x) && int32(c)==0 -> x -(ORQconst [-1] _) -> (MOVQconst [-1]) -(ORLconst [c] _) && int32(c)==-1 -> (MOVLconst [-1]) -(XORQconst [0] x) -> x -(XORLconst [c] x) && int32(c)==0 -> x +(ADDQconst [0] x) => x +(ADDLconst [c] x) && c==0 => x +(SUBQconst [0] x) => x +(SUBLconst [c] x) && c==0 => x +(ANDQconst [0] _) => (MOVQconst [0]) +(ANDLconst [c] _) && c==0 => (MOVLconst [0]) +(ANDQconst [-1] x) => x +(ANDLconst [c] x) && c==-1 => x +(ORQconst [0] x) => x +(ORLconst [c] x) && c==0 => x +(ORQconst [-1] _) => (MOVQconst [-1]) +(ORLconst [c] _) && c==-1 => (MOVLconst [-1]) +(XORQconst [0] x) => x +(XORLconst [c] x) && c==0 => x // TODO: since we got rid of the W/B versions, we might miss // things like (ANDLconst [0x100] x) which were formerly // (ANDBconst [0] x). Probably doesn't happen very often. @@ -1404,99 +1408,99 @@ // Remove redundant ops // Not in generic rules, because they may appear after lowering e. g. Slicemask -(NEG(Q|L) (NEG(Q|L) x)) -> x -(NEG(Q|L) s:(SUB(Q|L) x y)) && s.Uses == 1 -> (SUB(Q|L) y x) +(NEG(Q|L) (NEG(Q|L) x)) => x +(NEG(Q|L) s:(SUB(Q|L) x y)) && s.Uses == 1 => (SUB(Q|L) y x) // Convert constant subtracts to constant adds -(SUBQconst [c] x) && c != -(1<<31) -> (ADDQconst [-c] x) -(SUBLconst [c] x) -> (ADDLconst [int64(int32(-c))] x) +(SUBQconst [c] x) && c != -(1<<31) => (ADDQconst [-c] x) +(SUBLconst [c] x) => (ADDLconst [-c] x) // generic constant folding // TODO: more of this -(ADDQconst [c] (MOVQconst [d])) -> (MOVQconst [c+d]) -(ADDLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c+d))]) -(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(c+d) -> (ADDQconst [c+d] x) -(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [int64(int32(c+d))] x) -(SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c]) -(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x) -(SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)]) -(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int32(d))>>uint64(c)]) -(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int16(d))>>uint64(c)]) -(SARBconst [c] (MOVQconst [d])) -> (MOVQconst [int64(int8(d))>>uint64(c)]) -(NEGQ (MOVQconst [c])) -> (MOVQconst [-c]) -(NEGL (MOVLconst [c])) -> (MOVLconst [int64(int32(-c))]) -(MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d]) -(MULLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c*d))]) -(ANDQconst [c] (MOVQconst [d])) -> (MOVQconst [c&d]) -(ANDLconst [c] (MOVLconst [d])) -> (MOVLconst [c&d]) -(ORQconst [c] (MOVQconst [d])) -> (MOVQconst [c|d]) -(ORLconst [c] (MOVLconst [d])) -> (MOVLconst [c|d]) -(XORQconst [c] (MOVQconst [d])) -> (MOVQconst [c^d]) -(XORLconst [c] (MOVLconst [d])) -> (MOVLconst [c^d]) -(NOTQ (MOVQconst [c])) -> (MOVQconst [^c]) -(NOTL (MOVLconst [c])) -> (MOVLconst [^c]) -(BTSQconst [c] (MOVQconst [d])) -> (MOVQconst [d|(1<<uint32(c))]) -(BTSLconst [c] (MOVLconst [d])) -> (MOVLconst [d|(1<<uint32(c))]) -(BTRQconst [c] (MOVQconst [d])) -> (MOVQconst [d&^(1<<uint32(c))]) -(BTRLconst [c] (MOVLconst [d])) -> (MOVLconst [d&^(1<<uint32(c))]) -(BTCQconst [c] (MOVQconst [d])) -> (MOVQconst [d^(1<<uint32(c))]) -(BTCLconst [c] (MOVLconst [d])) -> (MOVLconst [d^(1<<uint32(c))]) +(ADDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)+d]) +(ADDLconst [c] (MOVLconst [d])) => (MOVLconst [c+d]) +(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDQconst [c+d] x) +(ADDLconst [c] (ADDLconst [d] x)) => (ADDLconst [c+d] x) +(SUBQconst (MOVQconst [d]) [c]) => (MOVQconst [d-int64(c)]) +(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(int64(-c)-int64(d)) => (ADDQconst [-c-d] x) +(SARQconst [c] (MOVQconst [d])) => (MOVQconst [d>>uint64(c)]) +(SARLconst [c] (MOVQconst [d])) => (MOVQconst [int64(int32(d))>>uint64(c)]) +(SARWconst [c] (MOVQconst [d])) => (MOVQconst [int64(int16(d))>>uint64(c)]) +(SARBconst [c] (MOVQconst [d])) => (MOVQconst [int64(int8(d))>>uint64(c)]) +(NEGQ (MOVQconst [c])) => (MOVQconst [-c]) +(NEGL (MOVLconst [c])) => (MOVLconst [-c]) +(MULQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)*d]) +(MULLconst [c] (MOVLconst [d])) => (MOVLconst [c*d]) +(ANDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)&d]) +(ANDLconst [c] (MOVLconst [d])) => (MOVLconst [c&d]) +(ORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)|d]) +(ORLconst [c] (MOVLconst [d])) => (MOVLconst [c|d]) +(XORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)^d]) +(XORLconst [c] (MOVLconst [d])) => (MOVLconst [c^d]) +(NOTQ (MOVQconst [c])) => (MOVQconst [^c]) +(NOTL (MOVLconst [c])) => (MOVLconst [^c]) +(BTSQconst [c] (MOVQconst [d])) => (MOVQconst [d|(1<<uint32(c))]) +(BTSLconst [c] (MOVLconst [d])) => (MOVLconst [d|(1<<uint32(c))]) +(BTRQconst [c] (MOVQconst [d])) => (MOVQconst [d&^(1<<uint32(c))]) +(BTRLconst [c] (MOVLconst [d])) => (MOVLconst [d&^(1<<uint32(c))]) +(BTCQconst [c] (MOVQconst [d])) => (MOVQconst [d^(1<<uint32(c))]) +(BTCLconst [c] (MOVLconst [d])) => (MOVLconst [d^(1<<uint32(c))]) // If c or d doesn't fit into 32 bits, then we can't construct ORQconst, // but we can still constant-fold. // In theory this applies to any of the simplifications above, // but ORQ is the only one I've actually seen occur. -(ORQ (MOVQconst [c]) (MOVQconst [d])) -> (MOVQconst [c|d]) +(ORQ (MOVQconst [c]) (MOVQconst [d])) => (MOVQconst [c|d]) // generic simplifications // TODO: more of this -(ADDQ x (NEGQ y)) -> (SUBQ x y) -(ADDL x (NEGL y)) -> (SUBL x y) -(SUBQ x x) -> (MOVQconst [0]) -(SUBL x x) -> (MOVLconst [0]) -(ANDQ x x) -> x -(ANDL x x) -> x -(ORQ x x) -> x -(ORL x x) -> x -(XORQ x x) -> (MOVQconst [0]) -(XORL x x) -> (MOVLconst [0]) +(ADDQ x (NEGQ y)) => (SUBQ x y) +(ADDL x (NEGL y)) => (SUBL x y) +(SUBQ x x) => (MOVQconst [0]) +(SUBL x x) => (MOVLconst [0]) +(ANDQ x x) => x +(ANDL x x) => x +(ORQ x x) => x +(ORL x x) => x +(XORQ x x) => (MOVQconst [0]) +(XORL x x) => (MOVLconst [0]) -(SHLLconst [d] (MOVLconst [c])) -> (MOVLconst [int64(int32(c)) << uint64(d)]) -(SHLQconst [d] (MOVQconst [c])) -> (MOVQconst [c << uint64(d)]) -(SHLQconst [d] (MOVLconst [c])) -> (MOVQconst [int64(int32(c)) << uint64(d)]) +(SHLLconst [d] (MOVLconst [c])) => (MOVLconst [c << uint64(d)]) +(SHLQconst [d] (MOVQconst [c])) => (MOVQconst [c << uint64(d)]) +(SHLQconst [d] (MOVLconst [c])) => (MOVQconst [int64(c) << uint64(d)]) // Fold NEG into ADDconst/MULconst. Take care to keep c in 32 bit range. -(NEGQ (ADDQconst [c] (NEGQ x))) && c != -(1<<31) -> (ADDQconst [-c] x) -(MULQconst [c] (NEGQ x)) && c != -(1<<31) -> (MULQconst [-c] x) +(NEGQ (ADDQconst [c] (NEGQ x))) && c != -(1<<31) => (ADDQconst [-c] x) +(MULQconst [c] (NEGQ x)) && c != -(1<<31) => (MULQconst [-c] x) // checking AND against 0. -(CMPQconst a:(ANDQ x y) [0]) && a.Uses == 1 -> (TESTQ x y) -(CMPLconst a:(ANDL x y) [0]) && a.Uses == 1 -> (TESTL x y) -(CMPWconst a:(ANDL x y) [0]) && a.Uses == 1 -> (TESTW x y) -(CMPBconst a:(ANDL x y) [0]) && a.Uses == 1 -> (TESTB x y) -(CMPQconst a:(ANDQconst [c] x) [0]) && a.Uses == 1 -> (TESTQconst [c] x) -(CMPLconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 -> (TESTLconst [c] x) -(CMPWconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 -> (TESTWconst [int64(int16(c))] x) -(CMPBconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 -> (TESTBconst [int64(int8(c))] x) +(CMPQconst a:(ANDQ x y) [0]) && a.Uses == 1 => (TESTQ x y) +(CMPLconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTL x y) +(CMPWconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTW x y) +(CMPBconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTB x y) +(CMPQconst a:(ANDQconst [c] x) [0]) && a.Uses == 1 => (TESTQconst [c] x) +(CMPLconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTLconst [c] x) +(CMPWconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTWconst [int16(c)] x) +(CMPBconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTBconst [int8(c)] x) // Convert TESTx to TESTxconst if possible. -(TESTQ (MOVQconst [c]) x) && is32Bit(c) -> (TESTQconst [c] x) -(TESTL (MOVLconst [c]) x) -> (TESTLconst [c] x) -(TESTW (MOVLconst [c]) x) -> (TESTWconst [c] x) -(TESTB (MOVLconst [c]) x) -> (TESTBconst [c] x) +(TESTQ (MOVQconst [c]) x) && is32Bit(c) => (TESTQconst [int32(c)] x) +(TESTL (MOVLconst [c]) x) => (TESTLconst [c] x) +(TESTW (MOVLconst [c]) x) => (TESTWconst [int16(c)] x) +(TESTB (MOVLconst [c]) x) => (TESTBconst [int8(c)] x) // TEST %reg,%reg is shorter than CMP -(CMPQconst x [0]) -> (TESTQ x x) -(CMPLconst x [0]) -> (TESTL x x) -(CMPWconst x [0]) -> (TESTW x x) -(CMPBconst x [0]) -> (TESTB x x) -(TESTQconst [-1] x) && x.Op != OpAMD64MOVQconst -> (TESTQ x x) -(TESTLconst [-1] x) && x.Op != OpAMD64MOVLconst -> (TESTL x x) -(TESTWconst [-1] x) && x.Op != OpAMD64MOVLconst -> (TESTW x x) -(TESTBconst [-1] x) && x.Op != OpAMD64MOVLconst -> (TESTB x x) +(CMPQconst x [0]) => (TESTQ x x) +(CMPLconst x [0]) => (TESTL x x) +(CMPWconst x [0]) => (TESTW x x) +(CMPBconst x [0]) => (TESTB x x) +(TESTQconst [-1] x) && x.Op != OpAMD64MOVQconst => (TESTQ x x) +(TESTLconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTL x x) +(TESTWconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTW x x) +(TESTBconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTB x x) // Convert LEAQ1 back to ADDQ if we can -(LEAQ1 [0] x y) && v.Aux == nil -> (ADDQ x y) +(LEAQ1 [0] x y) && v.Aux == nil => (ADDQ x y) // Combining byte loads into larger (unaligned) loads. // There are many ways these combinations could occur. This is @@ -1512,7 +1516,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem) + => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem) (OR(L|Q) x0:(MOVBload [i] {s} p0 mem) sh:(SHL(L|Q)const [8] x1:(MOVBload [i] {s} p1 mem))) @@ -1522,7 +1526,7 @@ && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem) + => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem) (OR(L|Q) x0:(MOVWload [i0] {s} p mem) sh:(SHL(L|Q)const [16] x1:(MOVWload [i1] {s} p mem))) @@ -1532,7 +1536,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem) + => @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem) (OR(L|Q) x0:(MOVWload [i] {s} p0 mem) sh:(SHL(L|Q)const [16] x1:(MOVWload [i] {s} p1 mem))) @@ -1542,7 +1546,7 @@ && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem) + => @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem) (ORQ x0:(MOVLload [i0] {s} p mem) sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p mem))) @@ -1552,7 +1556,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem) + => @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem) (ORQ x0:(MOVLload [i] {s} p0 mem) sh:(SHLQconst [32] x1:(MOVLload [i] {s} p1 mem))) @@ -1562,7 +1566,7 @@ && sequentialAddresses(p0, p1, 4) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem) + => @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem) (OR(L|Q) s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem)) @@ -1579,7 +1583,7 @@ && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y) + => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y) (OR(L|Q) s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem)) @@ -1596,7 +1600,7 @@ && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y) + => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y) (ORQ s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem)) @@ -1613,7 +1617,7 @@ && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y) + => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y) (ORQ s1:(SHLQconst [j1] x1:(MOVWload [i] {s} p1 mem)) @@ -1630,7 +1634,7 @@ && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y) + => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y) // Big-endian loads @@ -1643,7 +1647,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem)) + => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem)) (OR(L|Q) x1:(MOVBload [i] {s} p1 mem) @@ -1654,7 +1658,7 @@ && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh) - -> @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem)) + => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem)) (OR(L|Q) r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)) @@ -1667,7 +1671,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh) - -> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem)) + => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem)) (OR(L|Q) r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)) @@ -1680,7 +1684,7 @@ && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh) - -> @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem)) + => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem)) (ORQ r1:(BSWAPL x1:(MOVLload [i1] {s} p mem)) @@ -1693,7 +1697,7 @@ && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh) - -> @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem)) + => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem)) (ORQ r1:(BSWAPL x1:(MOVLload [i] {s} p1 mem)) @@ -1706,7 +1710,7 @@ && sequentialAddresses(p0, p1, 4) && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh) - -> @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem)) + => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem)) (OR(L|Q) s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem)) @@ -1723,7 +1727,7 @@ && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y) + => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y) (OR(L|Q) s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem)) @@ -1740,7 +1744,7 @@ && sequentialAddresses(p0, p1, 1) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y) + => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y) (ORQ s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))) @@ -1759,7 +1763,7 @@ && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y) + => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y) (ORQ s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))) @@ -1778,20 +1782,20 @@ && sequentialAddresses(p0, p1, 2) && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or) - -> @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y) + => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y) // Combine 2 byte stores + shift into rolw 8 + word store (MOVBstore [i] {s} p w x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem)) && x0.Uses == 1 && clobber(x0) - -> (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem) + => (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem) (MOVBstore [i] {s} p1 w x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem)) && x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0) - -> (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem) + => (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem) // Combine stores + shifts into bswap and larger (unaligned) stores (MOVBstore [i] {s} p w @@ -1802,7 +1806,7 @@ && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2) - -> (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem) + => (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem) (MOVBstore [i] {s} p3 w x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w) x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w) @@ -1814,7 +1818,7 @@ && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2) - -> (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem) + => (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem) (MOVBstore [i] {s} p w x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w) @@ -1832,7 +1836,7 @@ && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6) - -> (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem) + => (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem) (MOVBstore [i] {s} p7 w x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w) x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w) @@ -1856,114 +1860,114 @@ && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6) - -> (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem) + => (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem) // Combine constant stores into larger (unaligned) stores. (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 1 == ValAndOff(c).Off() + && a.Off() + 1 == c.Off() && clobber(x) - -> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem) + => (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem) (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 1 == ValAndOff(c).Off() + && a.Off() + 1 == c.Off() && clobber(x) - -> (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem) + => (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem) (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() + && a.Off() + 2 == c.Off() && clobber(x) - -> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem) + => (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem) (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() + && a.Off() + 2 == c.Off() && clobber(x) - -> (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem) + => (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem) (MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 4 == ValAndOff(c).Off() + && a.Off() + 4 == c.Off() && clobber(x) - -> (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem) + => (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem) (MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem)) && x.Uses == 1 - && ValAndOff(a).Off() + 4 == ValAndOff(c).Off() + && a.Off() + 4 == c.Off() && clobber(x) - -> (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem) + => (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem) (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem)) && config.useSSE && x.Uses == 1 - && ValAndOff(c2).Off() + 8 == ValAndOff(c).Off() - && ValAndOff(c).Val() == 0 - && ValAndOff(c2).Val() == 0 + && c2.Off() + 8 == c.Off() + && c.Val() == 0 + && c2.Val() == 0 && clobber(x) - -> (MOVOstore [ValAndOff(c2).Off()] {s} p (MOVOconst [0]) mem) + => (MOVOstore [c2.Off32()] {s} p (MOVOconst [0]) mem) // Combine stores into larger (unaligned) stores. Little endian. (MOVBstore [i] {s} p (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p w mem)) && x.Uses == 1 && clobber(x) - -> (MOVWstore [i-1] {s} p w mem) + => (MOVWstore [i-1] {s} p w mem) (MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHR(W|L|Q)const [8] w) mem)) && x.Uses == 1 && clobber(x) - -> (MOVWstore [i] {s} p w mem) + => (MOVWstore [i] {s} p w mem) (MOVBstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVBstore [i-1] {s} p w0:(SHR(L|Q)const [j-8] w) mem)) && x.Uses == 1 && clobber(x) - -> (MOVWstore [i-1] {s} p w0 mem) + => (MOVWstore [i-1] {s} p w0 mem) (MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) x:(MOVBstore [i] {s} p0 w mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) - -> (MOVWstore [i] {s} p0 w mem) + => (MOVWstore [i] {s} p0 w mem) (MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) - -> (MOVWstore [i] {s} p0 w mem) + => (MOVWstore [i] {s} p0 w mem) (MOVBstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVBstore [i] {s} p0 w0:(SHR(L|Q)const [j-8] w) mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) - -> (MOVWstore [i] {s} p0 w0 mem) + => (MOVWstore [i] {s} p0 w0 mem) (MOVWstore [i] {s} p (SHR(L|Q)const [16] w) x:(MOVWstore [i-2] {s} p w mem)) && x.Uses == 1 && clobber(x) - -> (MOVLstore [i-2] {s} p w mem) + => (MOVLstore [i-2] {s} p w mem) (MOVWstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVWstore [i-2] {s} p w0:(SHR(L|Q)const [j-16] w) mem)) && x.Uses == 1 && clobber(x) - -> (MOVLstore [i-2] {s} p w0 mem) + => (MOVLstore [i-2] {s} p w0 mem) (MOVWstore [i] {s} p1 (SHR(L|Q)const [16] w) x:(MOVWstore [i] {s} p0 w mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) - -> (MOVLstore [i] {s} p0 w mem) + => (MOVLstore [i] {s} p0 w mem) (MOVWstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVWstore [i] {s} p0 w0:(SHR(L|Q)const [j-16] w) mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) - -> (MOVLstore [i] {s} p0 w0 mem) + => (MOVLstore [i] {s} p0 w0 mem) (MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem)) && x.Uses == 1 && clobber(x) - -> (MOVQstore [i-4] {s} p w mem) + => (MOVQstore [i-4] {s} p w mem) (MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem)) && x.Uses == 1 && clobber(x) - -> (MOVQstore [i-4] {s} p w0 mem) + => (MOVQstore [i-4] {s} p w0 mem) (MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i] {s} p0 w mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x) - -> (MOVQstore [i] {s} p0 w mem) + => (MOVQstore [i] {s} p0 w mem) (MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i] {s} p0 w0:(SHRQconst [j-32] w) mem)) && x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x) - -> (MOVQstore [i] {s} p0 w0 mem) + => (MOVQstore [i] {s} p0 w0 mem) (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) @@ -1973,7 +1977,7 @@ && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) - -> (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem) + => (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem) (MOVWstore [i] {s} p x1:(MOVWload [j] {s2} p2 mem) @@ -1983,7 +1987,7 @@ && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) - -> (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem) + => (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem) (MOVLstore [i] {s} p x1:(MOVLload [j] {s2} p2 mem) @@ -1993,178 +1997,178 @@ && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) - -> (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem) + => (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem) -(MOVQload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVQload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVQload [off1+off2] {mergeSym(sym1,sym2)} base mem) -(MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) -(MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) -(MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) -(MOVQstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVQstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVQstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(off1+off2) -> +(MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) => (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) -> - (MOVQstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) -(MOVLstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) -> - (MOVLstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) -(MOVWstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) -> - (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) -(MOVBstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) -> - (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) +(MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off) => + (MOVQstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) +(MOVLstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off) => + (MOVLstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) +(MOVWstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off) => + (MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) +(MOVBstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off) => + (MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) -(MOVQload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVQload [off1+off2] {sym} ptr mem) -(MOVLload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVLload [off1+off2] {sym} ptr mem) -(MOVWload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVWload [off1+off2] {sym} ptr mem) -(MOVBload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVBload [off1+off2] {sym} ptr mem) -(MOVQstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVQstore [off1+off2] {sym} ptr val mem) -(MOVLstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVLstore [off1+off2] {sym} ptr val mem) -(MOVWstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVWstore [off1+off2] {sym} ptr val mem) -(MOVBstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} ptr val mem) -(MOVQstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> - (MOVQstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) -(MOVLstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> - (MOVLstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) -(MOVWstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> - (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) -(MOVBstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> - (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) +(MOVQload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (MOVQload [off1+off2] {sym} ptr mem) +(MOVLload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (MOVLload [off1+off2] {sym} ptr mem) +(MOVWload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (MOVWload [off1+off2] {sym} ptr mem) +(MOVBload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (MOVBload [off1+off2] {sym} ptr mem) +(MOVQstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) => (MOVQstore [off1+off2] {sym} ptr val mem) +(MOVLstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) => (MOVLstore [off1+off2] {sym} ptr val mem) +(MOVWstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) => (MOVWstore [off1+off2] {sym} ptr val mem) +(MOVBstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) => (MOVBstore [off1+off2] {sym} ptr val mem) +(MOVQstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) => + (MOVQstoreconst [sc.addOffset32(off)] {s} ptr mem) +(MOVLstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) => + (MOVLstoreconst [sc.addOffset32(off)] {s} ptr mem) +(MOVWstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) => + (MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem) +(MOVBstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) => + (MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem) // Merge load and op // TODO: add indexed variants? -((ADD|SUB|AND|OR|XOR)Q x l:(MOVQload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) -> ((ADD|SUB|AND|OR|XOR)Qload x [off] {sym} ptr mem) -((ADD|SUB|AND|OR|XOR)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) -> ((ADD|SUB|AND|OR|XOR)Lload x [off] {sym} ptr mem) -((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) -> ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem) -((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) -> ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem) -(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) -> ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) -(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) -> +((ADD|SUB|AND|OR|XOR)Q x l:(MOVQload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Qload x [off] {sym} ptr mem) +((ADD|SUB|AND|OR|XOR)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Lload x [off] {sym} ptr mem) +((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem) +((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem) +(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) +(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off] {sym} ptr x mem) -(MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) -> ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem) -(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) -> +(MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem) +(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off] {sym} ptr x mem) // Merge ADDQconst and LEAQ into atomic loads. -(MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) -> +(MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (MOV(Q|L|B)atomicload [off1+off2] {sym} ptr mem) -(MOV(Q|L|B)atomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) -> - (MOV(Q|L|B)atomicload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) +(MOV(Q|L|B)atomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => + (MOV(Q|L|B)atomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem) // Merge ADDQconst and LEAQ into atomic stores. -(XCHGQ [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) -> +(XCHGQ [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (XCHGQ [off1+off2] {sym} val ptr mem) -(XCHGQ [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB -> +(XCHGQ [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB => (XCHGQ [off1+off2] {mergeSym(sym1,sym2)} val ptr mem) -(XCHGL [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) -> +(XCHGL [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (XCHGL [off1+off2] {sym} val ptr mem) -(XCHGL [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB -> +(XCHGL [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB => (XCHGL [off1+off2] {mergeSym(sym1,sym2)} val ptr mem) // Merge ADDQconst into atomic adds. // TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions. -(XADDQlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) -> +(XADDQlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (XADDQlock [off1+off2] {sym} val ptr mem) -(XADDLlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) -> +(XADDLlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => (XADDLlock [off1+off2] {sym} val ptr mem) // Merge ADDQconst into atomic compare and swaps. // TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions. -(CMPXCHGQlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(off1+off2) -> +(CMPXCHGQlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) => (CMPXCHGQlock [off1+off2] {sym} ptr old new_ mem) -(CMPXCHGLlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(off1+off2) -> +(CMPXCHGLlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) => (CMPXCHGLlock [off1+off2] {sym} ptr old new_ mem) // We don't need the conditional move if we know the arg of BSF is not zero. -(CMOVQEQ x _ (Select1 (BSFQ (ORQconst [c] _)))) && c != 0 -> x +(CMOVQEQ x _ (Select1 (BSFQ (ORQconst [c] _)))) && c != 0 => x // Extension is unnecessary for trailing zeros. -(BSFQ (ORQconst <t> [1<<8] (MOVBQZX x))) -> (BSFQ (ORQconst <t> [1<<8] x)) -(BSFQ (ORQconst <t> [1<<16] (MOVWQZX x))) -> (BSFQ (ORQconst <t> [1<<16] x)) +(BSFQ (ORQconst <t> [1<<8] (MOVBQZX x))) => (BSFQ (ORQconst <t> [1<<8] x)) +(BSFQ (ORQconst <t> [1<<16] (MOVWQZX x))) => (BSFQ (ORQconst <t> [1<<16] x)) // Redundant sign/zero extensions // Note: see issue 21963. We have to make sure we use the right type on // the resulting extension (the outer type, not the inner type). -(MOVLQSX (MOVLQSX x)) -> (MOVLQSX x) -(MOVLQSX (MOVWQSX x)) -> (MOVWQSX x) -(MOVLQSX (MOVBQSX x)) -> (MOVBQSX x) -(MOVWQSX (MOVWQSX x)) -> (MOVWQSX x) -(MOVWQSX (MOVBQSX x)) -> (MOVBQSX x) -(MOVBQSX (MOVBQSX x)) -> (MOVBQSX x) -(MOVLQZX (MOVLQZX x)) -> (MOVLQZX x) -(MOVLQZX (MOVWQZX x)) -> (MOVWQZX x) -(MOVLQZX (MOVBQZX x)) -> (MOVBQZX x) -(MOVWQZX (MOVWQZX x)) -> (MOVWQZX x) -(MOVWQZX (MOVBQZX x)) -> (MOVBQZX x) -(MOVBQZX (MOVBQZX x)) -> (MOVBQZX x) +(MOVLQSX (MOVLQSX x)) => (MOVLQSX x) +(MOVLQSX (MOVWQSX x)) => (MOVWQSX x) +(MOVLQSX (MOVBQSX x)) => (MOVBQSX x) +(MOVWQSX (MOVWQSX x)) => (MOVWQSX x) +(MOVWQSX (MOVBQSX x)) => (MOVBQSX x) +(MOVBQSX (MOVBQSX x)) => (MOVBQSX x) +(MOVLQZX (MOVLQZX x)) => (MOVLQZX x) +(MOVLQZX (MOVWQZX x)) => (MOVWQZX x) +(MOVLQZX (MOVBQZX x)) => (MOVBQZX x) +(MOVWQZX (MOVWQZX x)) => (MOVWQZX x) +(MOVWQZX (MOVBQZX x)) => (MOVBQZX x) +(MOVBQZX (MOVBQZX x)) => (MOVBQZX x) (MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) -> - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) => + ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) (MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) -> - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) => + ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) // float <-> int register moves, with no conversion. // These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}. -(MOVQload [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) -> (MOVQf2i val) -(MOVLload [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) -> (MOVLf2i val) -(MOVSDload [off] {sym} ptr (MOVQstore [off] {sym} ptr val _)) -> (MOVQi2f val) -(MOVSSload [off] {sym} ptr (MOVLstore [off] {sym} ptr val _)) -> (MOVLi2f val) +(MOVQload [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) => (MOVQf2i val) +(MOVLload [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) => (MOVLf2i val) +(MOVSDload [off] {sym} ptr (MOVQstore [off] {sym} ptr val _)) => (MOVQi2f val) +(MOVSSload [off] {sym} ptr (MOVLstore [off] {sym} ptr val _)) => (MOVLi2f val) // Other load-like ops. -(ADDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (ADDQ x (MOVQf2i y)) -(ADDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (ADDL x (MOVLf2i y)) -(SUBQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (SUBQ x (MOVQf2i y)) -(SUBLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (SUBL x (MOVLf2i y)) -(ANDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (ANDQ x (MOVQf2i y)) -(ANDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (ANDL x (MOVLf2i y)) -( ORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> ( ORQ x (MOVQf2i y)) -( ORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> ( ORL x (MOVLf2i y)) -(XORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) -> (XORQ x (MOVQf2i y)) -(XORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) -> (XORL x (MOVLf2i y)) +(ADDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ADDQ x (MOVQf2i y)) +(ADDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ADDL x (MOVLf2i y)) +(SUBQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (SUBQ x (MOVQf2i y)) +(SUBLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (SUBL x (MOVLf2i y)) +(ANDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ANDQ x (MOVQf2i y)) +(ANDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ANDL x (MOVLf2i y)) +( ORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => ( ORQ x (MOVQf2i y)) +( ORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => ( ORL x (MOVLf2i y)) +(XORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (XORQ x (MOVQf2i y)) +(XORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (XORL x (MOVLf2i y)) -(ADDSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (ADDSD x (MOVQi2f y)) -(ADDSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (ADDSS x (MOVLi2f y)) -(SUBSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (SUBSD x (MOVQi2f y)) -(SUBSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (SUBSS x (MOVLi2f y)) -(MULSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) -> (MULSD x (MOVQi2f y)) -(MULSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) -> (MULSS x (MOVLi2f y)) +(ADDSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (ADDSD x (MOVQi2f y)) +(ADDSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (ADDSS x (MOVLi2f y)) +(SUBSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (SUBSD x (MOVQi2f y)) +(SUBSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (SUBSS x (MOVLi2f y)) +(MULSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (MULSD x (MOVQi2f y)) +(MULSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (MULSS x (MOVLi2f y)) // Redirect stores to use the other register set. -(MOVQstore [off] {sym} ptr (MOVQf2i val) mem) -> (MOVSDstore [off] {sym} ptr val mem) -(MOVLstore [off] {sym} ptr (MOVLf2i val) mem) -> (MOVSSstore [off] {sym} ptr val mem) -(MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) -> (MOVQstore [off] {sym} ptr val mem) -(MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) -> (MOVLstore [off] {sym} ptr val mem) +(MOVQstore [off] {sym} ptr (MOVQf2i val) mem) => (MOVSDstore [off] {sym} ptr val mem) +(MOVLstore [off] {sym} ptr (MOVLf2i val) mem) => (MOVSSstore [off] {sym} ptr val mem) +(MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) => (MOVQstore [off] {sym} ptr val mem) +(MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) => (MOVLstore [off] {sym} ptr val mem) // Load args directly into the register class where it will be used. // We do this by just modifying the type of the Arg. -(MOVQf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() -> @b.Func.Entry (Arg <t> [off] {sym}) -(MOVLf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() -> @b.Func.Entry (Arg <t> [off] {sym}) -(MOVQi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() -> @b.Func.Entry (Arg <t> [off] {sym}) -(MOVLi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() -> @b.Func.Entry (Arg <t> [off] {sym}) +(MOVQf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym}) +(MOVLf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym}) +(MOVQi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym}) +(MOVLi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym}) // LEAQ is rematerializeable, so this helps to avoid register spill. // See issue 22947 for details -(ADD(Q|L)const [off] x:(SP)) -> (LEA(Q|L) [off] x) +(ADD(Q|L)const [off] x:(SP)) => (LEA(Q|L) [off] x) // HMULx is commutative, but its first argument must go in AX. // If possible, put a rematerializeable value in the first argument slot, // to reduce the odds that another value will be have to spilled // specifically to free up AX. -(HMUL(Q|L) x y) && !x.rematerializeable() && y.rematerializeable() -> (HMUL(Q|L) y x) -(HMUL(Q|L)U x y) && !x.rematerializeable() && y.rematerializeable() -> (HMUL(Q|L)U y x) +(HMUL(Q|L) x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L) y x) +(HMUL(Q|L)U x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L)U y x) // Fold loads into compares // Note: these may be undone by the flagalloc pass. -(CMP(Q|L|W|B) l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) -> (CMP(Q|L|W|B)load {sym} [off] ptr x mem) -(CMP(Q|L|W|B) x l:(MOV(Q|L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) -> (InvertFlags (CMP(Q|L|W|B)load {sym} [off] ptr x mem)) +(CMP(Q|L|W|B) l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (CMP(Q|L|W|B)load {sym} [off] ptr x mem) +(CMP(Q|L|W|B) x l:(MOV(Q|L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (InvertFlags (CMP(Q|L|W|B)load {sym} [off] ptr x mem)) (CMP(Q|L)const l:(MOV(Q|L)load {sym} [off] ptr mem) [c]) && l.Uses == 1 @@ -2175,22 +2179,22 @@ && clobber(l) => @l.Block (CMP(W|B)constload {sym} [makeValAndOff32(int32(c),off)] ptr mem) -(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validValAndOff(c,off) -> (CMPQconstload {sym} [makeValAndOff(c,off)] ptr mem) -(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(c,off) -> (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem) -(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int16(c)),off) -> (CMPWconstload {sym} [makeValAndOff(int64(int16(c)),off)] ptr mem) -(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int8(c)),off) -> (CMPBconstload {sym} [makeValAndOff(int64(int8(c)),off)] ptr mem) +(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validValAndOff(c,int64(off)) => (CMPQconstload {sym} [makeValAndOff64(c,int64(off))] ptr mem) +(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(c),int64(off)) => (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem) +(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int16(c)),int64(off)) => (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem) +(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) && validValAndOff(int64(int8(c)),int64(off)) => (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem) (TEST(Q|L|W|B) l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) l2) && l == l2 && l.Uses == 2 - && validValAndOff(0,off) - && clobber(l) -> - @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff(0,off)] ptr mem) + && validValAndOff(0, int64(off)) + && clobber(l) => + @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff64(0, int64(off))] ptr mem) -(MOVBload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVLconst [int64(read8(sym, off))]) -(MOVWload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVLconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))]) -(MOVLload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVQconst [int64(read32(sym, off, config.ctxt.Arch.ByteOrder))]) -(MOVQload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVQconst [int64(read64(sym, off, config.ctxt.Arch.ByteOrder))]) -(MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) && symIsRO(srcSym) -> - (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, srcOff+8, config.ctxt.Arch.ByteOrder))]) - (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, srcOff, config.ctxt.Arch.ByteOrder))]) mem)) +(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))]) +(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))]) +(MOVLload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))]) +(MOVQload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))]) +(MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) && symIsRO(srcSym) => + (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))]) + (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))]) mem)) diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index e6d66957dd..de5372670b 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -767,9 +767,9 @@ func init() { faultOnNilArg0: true, }, - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // arg0 = destination pointer // arg1 = source pointer @@ -902,7 +902,9 @@ func init() { // Atomic memory updates. {name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1 + {name: "ANDLlock", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1 {name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) |= arg1 + {name: "ORLlock", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) |= arg1 } var AMD64blocks = []blockData{ diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules index 983f884849..11c36b5da3 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM.rules @@ -2,83 +2,83 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -(Add(Ptr|32|16|8) ...) -> (ADD ...) -(Add(32|64)F ...) -> (ADD(F|D) ...) -(Add32carry ...) -> (ADDS ...) -(Add32withcarry ...) -> (ADC ...) +(Add(Ptr|32|16|8) ...) => (ADD ...) +(Add(32|64)F ...) => (ADD(F|D) ...) +(Add32carry ...) => (ADDS ...) +(Add32withcarry ...) => (ADC ...) -(Sub(Ptr|32|16|8) ...) -> (SUB ...) -(Sub(32|64)F ...) -> (SUB(F|D) ...) -(Sub32carry ...) -> (SUBS ...) -(Sub32withcarry ...) -> (SBC ...) +(Sub(Ptr|32|16|8) ...) => (SUB ...) +(Sub(32|64)F ...) => (SUB(F|D) ...) +(Sub32carry ...) => (SUBS ...) +(Sub32withcarry ...) => (SBC ...) -(Mul(32|16|8) ...) -> (MUL ...) -(Mul(32|64)F ...) -> (MUL(F|D) ...) -(Hmul(32|32u) ...) -> (HMU(L|LU) ...) -(Mul32uhilo ...) -> (MULLU ...) +(Mul(32|16|8) ...) => (MUL ...) +(Mul(32|64)F ...) => (MUL(F|D) ...) +(Hmul(32|32u) ...) => (HMU(L|LU) ...) +(Mul32uhilo ...) => (MULLU ...) -(Div32 x y) -> +(Div32 x y) => (SUB (XOR <typ.UInt32> // negate the result if one operand is negative (Select0 <typ.UInt32> (CALLudiv (SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x)) // negate x if negative (SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y)))) // negate y if negative (Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y))) -(Div32u x y) -> (Select0 <typ.UInt32> (CALLudiv x y)) -(Div16 x y) -> (Div32 (SignExt16to32 x) (SignExt16to32 y)) -(Div16u x y) -> (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y)) -(Div8 x y) -> (Div32 (SignExt8to32 x) (SignExt8to32 y)) -(Div8u x y) -> (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y)) -(Div(32|64)F ...) -> (DIV(F|D) ...) +(Div32u x y) => (Select0 <typ.UInt32> (CALLudiv x y)) +(Div16 x y) => (Div32 (SignExt16to32 x) (SignExt16to32 y)) +(Div16u x y) => (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y)) +(Div8 x y) => (Div32 (SignExt8to32 x) (SignExt8to32 y)) +(Div8u x y) => (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y)) +(Div(32|64)F ...) => (DIV(F|D) ...) -(Mod32 x y) -> +(Mod32 x y) => (SUB (XOR <typ.UInt32> // negate the result if x is negative (Select1 <typ.UInt32> (CALLudiv (SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x)) // negate x if negative (SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y)))) // negate y if negative (Signmask x)) (Signmask x)) -(Mod32u x y) -> (Select1 <typ.UInt32> (CALLudiv x y)) -(Mod16 x y) -> (Mod32 (SignExt16to32 x) (SignExt16to32 y)) -(Mod16u x y) -> (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y)) -(Mod8 x y) -> (Mod32 (SignExt8to32 x) (SignExt8to32 y)) -(Mod8u x y) -> (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y)) +(Mod32u x y) => (Select1 <typ.UInt32> (CALLudiv x y)) +(Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y)) +(Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y)) +(Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y)) +(Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y)) // (x + y) / 2 with x>=y -> (x - y) / 2 + y -(Avg32u <t> x y) -> (ADD (SRLconst <t> (SUB <t> x y) [1]) y) +(Avg32u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y) -(And(32|16|8) ...) -> (AND ...) -(Or(32|16|8) ...) -> (OR ...) -(Xor(32|16|8) ...) -> (XOR ...) +(And(32|16|8) ...) => (AND ...) +(Or(32|16|8) ...) => (OR ...) +(Xor(32|16|8) ...) => (XOR ...) // unary ops -(Neg(32|16|8) x) -> (RSBconst [0] x) -(Neg(32|64)F ...) -> (NEG(F|D) ...) +(Neg(32|16|8) x) => (RSBconst [0] x) +(Neg(32|64)F ...) => (NEG(F|D) ...) -(Com(32|16|8) ...) -> (MVN ...) +(Com(32|16|8) ...) => (MVN ...) -(Sqrt ...) -> (SQRTD ...) -(Abs ...) -> (ABSD ...) +(Sqrt ...) => (SQRTD ...) +(Abs ...) => (ABSD ...) // TODO: optimize this for ARMv5 and ARMv6 -(Ctz32NonZero ...) -> (Ctz32 ...) -(Ctz16NonZero ...) -> (Ctz32 ...) -(Ctz8NonZero ...) -> (Ctz32 ...) +(Ctz32NonZero ...) => (Ctz32 ...) +(Ctz16NonZero ...) => (Ctz32 ...) +(Ctz8NonZero ...) => (Ctz32 ...) // count trailing zero for ARMv5 and ARMv6 // 32 - CLZ(x&-x - 1) -(Ctz32 <t> x) && objabi.GOARM<=6 -> +(Ctz32 <t> x) && objabi.GOARM<=6 => (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1]))) -(Ctz16 <t> x) && objabi.GOARM<=6 -> +(Ctz16 <t> x) && objabi.GOARM<=6 => (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1]))) -(Ctz8 <t> x) && objabi.GOARM<=6 -> +(Ctz8 <t> x) && objabi.GOARM<=6 => (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1]))) // count trailing zero for ARMv7 -(Ctz32 <t> x) && objabi.GOARM==7 -> (CLZ <t> (RBIT <t> x)) -(Ctz16 <t> x) && objabi.GOARM==7 -> (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x))) -(Ctz8 <t> x) && objabi.GOARM==7 -> (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x))) +(Ctz32 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <t> x)) +(Ctz16 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x))) +(Ctz8 <t> x) && objabi.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x))) // bit length -(BitLen32 <t> x) -> (RSBconst [32] (CLZ <t> x)) +(BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x)) // byte swap for ARMv5 // let (a, b, c, d) be the bytes of x from high to low @@ -89,203 +89,203 @@ // t5 = x right rotate 8 bits -- (d, a, b, c ) // result = t4 ^ t5 -- (d, c, b, a ) // using shifted ops this can be done in 4 instructions. -(Bswap32 <t> x) && objabi.GOARM==5 -> +(Bswap32 <t> x) && objabi.GOARM==5 => (XOR <t> (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8]) (SRRconst <t> x [8])) // byte swap for ARMv6 and above -(Bswap32 x) && objabi.GOARM>=6 -> (REV x) +(Bswap32 x) && objabi.GOARM>=6 => (REV x) // boolean ops -- booleans are represented with 0=false, 1=true -(AndB ...) -> (AND ...) -(OrB ...) -> (OR ...) -(EqB x y) -> (XORconst [1] (XOR <typ.Bool> x y)) -(NeqB ...) -> (XOR ...) -(Not x) -> (XORconst [1] x) +(AndB ...) => (AND ...) +(OrB ...) => (OR ...) +(EqB x y) => (XORconst [1] (XOR <typ.Bool> x y)) +(NeqB ...) => (XOR ...) +(Not x) => (XORconst [1] x) // shifts // hardware instruction uses only the low byte of the shift // we compare to 256 to ensure Go semantics for large shifts -(Lsh32x32 x y) -> (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) -(Lsh32x16 x y) -> (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Lsh32x8 x y) -> (SLL x (ZeroExt8to32 y)) +(Lsh32x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) +(Lsh32x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Lsh32x8 x y) => (SLL x (ZeroExt8to32 y)) -(Lsh16x32 x y) -> (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) -(Lsh16x16 x y) -> (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Lsh16x8 x y) -> (SLL x (ZeroExt8to32 y)) +(Lsh16x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) +(Lsh16x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Lsh16x8 x y) => (SLL x (ZeroExt8to32 y)) -(Lsh8x32 x y) -> (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) -(Lsh8x16 x y) -> (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Lsh8x8 x y) -> (SLL x (ZeroExt8to32 y)) +(Lsh8x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0]) +(Lsh8x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Lsh8x8 x y) => (SLL x (ZeroExt8to32 y)) -(Rsh32Ux32 x y) -> (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0]) -(Rsh32Ux16 x y) -> (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Rsh32Ux8 x y) -> (SRL x (ZeroExt8to32 y)) +(Rsh32Ux32 x y) => (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0]) +(Rsh32Ux16 x y) => (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Rsh32Ux8 x y) => (SRL x (ZeroExt8to32 y)) -(Rsh16Ux32 x y) -> (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0]) -(Rsh16Ux16 x y) -> (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Rsh16Ux8 x y) -> (SRL (ZeroExt16to32 x) (ZeroExt8to32 y)) +(Rsh16Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0]) +(Rsh16Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Rsh16Ux8 x y) => (SRL (ZeroExt16to32 x) (ZeroExt8to32 y)) -(Rsh8Ux32 x y) -> (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0]) -(Rsh8Ux16 x y) -> (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) -(Rsh8Ux8 x y) -> (SRL (ZeroExt8to32 x) (ZeroExt8to32 y)) +(Rsh8Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0]) +(Rsh8Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) +(Rsh8Ux8 x y) => (SRL (ZeroExt8to32 x) (ZeroExt8to32 y)) -(Rsh32x32 x y) -> (SRAcond x y (CMPconst [256] y)) -(Rsh32x16 x y) -> (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) -(Rsh32x8 x y) -> (SRA x (ZeroExt8to32 y)) +(Rsh32x32 x y) => (SRAcond x y (CMPconst [256] y)) +(Rsh32x16 x y) => (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) +(Rsh32x8 x y) => (SRA x (ZeroExt8to32 y)) -(Rsh16x32 x y) -> (SRAcond (SignExt16to32 x) y (CMPconst [256] y)) -(Rsh16x16 x y) -> (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) -(Rsh16x8 x y) -> (SRA (SignExt16to32 x) (ZeroExt8to32 y)) +(Rsh16x32 x y) => (SRAcond (SignExt16to32 x) y (CMPconst [256] y)) +(Rsh16x16 x y) => (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) +(Rsh16x8 x y) => (SRA (SignExt16to32 x) (ZeroExt8to32 y)) -(Rsh8x32 x y) -> (SRAcond (SignExt8to32 x) y (CMPconst [256] y)) -(Rsh8x16 x y) -> (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) -(Rsh8x8 x y) -> (SRA (SignExt8to32 x) (ZeroExt8to32 y)) +(Rsh8x32 x y) => (SRAcond (SignExt8to32 x) y (CMPconst [256] y)) +(Rsh8x16 x y) => (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) +(Rsh8x8 x y) => (SRA (SignExt8to32 x) (ZeroExt8to32 y)) // constant shifts // generic opt rewrites all constant shifts to shift by Const64 -(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 -> (SLLconst x [c]) -(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 -> (SRAconst x [c]) -(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 -> (SRLconst x [c]) -(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 -> (SLLconst x [c]) -(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 -> (SRAconst (SLLconst <typ.UInt32> x [16]) [c+16]) -(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 -> (SRLconst (SLLconst <typ.UInt32> x [16]) [c+16]) -(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 -> (SLLconst x [c]) -(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 -> (SRAconst (SLLconst <typ.UInt32> x [24]) [c+24]) -(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 -> (SRLconst (SLLconst <typ.UInt32> x [24]) [c+24]) +(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SLLconst x [int32(c)]) +(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SRAconst x [int32(c)]) +(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SRLconst x [int32(c)]) +(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SLLconst x [int32(c)]) +(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)]) +(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SRLconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)]) +(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SLLconst x [int32(c)]) +(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)]) +(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SRLconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)]) // large constant shifts -(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 -> (Const32 [0]) -(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 -> (Const32 [0]) -(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 -> (Const16 [0]) -(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 -> (Const16 [0]) -(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0]) -(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 -> (Const8 [0]) +(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0]) +(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0]) +(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0]) +(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0]) +(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0]) +(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0]) // large constant signed right shift, we leave the sign bit -(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 -> (SRAconst x [31]) -(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 -> (SRAconst (SLLconst <typ.UInt32> x [16]) [31]) -(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SRAconst (SLLconst <typ.UInt32> x [24]) [31]) +(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SRAconst x [31]) +(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [31]) +(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [31]) // constants -(Const(8|16|32) ...) -> (MOVWconst ...) -(Const(32F|64F) ...) -> (MOV(F|D)const ...) -(ConstNil) -> (MOVWconst [0]) -(ConstBool ...) -> (MOVWconst ...) +(Const(8|16|32) [val]) => (MOVWconst [int32(val)]) +(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)]) +(ConstNil) => (MOVWconst [0]) +(ConstBool [b]) => (MOVWconst [b2i32(b)]) // truncations // Because we ignore high parts of registers, truncates are just copies. -(Trunc16to8 ...) -> (Copy ...) -(Trunc32to8 ...) -> (Copy ...) -(Trunc32to16 ...) -> (Copy ...) +(Trunc16to8 ...) => (Copy ...) +(Trunc32to8 ...) => (Copy ...) +(Trunc32to16 ...) => (Copy ...) // Zero-/Sign-extensions -(ZeroExt8to16 ...) -> (MOVBUreg ...) -(ZeroExt8to32 ...) -> (MOVBUreg ...) -(ZeroExt16to32 ...) -> (MOVHUreg ...) +(ZeroExt8to16 ...) => (MOVBUreg ...) +(ZeroExt8to32 ...) => (MOVBUreg ...) +(ZeroExt16to32 ...) => (MOVHUreg ...) -(SignExt8to16 ...) -> (MOVBreg ...) -(SignExt8to32 ...) -> (MOVBreg ...) -(SignExt16to32 ...) -> (MOVHreg ...) +(SignExt8to16 ...) => (MOVBreg ...) +(SignExt8to32 ...) => (MOVBreg ...) +(SignExt16to32 ...) => (MOVHreg ...) -(Signmask x) -> (SRAconst x [31]) -(Zeromask x) -> (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31]) // sign bit of uint32(x)>>1 - x -(Slicemask <t> x) -> (SRAconst (RSBconst <t> [0] x) [31]) +(Signmask x) => (SRAconst x [31]) +(Zeromask x) => (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31]) // sign bit of uint32(x)>>1 - x +(Slicemask <t> x) => (SRAconst (RSBconst <t> [0] x) [31]) // float <-> int conversion -(Cvt32to32F ...) -> (MOVWF ...) -(Cvt32to64F ...) -> (MOVWD ...) -(Cvt32Uto32F ...) -> (MOVWUF ...) -(Cvt32Uto64F ...) -> (MOVWUD ...) -(Cvt32Fto32 ...) -> (MOVFW ...) -(Cvt64Fto32 ...) -> (MOVDW ...) -(Cvt32Fto32U ...) -> (MOVFWU ...) -(Cvt64Fto32U ...) -> (MOVDWU ...) -(Cvt32Fto64F ...) -> (MOVFD ...) -(Cvt64Fto32F ...) -> (MOVDF ...) +(Cvt32to32F ...) => (MOVWF ...) +(Cvt32to64F ...) => (MOVWD ...) +(Cvt32Uto32F ...) => (MOVWUF ...) +(Cvt32Uto64F ...) => (MOVWUD ...) +(Cvt32Fto32 ...) => (MOVFW ...) +(Cvt64Fto32 ...) => (MOVDW ...) +(Cvt32Fto32U ...) => (MOVFWU ...) +(Cvt64Fto32U ...) => (MOVDWU ...) +(Cvt32Fto64F ...) => (MOVFD ...) +(Cvt64Fto32F ...) => (MOVDF ...) -(Round(32|64)F ...) -> (Copy ...) +(Round(32|64)F ...) => (Copy ...) -(CvtBoolToUint8 ...) -> (Copy ...) +(CvtBoolToUint8 ...) => (Copy ...) // fused-multiply-add -(FMA x y z) -> (FMULAD z x y) +(FMA x y z) => (FMULAD z x y) // comparisons -(Eq8 x y) -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) -(Eq16 x y) -> (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) -(Eq32 x y) -> (Equal (CMP x y)) -(EqPtr x y) -> (Equal (CMP x y)) -(Eq(32|64)F x y) -> (Equal (CMP(F|D) x y)) +(Eq8 x y) => (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) +(Eq16 x y) => (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) +(Eq32 x y) => (Equal (CMP x y)) +(EqPtr x y) => (Equal (CMP x y)) +(Eq(32|64)F x y) => (Equal (CMP(F|D) x y)) -(Neq8 x y) -> (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) -(Neq16 x y) -> (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) -(Neq32 x y) -> (NotEqual (CMP x y)) -(NeqPtr x y) -> (NotEqual (CMP x y)) -(Neq(32|64)F x y) -> (NotEqual (CMP(F|D) x y)) +(Neq8 x y) => (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) +(Neq16 x y) => (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) +(Neq32 x y) => (NotEqual (CMP x y)) +(NeqPtr x y) => (NotEqual (CMP x y)) +(Neq(32|64)F x y) => (NotEqual (CMP(F|D) x y)) -(Less8 x y) -> (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y))) -(Less16 x y) -> (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y))) -(Less32 x y) -> (LessThan (CMP x y)) -(Less(32|64)F x y) -> (GreaterThan (CMP(F|D) y x)) // reverse operands to work around NaN +(Less8 x y) => (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y))) +(Less16 x y) => (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y))) +(Less32 x y) => (LessThan (CMP x y)) +(Less(32|64)F x y) => (GreaterThan (CMP(F|D) y x)) // reverse operands to work around NaN -(Less8U x y) -> (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) -(Less16U x y) -> (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) -(Less32U x y) -> (LessThanU (CMP x y)) +(Less8U x y) => (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) +(Less16U x y) => (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) +(Less32U x y) => (LessThanU (CMP x y)) -(Leq8 x y) -> (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y))) -(Leq16 x y) -> (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y))) -(Leq32 x y) -> (LessEqual (CMP x y)) -(Leq(32|64)F x y) -> (GreaterEqual (CMP(F|D) y x)) // reverse operands to work around NaN +(Leq8 x y) => (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y))) +(Leq16 x y) => (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y))) +(Leq32 x y) => (LessEqual (CMP x y)) +(Leq(32|64)F x y) => (GreaterEqual (CMP(F|D) y x)) // reverse operands to work around NaN -(Leq8U x y) -> (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) -(Leq16U x y) -> (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) -(Leq32U x y) -> (LessEqualU (CMP x y)) +(Leq8U x y) => (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y))) +(Leq16U x y) => (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y))) +(Leq32U x y) => (LessEqualU (CMP x y)) -(OffPtr [off] ptr:(SP)) -> (MOVWaddr [off] ptr) -(OffPtr [off] ptr) -> (ADDconst [off] ptr) +(OffPtr [off] ptr:(SP)) => (MOVWaddr [int32(off)] ptr) +(OffPtr [off] ptr) => (ADDconst [int32(off)] ptr) -(Addr ...) -> (MOVWaddr ...) -(LocalAddr {sym} base _) -> (MOVWaddr {sym} base) +(Addr {sym} base) => (MOVWaddr {sym} base) +(LocalAddr {sym} base _) => (MOVWaddr {sym} base) // loads -(Load <t> ptr mem) && t.IsBoolean() -> (MOVBUload ptr mem) -(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) -> (MOVBload ptr mem) -(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) -> (MOVBUload ptr mem) -(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) -> (MOVHload ptr mem) -(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) -> (MOVHUload ptr mem) -(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) -> (MOVWload ptr mem) -(Load <t> ptr mem) && is32BitFloat(t) -> (MOVFload ptr mem) -(Load <t> ptr mem) && is64BitFloat(t) -> (MOVDload ptr mem) +(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem) +(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem) +(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem) +(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem) +(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem) +(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVWload ptr mem) +(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem) +(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem) // stores -(Store {t} ptr val mem) && t.(*types.Type).Size() == 1 -> (MOVBstore ptr val mem) -(Store {t} ptr val mem) && t.(*types.Type).Size() == 2 -> (MOVHstore ptr val mem) -(Store {t} ptr val mem) && t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type) -> (MOVWstore ptr val mem) -(Store {t} ptr val mem) && t.(*types.Type).Size() == 4 && is32BitFloat(val.Type) -> (MOVFstore ptr val mem) -(Store {t} ptr val mem) && t.(*types.Type).Size() == 8 && is64BitFloat(val.Type) -> (MOVDstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem) // zero instructions -(Zero [0] _ mem) -> mem -(Zero [1] ptr mem) -> (MOVBstore ptr (MOVWconst [0]) mem) -(Zero [2] {t} ptr mem) && t.(*types.Type).Alignment()%2 == 0 -> +(Zero [0] _ mem) => mem +(Zero [1] ptr mem) => (MOVBstore ptr (MOVWconst [0]) mem) +(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 => (MOVHstore ptr (MOVWconst [0]) mem) -(Zero [2] ptr mem) -> +(Zero [2] ptr mem) => (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem)) -(Zero [4] {t} ptr mem) && t.(*types.Type).Alignment()%4 == 0 -> +(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 => (MOVWstore ptr (MOVWconst [0]) mem) -(Zero [4] {t} ptr mem) && t.(*types.Type).Alignment()%2 == 0 -> +(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 => (MOVHstore [2] ptr (MOVWconst [0]) (MOVHstore [0] ptr (MOVWconst [0]) mem)) -(Zero [4] ptr mem) -> +(Zero [4] ptr mem) => (MOVBstore [3] ptr (MOVWconst [0]) (MOVBstore [2] ptr (MOVWconst [0]) (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem)))) -(Zero [3] ptr mem) -> +(Zero [3] ptr mem) => (MOVBstore [2] ptr (MOVWconst [0]) (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem))) @@ -294,38 +294,38 @@ // 4 and 128 are magic constants, see runtime/mkduff.go (Zero [s] {t} ptr mem) && s%4 == 0 && s > 4 && s <= 512 - && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice -> + && t.Alignment()%4 == 0 && !config.noDuffDevice => (DUFFZERO [4 * (128 - s/4)] ptr (MOVWconst [0]) mem) // Large zeroing uses a loop (Zero [s] {t} ptr mem) - && (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0 -> - (LoweredZero [t.(*types.Type).Alignment()] + && (s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0 => + (LoweredZero [t.Alignment()] ptr - (ADDconst <ptr.Type> ptr [s-moveSize(t.(*types.Type).Alignment(), config)]) + (ADDconst <ptr.Type> ptr [int32(s-moveSize(t.Alignment(), config))]) (MOVWconst [0]) mem) // moves -(Move [0] _ _ mem) -> mem -(Move [1] dst src mem) -> (MOVBstore dst (MOVBUload src mem) mem) -(Move [2] {t} dst src mem) && t.(*types.Type).Alignment()%2 == 0 -> +(Move [0] _ _ mem) => mem +(Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem) +(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 => (MOVHstore dst (MOVHUload src mem) mem) -(Move [2] dst src mem) -> +(Move [2] dst src mem) => (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem)) -(Move [4] {t} dst src mem) && t.(*types.Type).Alignment()%4 == 0 -> +(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 => (MOVWstore dst (MOVWload src mem) mem) -(Move [4] {t} dst src mem) && t.(*types.Type).Alignment()%2 == 0 -> +(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 => (MOVHstore [2] dst (MOVHUload [2] src mem) (MOVHstore dst (MOVHUload src mem) mem)) -(Move [4] dst src mem) -> +(Move [4] dst src mem) => (MOVBstore [3] dst (MOVBUload [3] src mem) (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem)))) -(Move [3] dst src mem) -> +(Move [3] dst src mem) => (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem))) @@ -334,279 +334,279 @@ // 8 and 128 are magic constants, see runtime/mkduff.go (Move [s] {t} dst src mem) && s%4 == 0 && s > 4 && s <= 512 - && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) -> + && t.Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) => (DUFFCOPY [8 * (128 - s/4)] dst src mem) // Large move uses a loop (Move [s] {t} dst src mem) - && ((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) && logLargeCopy(v, s) -> - (LoweredMove [t.(*types.Type).Alignment()] + && ((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) && logLargeCopy(v, s) => + (LoweredMove [t.Alignment()] dst src - (ADDconst <src.Type> src [s-moveSize(t.(*types.Type).Alignment(), config)]) + (ADDconst <src.Type> src [int32(s-moveSize(t.Alignment(), config))]) mem) // calls -(StaticCall ...) -> (CALLstatic ...) -(ClosureCall ...) -> (CALLclosure ...) -(InterCall ...) -> (CALLinter ...) +(StaticCall ...) => (CALLstatic ...) +(ClosureCall ...) => (CALLclosure ...) +(InterCall ...) => (CALLinter ...) // checks -(NilCheck ...) -> (LoweredNilCheck ...) -(IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr)) -(IsInBounds idx len) -> (LessThanU (CMP idx len)) -(IsSliceInBounds idx len) -> (LessEqualU (CMP idx len)) +(NilCheck ...) => (LoweredNilCheck ...) +(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr)) +(IsInBounds idx len) => (LessThanU (CMP idx len)) +(IsSliceInBounds idx len) => (LessEqualU (CMP idx len)) // pseudo-ops -(GetClosurePtr ...) -> (LoweredGetClosurePtr ...) -(GetCallerSP ...) -> (LoweredGetCallerSP ...) -(GetCallerPC ...) -> (LoweredGetCallerPC ...) +(GetClosurePtr ...) => (LoweredGetClosurePtr ...) +(GetCallerSP ...) => (LoweredGetCallerSP ...) +(GetCallerPC ...) => (LoweredGetCallerPC ...) // Absorb pseudo-ops into blocks. -(If (Equal cc) yes no) -> (EQ cc yes no) -(If (NotEqual cc) yes no) -> (NE cc yes no) -(If (LessThan cc) yes no) -> (LT cc yes no) -(If (LessThanU cc) yes no) -> (ULT cc yes no) -(If (LessEqual cc) yes no) -> (LE cc yes no) -(If (LessEqualU cc) yes no) -> (ULE cc yes no) -(If (GreaterThan cc) yes no) -> (GT cc yes no) -(If (GreaterThanU cc) yes no) -> (UGT cc yes no) -(If (GreaterEqual cc) yes no) -> (GE cc yes no) -(If (GreaterEqualU cc) yes no) -> (UGE cc yes no) +(If (Equal cc) yes no) => (EQ cc yes no) +(If (NotEqual cc) yes no) => (NE cc yes no) +(If (LessThan cc) yes no) => (LT cc yes no) +(If (LessThanU cc) yes no) => (ULT cc yes no) +(If (LessEqual cc) yes no) => (LE cc yes no) +(If (LessEqualU cc) yes no) => (ULE cc yes no) +(If (GreaterThan cc) yes no) => (GT cc yes no) +(If (GreaterThanU cc) yes no) => (UGT cc yes no) +(If (GreaterEqual cc) yes no) => (GE cc yes no) +(If (GreaterEqualU cc) yes no) => (UGE cc yes no) -(If cond yes no) -> (NE (CMPconst [0] cond) yes no) +(If cond yes no) => (NE (CMPconst [0] cond) yes no) // Absorb boolean tests into block -(NE (CMPconst [0] (Equal cc)) yes no) -> (EQ cc yes no) -(NE (CMPconst [0] (NotEqual cc)) yes no) -> (NE cc yes no) -(NE (CMPconst [0] (LessThan cc)) yes no) -> (LT cc yes no) -(NE (CMPconst [0] (LessThanU cc)) yes no) -> (ULT cc yes no) -(NE (CMPconst [0] (LessEqual cc)) yes no) -> (LE cc yes no) -(NE (CMPconst [0] (LessEqualU cc)) yes no) -> (ULE cc yes no) -(NE (CMPconst [0] (GreaterThan cc)) yes no) -> (GT cc yes no) -(NE (CMPconst [0] (GreaterThanU cc)) yes no) -> (UGT cc yes no) -(NE (CMPconst [0] (GreaterEqual cc)) yes no) -> (GE cc yes no) -(NE (CMPconst [0] (GreaterEqualU cc)) yes no) -> (UGE cc yes no) +(NE (CMPconst [0] (Equal cc)) yes no) => (EQ cc yes no) +(NE (CMPconst [0] (NotEqual cc)) yes no) => (NE cc yes no) +(NE (CMPconst [0] (LessThan cc)) yes no) => (LT cc yes no) +(NE (CMPconst [0] (LessThanU cc)) yes no) => (ULT cc yes no) +(NE (CMPconst [0] (LessEqual cc)) yes no) => (LE cc yes no) +(NE (CMPconst [0] (LessEqualU cc)) yes no) => (ULE cc yes no) +(NE (CMPconst [0] (GreaterThan cc)) yes no) => (GT cc yes no) +(NE (CMPconst [0] (GreaterThanU cc)) yes no) => (UGT cc yes no) +(NE (CMPconst [0] (GreaterEqual cc)) yes no) => (GE cc yes no) +(NE (CMPconst [0] (GreaterEqualU cc)) yes no) => (UGE cc yes no) // Write barrier. -(WB ...) -> (LoweredWB ...) +(WB ...) => (LoweredWB ...) -(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem) -(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem) -(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 -> (LoweredPanicBoundsC [kind] x y mem) +(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem) +(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem) +(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem) -(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 -> (LoweredPanicExtendA [kind] hi lo y mem) -(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 -> (LoweredPanicExtendB [kind] hi lo y mem) -(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 -> (LoweredPanicExtendC [kind] hi lo y mem) +(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem) +(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem) +(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem) // Optimizations // fold offset into address -(ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) -> (MOVWaddr [off1+off2] {sym} ptr) -(SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) -> (MOVWaddr [off2-off1] {sym} ptr) +(ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off1+off2] {sym} ptr) +(SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off2-off1] {sym} ptr) // fold address into load/store -(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBload [off1+off2] {sym} ptr mem) -(MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVBload [off1-off2] {sym} ptr mem) -(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBUload [off1+off2] {sym} ptr mem) -(MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVBUload [off1-off2] {sym} ptr mem) -(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVHload [off1+off2] {sym} ptr mem) -(MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVHload [off1-off2] {sym} ptr mem) -(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVHUload [off1+off2] {sym} ptr mem) -(MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVHUload [off1-off2] {sym} ptr mem) -(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVWload [off1+off2] {sym} ptr mem) -(MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVWload [off1-off2] {sym} ptr mem) -(MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVFload [off1+off2] {sym} ptr mem) -(MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVFload [off1-off2] {sym} ptr mem) -(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVDload [off1+off2] {sym} ptr mem) -(MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) -> (MOVDload [off1-off2] {sym} ptr mem) +(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBload [off1+off2] {sym} ptr mem) +(MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBload [off1-off2] {sym} ptr mem) +(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBUload [off1+off2] {sym} ptr mem) +(MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBUload [off1-off2] {sym} ptr mem) +(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHload [off1+off2] {sym} ptr mem) +(MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHload [off1-off2] {sym} ptr mem) +(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHUload [off1+off2] {sym} ptr mem) +(MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHUload [off1-off2] {sym} ptr mem) +(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVWload [off1+off2] {sym} ptr mem) +(MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVWload [off1-off2] {sym} ptr mem) +(MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVFload [off1+off2] {sym} ptr mem) +(MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVFload [off1-off2] {sym} ptr mem) +(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVDload [off1+off2] {sym} ptr mem) +(MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVDload [off1-off2] {sym} ptr mem) -(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVBstore [off1+off2] {sym} ptr val mem) -(MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) -> (MOVBstore [off1-off2] {sym} ptr val mem) -(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVHstore [off1+off2] {sym} ptr val mem) -(MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) -> (MOVHstore [off1-off2] {sym} ptr val mem) -(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVWstore [off1+off2] {sym} ptr val mem) -(MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) -> (MOVWstore [off1-off2] {sym} ptr val mem) -(MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVFstore [off1+off2] {sym} ptr val mem) -(MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) -> (MOVFstore [off1-off2] {sym} ptr val mem) -(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVDstore [off1+off2] {sym} ptr val mem) -(MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) -> (MOVDstore [off1-off2] {sym} ptr val mem) +(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVBstore [off1+off2] {sym} ptr val mem) +(MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVBstore [off1-off2] {sym} ptr val mem) +(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVHstore [off1+off2] {sym} ptr val mem) +(MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVHstore [off1-off2] {sym} ptr val mem) +(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVWstore [off1+off2] {sym} ptr val mem) +(MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVWstore [off1-off2] {sym} ptr val mem) +(MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVFstore [off1+off2] {sym} ptr val mem) +(MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVFstore [off1-off2] {sym} ptr val mem) +(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVDstore [off1+off2] {sym} ptr val mem) +(MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVDstore [off1-off2] {sym} ptr val mem) -(MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) -> +(MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) -(MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) -> +(MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) -(MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) -> +(MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) -(MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) -> +(MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) -(MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) -> +(MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) -(MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) -> +(MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) // replace load from same location as preceding store with zero/sign extension (or copy in case of full width) -(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBreg x) -(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBUreg x) -(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHreg x) -(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHUreg x) -(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x +(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBreg x) +(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBUreg x) +(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHreg x) +(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHUreg x) +(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x -(MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x -(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x +(MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x +(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x -(MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> x -(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x -(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x -(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x -(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBUreg x) -(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBreg x) -(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHUreg x) -(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHreg x) +(MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => x +(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x +(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x +(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x +(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBUreg x) +(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBreg x) +(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHUreg x) +(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHreg x) // fold constant into arithmatic ops -(ADD x (MOVWconst [c])) -> (ADDconst [c] x) -(SUB (MOVWconst [c]) x) -> (RSBconst [c] x) -(SUB x (MOVWconst [c])) -> (SUBconst [c] x) -(RSB (MOVWconst [c]) x) -> (SUBconst [c] x) -(RSB x (MOVWconst [c])) -> (RSBconst [c] x) +(ADD x (MOVWconst [c])) => (ADDconst [c] x) +(SUB (MOVWconst [c]) x) => (RSBconst [c] x) +(SUB x (MOVWconst [c])) => (SUBconst [c] x) +(RSB (MOVWconst [c]) x) => (SUBconst [c] x) +(RSB x (MOVWconst [c])) => (RSBconst [c] x) -(ADDS x (MOVWconst [c])) -> (ADDSconst [c] x) -(SUBS x (MOVWconst [c])) -> (SUBSconst [c] x) +(ADDS x (MOVWconst [c])) => (ADDSconst [c] x) +(SUBS x (MOVWconst [c])) => (SUBSconst [c] x) -(ADC (MOVWconst [c]) x flags) -> (ADCconst [c] x flags) -(SBC (MOVWconst [c]) x flags) -> (RSCconst [c] x flags) -(SBC x (MOVWconst [c]) flags) -> (SBCconst [c] x flags) +(ADC (MOVWconst [c]) x flags) => (ADCconst [c] x flags) +(SBC (MOVWconst [c]) x flags) => (RSCconst [c] x flags) +(SBC x (MOVWconst [c]) flags) => (SBCconst [c] x flags) -(AND x (MOVWconst [c])) -> (ANDconst [c] x) -(OR x (MOVWconst [c])) -> (ORconst [c] x) -(XOR x (MOVWconst [c])) -> (XORconst [c] x) -(BIC x (MOVWconst [c])) -> (BICconst [c] x) +(AND x (MOVWconst [c])) => (ANDconst [c] x) +(OR x (MOVWconst [c])) => (ORconst [c] x) +(XOR x (MOVWconst [c])) => (XORconst [c] x) +(BIC x (MOVWconst [c])) => (BICconst [c] x) -(SLL x (MOVWconst [c])) -> (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32) -(SRL x (MOVWconst [c])) -> (SRLconst x [c&31]) -(SRA x (MOVWconst [c])) -> (SRAconst x [c&31]) +(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32) +(SRL x (MOVWconst [c])) => (SRLconst x [c&31]) +(SRA x (MOVWconst [c])) => (SRAconst x [c&31]) -(CMP x (MOVWconst [c])) -> (CMPconst [c] x) -(CMP (MOVWconst [c]) x) -> (InvertFlags (CMPconst [c] x)) -(CMN x (MOVWconst [c])) -> (CMNconst [c] x) -(TST x (MOVWconst [c])) -> (TSTconst [c] x) -(TEQ x (MOVWconst [c])) -> (TEQconst [c] x) +(CMP x (MOVWconst [c])) => (CMPconst [c] x) +(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x)) +(CMN x (MOVWconst [c])) => (CMNconst [c] x) +(TST x (MOVWconst [c])) => (TSTconst [c] x) +(TEQ x (MOVWconst [c])) => (TEQconst [c] x) // Canonicalize the order of arguments to comparisons - helps with CSE. -(CMP x y) && x.ID > y.ID -> (InvertFlags (CMP y x)) +(CMP x y) && x.ID > y.ID => (InvertFlags (CMP y x)) // don't extend after proper load // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type. -(MOVBreg x:(MOVBload _ _)) -> (MOVWreg x) -(MOVBUreg x:(MOVBUload _ _)) -> (MOVWreg x) -(MOVHreg x:(MOVBload _ _)) -> (MOVWreg x) -(MOVHreg x:(MOVBUload _ _)) -> (MOVWreg x) -(MOVHreg x:(MOVHload _ _)) -> (MOVWreg x) -(MOVHUreg x:(MOVBUload _ _)) -> (MOVWreg x) -(MOVHUreg x:(MOVHUload _ _)) -> (MOVWreg x) +(MOVBreg x:(MOVBload _ _)) => (MOVWreg x) +(MOVBUreg x:(MOVBUload _ _)) => (MOVWreg x) +(MOVHreg x:(MOVBload _ _)) => (MOVWreg x) +(MOVHreg x:(MOVBUload _ _)) => (MOVWreg x) +(MOVHreg x:(MOVHload _ _)) => (MOVWreg x) +(MOVHUreg x:(MOVBUload _ _)) => (MOVWreg x) +(MOVHUreg x:(MOVHUload _ _)) => (MOVWreg x) // fold extensions and ANDs together -(MOVBUreg (ANDconst [c] x)) -> (ANDconst [c&0xff] x) -(MOVHUreg (ANDconst [c] x)) -> (ANDconst [c&0xffff] x) -(MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 -> (ANDconst [c&0x7f] x) -(MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 -> (ANDconst [c&0x7fff] x) +(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&0xff] x) +(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&0xffff] x) +(MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 => (ANDconst [c&0x7f] x) +(MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 => (ANDconst [c&0x7fff] x) // fold double extensions -(MOVBreg x:(MOVBreg _)) -> (MOVWreg x) -(MOVBUreg x:(MOVBUreg _)) -> (MOVWreg x) -(MOVHreg x:(MOVBreg _)) -> (MOVWreg x) -(MOVHreg x:(MOVBUreg _)) -> (MOVWreg x) -(MOVHreg x:(MOVHreg _)) -> (MOVWreg x) -(MOVHUreg x:(MOVBUreg _)) -> (MOVWreg x) -(MOVHUreg x:(MOVHUreg _)) -> (MOVWreg x) +(MOVBreg x:(MOVBreg _)) => (MOVWreg x) +(MOVBUreg x:(MOVBUreg _)) => (MOVWreg x) +(MOVHreg x:(MOVBreg _)) => (MOVWreg x) +(MOVHreg x:(MOVBUreg _)) => (MOVWreg x) +(MOVHreg x:(MOVHreg _)) => (MOVWreg x) +(MOVHUreg x:(MOVBUreg _)) => (MOVWreg x) +(MOVHUreg x:(MOVHUreg _)) => (MOVWreg x) // don't extend before store -(MOVBstore [off] {sym} ptr (MOVBreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) -(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) -(MOVBstore [off] {sym} ptr (MOVHreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) -(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) -(MOVHstore [off] {sym} ptr (MOVHreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) -(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem) // if a register move has only 1 use, just use the same register without emitting instruction // MOVWnop doesn't emit instruction, only for ensuring the type. -(MOVWreg x) && x.Uses == 1 -> (MOVWnop x) +(MOVWreg x) && x.Uses == 1 => (MOVWnop x) // mul by constant -(MUL x (MOVWconst [c])) && int32(c) == -1 -> (RSBconst [0] x) -(MUL _ (MOVWconst [0])) -> (MOVWconst [0]) -(MUL x (MOVWconst [1])) -> x -(MUL x (MOVWconst [c])) && isPowerOfTwo(c) -> (SLLconst [log2(c)] x) -(MUL x (MOVWconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADDshiftLL x x [log2(c-1)]) -(MUL x (MOVWconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSBshiftLL x x [log2(c+1)]) -(MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) -(MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) -(MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) -(MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) +(MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x) +(MUL _ (MOVWconst [0])) => (MOVWconst [0]) +(MUL x (MOVWconst [1])) => x +(MUL x (MOVWconst [c])) && isPowerOfTwo32(c) => (SLLconst [int32(log32(c))] x) +(MUL x (MOVWconst [c])) && isPowerOfTwo32(c-1) && c >= 3 => (ADDshiftLL x x [int32(log32(c-1))]) +(MUL x (MOVWconst [c])) && isPowerOfTwo32(c+1) && c >= 7 => (RSBshiftLL x x [int32(log32(c+1))]) +(MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo32(c/3) => (SLLconst [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) +(MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo32(c/5) => (SLLconst [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) +(MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo32(c/7) => (SLLconst [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) +(MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo32(c/9) => (SLLconst [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) -(MULA x (MOVWconst [c]) a) && int32(c) == -1 -> (SUB a x) -(MULA _ (MOVWconst [0]) a) -> a -(MULA x (MOVWconst [1]) a) -> (ADD x a) -(MULA x (MOVWconst [c]) a) && isPowerOfTwo(c) -> (ADD (SLLconst <x.Type> [log2(c)] x) a) -(MULA x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADD (ADDshiftLL <x.Type> x x [log2(c-1)]) a) -(MULA x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (ADD (RSBshiftLL <x.Type> x x [log2(c+1)]) a) -(MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) -(MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) -(MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) -(MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) +(MULA x (MOVWconst [c]) a) && c == -1 => (SUB a x) +(MULA _ (MOVWconst [0]) a) => a +(MULA x (MOVWconst [1]) a) => (ADD x a) +(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a) +(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) +(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) +(MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) +(MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) +(MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) +(MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) -(MULA (MOVWconst [c]) x a) && int32(c) == -1 -> (SUB a x) -(MULA (MOVWconst [0]) _ a) -> a -(MULA (MOVWconst [1]) x a) -> (ADD x a) -(MULA (MOVWconst [c]) x a) && isPowerOfTwo(c) -> (ADD (SLLconst <x.Type> [log2(c)] x) a) -(MULA (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADD (ADDshiftLL <x.Type> x x [log2(c-1)]) a) -(MULA (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (ADD (RSBshiftLL <x.Type> x x [log2(c+1)]) a) -(MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) -(MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) -(MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) -(MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) +(MULA (MOVWconst [c]) x a) && c == -1 => (SUB a x) +(MULA (MOVWconst [0]) _ a) => a +(MULA (MOVWconst [1]) x a) => (ADD x a) +(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a) +(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) +(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) +(MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) +(MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) +(MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) +(MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) -(MULS x (MOVWconst [c]) a) && int32(c) == -1 -> (ADD a x) -(MULS _ (MOVWconst [0]) a) -> a -(MULS x (MOVWconst [1]) a) -> (RSB x a) -(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c) -> (RSB (SLLconst <x.Type> [log2(c)] x) a) -(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a) -(MULS x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a) -(MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) -(MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) -(MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) -(MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) +(MULS x (MOVWconst [c]) a) && c == -1 => (ADD a x) +(MULS _ (MOVWconst [0]) a) => a +(MULS x (MOVWconst [1]) a) => (RSB x a) +(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a) +(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) +(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) +(MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) +(MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) +(MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) +(MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) -(MULS (MOVWconst [c]) x a) && int32(c) == -1 -> (ADD a x) -(MULS (MOVWconst [0]) _ a) -> a -(MULS (MOVWconst [1]) x a) -> (RSB x a) -(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c) -> (RSB (SLLconst <x.Type> [log2(c)] x) a) -(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a) -(MULS (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a) -(MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) -(MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) -(MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) -(MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) +(MULS (MOVWconst [c]) x a) && c == -1 => (ADD a x) +(MULS (MOVWconst [0]) _ a) => a +(MULS (MOVWconst [1]) x a) => (RSB x a) +(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a) +(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) +(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) +(MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) +(MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) +(MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) +(MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) // div by constant -(Select0 (CALLudiv x (MOVWconst [1]))) -> x -(Select1 (CALLudiv _ (MOVWconst [1]))) -> (MOVWconst [0]) -(Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x) -(Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) -> (ANDconst [c-1] x) +(Select0 (CALLudiv x (MOVWconst [1]))) => x +(Select1 (CALLudiv _ (MOVWconst [1]))) => (MOVWconst [0]) +(Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (SRLconst [int32(log32(c))] x) +(Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (ANDconst [c-1] x) // constant comparisons (CMPconst (MOVWconst [x]) [y]) => (FlagConstant [subFlags32(x,y)]) @@ -664,16 +664,16 @@ (GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes) // absorb InvertFlags into branches -(LT (InvertFlags cmp) yes no) -> (GT cmp yes no) -(GT (InvertFlags cmp) yes no) -> (LT cmp yes no) -(LE (InvertFlags cmp) yes no) -> (GE cmp yes no) -(GE (InvertFlags cmp) yes no) -> (LE cmp yes no) -(ULT (InvertFlags cmp) yes no) -> (UGT cmp yes no) -(UGT (InvertFlags cmp) yes no) -> (ULT cmp yes no) -(ULE (InvertFlags cmp) yes no) -> (UGE cmp yes no) -(UGE (InvertFlags cmp) yes no) -> (ULE cmp yes no) -(EQ (InvertFlags cmp) yes no) -> (EQ cmp yes no) -(NE (InvertFlags cmp) yes no) -> (NE cmp yes no) +(LT (InvertFlags cmp) yes no) => (GT cmp yes no) +(GT (InvertFlags cmp) yes no) => (LT cmp yes no) +(LE (InvertFlags cmp) yes no) => (GE cmp yes no) +(GE (InvertFlags cmp) yes no) => (LE cmp yes no) +(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no) +(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no) +(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no) +(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no) +(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no) +(NE (InvertFlags cmp) yes no) => (NE cmp yes no) (LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no) (GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no) (LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no) @@ -692,16 +692,16 @@ (GreaterEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.uge())]) // absorb InvertFlags into boolean values -(Equal (InvertFlags x)) -> (Equal x) -(NotEqual (InvertFlags x)) -> (NotEqual x) -(LessThan (InvertFlags x)) -> (GreaterThan x) -(LessThanU (InvertFlags x)) -> (GreaterThanU x) -(GreaterThan (InvertFlags x)) -> (LessThan x) -(GreaterThanU (InvertFlags x)) -> (LessThanU x) -(LessEqual (InvertFlags x)) -> (GreaterEqual x) -(LessEqualU (InvertFlags x)) -> (GreaterEqualU x) -(GreaterEqual (InvertFlags x)) -> (LessEqual x) -(GreaterEqualU (InvertFlags x)) -> (LessEqualU x) +(Equal (InvertFlags x)) => (Equal x) +(NotEqual (InvertFlags x)) => (NotEqual x) +(LessThan (InvertFlags x)) => (GreaterThan x) +(LessThanU (InvertFlags x)) => (GreaterThanU x) +(GreaterThan (InvertFlags x)) => (LessThan x) +(GreaterThanU (InvertFlags x)) => (LessThanU x) +(LessEqual (InvertFlags x)) => (GreaterEqual x) +(LessEqualU (InvertFlags x)) => (GreaterEqualU x) +(GreaterEqual (InvertFlags x)) => (LessEqual x) +(GreaterEqualU (InvertFlags x)) => (LessEqualU x) // absorb flag constants into conditional instructions (CMOVWLSconst _ (FlagConstant [fc]) [c]) && fc.ule() => (MOVWconst [c]) @@ -710,766 +710,766 @@ (CMOVWHSconst _ (FlagConstant [fc]) [c]) && fc.uge() => (MOVWconst [c]) (CMOVWHSconst x (FlagConstant [fc]) [c]) && fc.ult() => x -(CMOVWLSconst x (InvertFlags flags) [c]) -> (CMOVWHSconst x flags [c]) -(CMOVWHSconst x (InvertFlags flags) [c]) -> (CMOVWLSconst x flags [c]) +(CMOVWLSconst x (InvertFlags flags) [c]) => (CMOVWHSconst x flags [c]) +(CMOVWHSconst x (InvertFlags flags) [c]) => (CMOVWLSconst x flags [c]) (SRAcond x _ (FlagConstant [fc])) && fc.uge() => (SRAconst x [31]) (SRAcond x y (FlagConstant [fc])) && fc.ult() => (SRA x y) // remove redundant *const ops -(ADDconst [0] x) -> x -(SUBconst [0] x) -> x -(ANDconst [0] _) -> (MOVWconst [0]) -(ANDconst [c] x) && int32(c)==-1 -> x -(ORconst [0] x) -> x -(ORconst [c] _) && int32(c)==-1 -> (MOVWconst [-1]) -(XORconst [0] x) -> x -(BICconst [0] x) -> x -(BICconst [c] _) && int32(c)==-1 -> (MOVWconst [0]) +(ADDconst [0] x) => x +(SUBconst [0] x) => x +(ANDconst [0] _) => (MOVWconst [0]) +(ANDconst [c] x) && int32(c)==-1 => x +(ORconst [0] x) => x +(ORconst [c] _) && int32(c)==-1 => (MOVWconst [-1]) +(XORconst [0] x) => x +(BICconst [0] x) => x +(BICconst [c] _) && int32(c)==-1 => (MOVWconst [0]) // generic constant folding -(ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) -> (SUBconst [int64(int32(-c))] x) -(SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) -> (ADDconst [int64(int32(-c))] x) -(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (BICconst [int64(int32(^uint32(c)))] x) -(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) -> (ANDconst [int64(int32(^uint32(c)))] x) -(ADDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff -> (SUBconst [int64(int32(-c))] x) -(SUBconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff -> (ANDconst [int64(int32(-c))] x) -(ANDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff -> (BICconst [int64(int32(^uint32(c)))] x) -(BICconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff -> (ANDconst [int64(int32(^uint32(c)))] x) -(ADDconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(c+d))]) -(ADDconst [c] (ADDconst [d] x)) -> (ADDconst [int64(int32(c+d))] x) -(ADDconst [c] (SUBconst [d] x)) -> (ADDconst [int64(int32(c-d))] x) -(ADDconst [c] (RSBconst [d] x)) -> (RSBconst [int64(int32(c+d))] x) -(ADCconst [c] (ADDconst [d] x) flags) -> (ADCconst [int64(int32(c+d))] x flags) -(ADCconst [c] (SUBconst [d] x) flags) -> (ADCconst [int64(int32(c-d))] x flags) -(SUBconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d-c))]) -(SUBconst [c] (SUBconst [d] x)) -> (ADDconst [int64(int32(-c-d))] x) -(SUBconst [c] (ADDconst [d] x)) -> (ADDconst [int64(int32(-c+d))] x) -(SUBconst [c] (RSBconst [d] x)) -> (RSBconst [int64(int32(-c+d))] x) -(SBCconst [c] (ADDconst [d] x) flags) -> (SBCconst [int64(int32(c-d))] x flags) -(SBCconst [c] (SUBconst [d] x) flags) -> (SBCconst [int64(int32(c+d))] x flags) -(RSBconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(c-d))]) -(RSBconst [c] (RSBconst [d] x)) -> (ADDconst [int64(int32(c-d))] x) -(RSBconst [c] (ADDconst [d] x)) -> (RSBconst [int64(int32(c-d))] x) -(RSBconst [c] (SUBconst [d] x)) -> (RSBconst [int64(int32(c+d))] x) -(RSCconst [c] (ADDconst [d] x) flags) -> (RSCconst [int64(int32(c-d))] x flags) -(RSCconst [c] (SUBconst [d] x) flags) -> (RSCconst [int64(int32(c+d))] x flags) -(SLLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)<<uint64(c)))]) -(SRLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)>>uint64(c)))]) -(SRAconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)>>uint64(c))]) -(MUL (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c*d))]) -(MULA (MOVWconst [c]) (MOVWconst [d]) a) -> (ADDconst [int64(int32(c*d))] a) -(MULS (MOVWconst [c]) (MOVWconst [d]) a) -> (SUBconst [int64(int32(c*d))] a) -(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(int32(uint32(c)/uint32(d)))]) -(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(int32(uint32(c)%uint32(d)))]) -(ANDconst [c] (MOVWconst [d])) -> (MOVWconst [c&d]) -(ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x) -(ORconst [c] (MOVWconst [d])) -> (MOVWconst [c|d]) -(ORconst [c] (ORconst [d] x)) -> (ORconst [c|d] x) -(XORconst [c] (MOVWconst [d])) -> (MOVWconst [c^d]) -(XORconst [c] (XORconst [d] x)) -> (XORconst [c^d] x) -(BICconst [c] (MOVWconst [d])) -> (MOVWconst [d&^c]) -(BICconst [c] (BICconst [d] x)) -> (BICconst [int64(int32(c|d))] x) -(MVN (MOVWconst [c])) -> (MOVWconst [^c]) -(MOVBreg (MOVWconst [c])) -> (MOVWconst [int64(int8(c))]) -(MOVBUreg (MOVWconst [c])) -> (MOVWconst [int64(uint8(c))]) -(MOVHreg (MOVWconst [c])) -> (MOVWconst [int64(int16(c))]) -(MOVHUreg (MOVWconst [c])) -> (MOVWconst [int64(uint16(c))]) -(MOVWreg (MOVWconst [c])) -> (MOVWconst [c]) +(ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (SUBconst [-c] x) +(SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x) +(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x) +(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x) +(ADDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x) +(SUBconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x) +(ANDconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x) +(BICconst [c] x) && objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x) +(ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d]) +(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x) +(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x) +(ADDconst [c] (RSBconst [d] x)) => (RSBconst [c+d] x) +(ADCconst [c] (ADDconst [d] x) flags) => (ADCconst [c+d] x flags) +(ADCconst [c] (SUBconst [d] x) flags) => (ADCconst [c-d] x flags) +(SUBconst [c] (MOVWconst [d])) => (MOVWconst [d-c]) +(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x) +(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x) +(SUBconst [c] (RSBconst [d] x)) => (RSBconst [-c+d] x) +(SBCconst [c] (ADDconst [d] x) flags) => (SBCconst [c-d] x flags) +(SBCconst [c] (SUBconst [d] x) flags) => (SBCconst [c+d] x flags) +(RSBconst [c] (MOVWconst [d])) => (MOVWconst [c-d]) +(RSBconst [c] (RSBconst [d] x)) => (ADDconst [c-d] x) +(RSBconst [c] (ADDconst [d] x)) => (RSBconst [c-d] x) +(RSBconst [c] (SUBconst [d] x)) => (RSBconst [c+d] x) +(RSCconst [c] (ADDconst [d] x) flags) => (RSCconst [c-d] x flags) +(RSCconst [c] (SUBconst [d] x) flags) => (RSCconst [c+d] x flags) +(SLLconst [c] (MOVWconst [d])) => (MOVWconst [d<<uint64(c)]) +(SRLconst [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)>>uint64(c))]) +(SRAconst [c] (MOVWconst [d])) => (MOVWconst [d>>uint64(c)]) +(MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d]) +(MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a) +(MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [c*d] a) +(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))]) +(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))]) +(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d]) +(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) +(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d]) +(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x) +(XORconst [c] (MOVWconst [d])) => (MOVWconst [c^d]) +(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x) +(BICconst [c] (MOVWconst [d])) => (MOVWconst [d&^c]) +(BICconst [c] (BICconst [d] x)) => (BICconst [c|d] x) +(MVN (MOVWconst [c])) => (MOVWconst [^c]) +(MOVBreg (MOVWconst [c])) => (MOVWconst [int32(int8(c))]) +(MOVBUreg (MOVWconst [c])) => (MOVWconst [int32(uint8(c))]) +(MOVHreg (MOVWconst [c])) => (MOVWconst [int32(int16(c))]) +(MOVHUreg (MOVWconst [c])) => (MOVWconst [int32(uint16(c))]) +(MOVWreg (MOVWconst [c])) => (MOVWconst [c]) // BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width) -(BFX [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))]) -(BFXU [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))))]) +(BFX [c] (MOVWconst [d])) => (MOVWconst [d<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))]) +(BFXU [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))]) // absorb shifts into ops -(ADD x (SLLconst [c] y)) -> (ADDshiftLL x y [c]) -(ADD x (SRLconst [c] y)) -> (ADDshiftRL x y [c]) -(ADD x (SRAconst [c] y)) -> (ADDshiftRA x y [c]) -(ADD x (SLL y z)) -> (ADDshiftLLreg x y z) -(ADD x (SRL y z)) -> (ADDshiftRLreg x y z) -(ADD x (SRA y z)) -> (ADDshiftRAreg x y z) -(ADC x (SLLconst [c] y) flags) -> (ADCshiftLL x y [c] flags) -(ADC x (SRLconst [c] y) flags) -> (ADCshiftRL x y [c] flags) -(ADC x (SRAconst [c] y) flags) -> (ADCshiftRA x y [c] flags) -(ADC x (SLL y z) flags) -> (ADCshiftLLreg x y z flags) -(ADC x (SRL y z) flags) -> (ADCshiftRLreg x y z flags) -(ADC x (SRA y z) flags) -> (ADCshiftRAreg x y z flags) -(ADDS x (SLLconst [c] y)) -> (ADDSshiftLL x y [c]) -(ADDS x (SRLconst [c] y)) -> (ADDSshiftRL x y [c]) -(ADDS x (SRAconst [c] y)) -> (ADDSshiftRA x y [c]) -(ADDS x (SLL y z)) -> (ADDSshiftLLreg x y z) -(ADDS x (SRL y z)) -> (ADDSshiftRLreg x y z) -(ADDS x (SRA y z)) -> (ADDSshiftRAreg x y z) -(SUB x (SLLconst [c] y)) -> (SUBshiftLL x y [c]) -(SUB (SLLconst [c] y) x) -> (RSBshiftLL x y [c]) -(SUB x (SRLconst [c] y)) -> (SUBshiftRL x y [c]) -(SUB (SRLconst [c] y) x) -> (RSBshiftRL x y [c]) -(SUB x (SRAconst [c] y)) -> (SUBshiftRA x y [c]) -(SUB (SRAconst [c] y) x) -> (RSBshiftRA x y [c]) -(SUB x (SLL y z)) -> (SUBshiftLLreg x y z) -(SUB (SLL y z) x) -> (RSBshiftLLreg x y z) -(SUB x (SRL y z)) -> (SUBshiftRLreg x y z) -(SUB (SRL y z) x) -> (RSBshiftRLreg x y z) -(SUB x (SRA y z)) -> (SUBshiftRAreg x y z) -(SUB (SRA y z) x) -> (RSBshiftRAreg x y z) -(SBC x (SLLconst [c] y) flags) -> (SBCshiftLL x y [c] flags) -(SBC (SLLconst [c] y) x flags) -> (RSCshiftLL x y [c] flags) -(SBC x (SRLconst [c] y) flags) -> (SBCshiftRL x y [c] flags) -(SBC (SRLconst [c] y) x flags) -> (RSCshiftRL x y [c] flags) -(SBC x (SRAconst [c] y) flags) -> (SBCshiftRA x y [c] flags) -(SBC (SRAconst [c] y) x flags) -> (RSCshiftRA x y [c] flags) -(SBC x (SLL y z) flags) -> (SBCshiftLLreg x y z flags) -(SBC (SLL y z) x flags) -> (RSCshiftLLreg x y z flags) -(SBC x (SRL y z) flags) -> (SBCshiftRLreg x y z flags) -(SBC (SRL y z) x flags) -> (RSCshiftRLreg x y z flags) -(SBC x (SRA y z) flags) -> (SBCshiftRAreg x y z flags) -(SBC (SRA y z) x flags) -> (RSCshiftRAreg x y z flags) -(SUBS x (SLLconst [c] y)) -> (SUBSshiftLL x y [c]) -(SUBS (SLLconst [c] y) x) -> (RSBSshiftLL x y [c]) -(SUBS x (SRLconst [c] y)) -> (SUBSshiftRL x y [c]) -(SUBS (SRLconst [c] y) x) -> (RSBSshiftRL x y [c]) -(SUBS x (SRAconst [c] y)) -> (SUBSshiftRA x y [c]) -(SUBS (SRAconst [c] y) x) -> (RSBSshiftRA x y [c]) -(SUBS x (SLL y z)) -> (SUBSshiftLLreg x y z) -(SUBS (SLL y z) x) -> (RSBSshiftLLreg x y z) -(SUBS x (SRL y z)) -> (SUBSshiftRLreg x y z) -(SUBS (SRL y z) x) -> (RSBSshiftRLreg x y z) -(SUBS x (SRA y z)) -> (SUBSshiftRAreg x y z) -(SUBS (SRA y z) x) -> (RSBSshiftRAreg x y z) -(RSB x (SLLconst [c] y)) -> (RSBshiftLL x y [c]) -(RSB (SLLconst [c] y) x) -> (SUBshiftLL x y [c]) -(RSB x (SRLconst [c] y)) -> (RSBshiftRL x y [c]) -(RSB (SRLconst [c] y) x) -> (SUBshiftRL x y [c]) -(RSB x (SRAconst [c] y)) -> (RSBshiftRA x y [c]) -(RSB (SRAconst [c] y) x) -> (SUBshiftRA x y [c]) -(RSB x (SLL y z)) -> (RSBshiftLLreg x y z) -(RSB (SLL y z) x) -> (SUBshiftLLreg x y z) -(RSB x (SRL y z)) -> (RSBshiftRLreg x y z) -(RSB (SRL y z) x) -> (SUBshiftRLreg x y z) -(RSB x (SRA y z)) -> (RSBshiftRAreg x y z) -(RSB (SRA y z) x) -> (SUBshiftRAreg x y z) -(AND x (SLLconst [c] y)) -> (ANDshiftLL x y [c]) -(AND x (SRLconst [c] y)) -> (ANDshiftRL x y [c]) -(AND x (SRAconst [c] y)) -> (ANDshiftRA x y [c]) -(AND x (SLL y z)) -> (ANDshiftLLreg x y z) -(AND x (SRL y z)) -> (ANDshiftRLreg x y z) -(AND x (SRA y z)) -> (ANDshiftRAreg x y z) -(OR x (SLLconst [c] y)) -> (ORshiftLL x y [c]) -(OR x (SRLconst [c] y)) -> (ORshiftRL x y [c]) -(OR x (SRAconst [c] y)) -> (ORshiftRA x y [c]) -(OR x (SLL y z)) -> (ORshiftLLreg x y z) -(OR x (SRL y z)) -> (ORshiftRLreg x y z) -(OR x (SRA y z)) -> (ORshiftRAreg x y z) -(XOR x (SLLconst [c] y)) -> (XORshiftLL x y [c]) -(XOR x (SRLconst [c] y)) -> (XORshiftRL x y [c]) -(XOR x (SRAconst [c] y)) -> (XORshiftRA x y [c]) -(XOR x (SRRconst [c] y)) -> (XORshiftRR x y [c]) -(XOR x (SLL y z)) -> (XORshiftLLreg x y z) -(XOR x (SRL y z)) -> (XORshiftRLreg x y z) -(XOR x (SRA y z)) -> (XORshiftRAreg x y z) -(BIC x (SLLconst [c] y)) -> (BICshiftLL x y [c]) -(BIC x (SRLconst [c] y)) -> (BICshiftRL x y [c]) -(BIC x (SRAconst [c] y)) -> (BICshiftRA x y [c]) -(BIC x (SLL y z)) -> (BICshiftLLreg x y z) -(BIC x (SRL y z)) -> (BICshiftRLreg x y z) -(BIC x (SRA y z)) -> (BICshiftRAreg x y z) -(MVN (SLLconst [c] x)) -> (MVNshiftLL x [c]) -(MVN (SRLconst [c] x)) -> (MVNshiftRL x [c]) -(MVN (SRAconst [c] x)) -> (MVNshiftRA x [c]) -(MVN (SLL x y)) -> (MVNshiftLLreg x y) -(MVN (SRL x y)) -> (MVNshiftRLreg x y) -(MVN (SRA x y)) -> (MVNshiftRAreg x y) +(ADD x (SLLconst [c] y)) => (ADDshiftLL x y [c]) +(ADD x (SRLconst [c] y)) => (ADDshiftRL x y [c]) +(ADD x (SRAconst [c] y)) => (ADDshiftRA x y [c]) +(ADD x (SLL y z)) => (ADDshiftLLreg x y z) +(ADD x (SRL y z)) => (ADDshiftRLreg x y z) +(ADD x (SRA y z)) => (ADDshiftRAreg x y z) +(ADC x (SLLconst [c] y) flags) => (ADCshiftLL x y [c] flags) +(ADC x (SRLconst [c] y) flags) => (ADCshiftRL x y [c] flags) +(ADC x (SRAconst [c] y) flags) => (ADCshiftRA x y [c] flags) +(ADC x (SLL y z) flags) => (ADCshiftLLreg x y z flags) +(ADC x (SRL y z) flags) => (ADCshiftRLreg x y z flags) +(ADC x (SRA y z) flags) => (ADCshiftRAreg x y z flags) +(ADDS x (SLLconst [c] y)) => (ADDSshiftLL x y [c]) +(ADDS x (SRLconst [c] y)) => (ADDSshiftRL x y [c]) +(ADDS x (SRAconst [c] y)) => (ADDSshiftRA x y [c]) +(ADDS x (SLL y z)) => (ADDSshiftLLreg x y z) +(ADDS x (SRL y z)) => (ADDSshiftRLreg x y z) +(ADDS x (SRA y z)) => (ADDSshiftRAreg x y z) +(SUB x (SLLconst [c] y)) => (SUBshiftLL x y [c]) +(SUB (SLLconst [c] y) x) => (RSBshiftLL x y [c]) +(SUB x (SRLconst [c] y)) => (SUBshiftRL x y [c]) +(SUB (SRLconst [c] y) x) => (RSBshiftRL x y [c]) +(SUB x (SRAconst [c] y)) => (SUBshiftRA x y [c]) +(SUB (SRAconst [c] y) x) => (RSBshiftRA x y [c]) +(SUB x (SLL y z)) => (SUBshiftLLreg x y z) +(SUB (SLL y z) x) => (RSBshiftLLreg x y z) +(SUB x (SRL y z)) => (SUBshiftRLreg x y z) +(SUB (SRL y z) x) => (RSBshiftRLreg x y z) +(SUB x (SRA y z)) => (SUBshiftRAreg x y z) +(SUB (SRA y z) x) => (RSBshiftRAreg x y z) +(SBC x (SLLconst [c] y) flags) => (SBCshiftLL x y [c] flags) +(SBC (SLLconst [c] y) x flags) => (RSCshiftLL x y [c] flags) +(SBC x (SRLconst [c] y) flags) => (SBCshiftRL x y [c] flags) +(SBC (SRLconst [c] y) x flags) => (RSCshiftRL x y [c] flags) +(SBC x (SRAconst [c] y) flags) => (SBCshiftRA x y [c] flags) +(SBC (SRAconst [c] y) x flags) => (RSCshiftRA x y [c] flags) +(SBC x (SLL y z) flags) => (SBCshiftLLreg x y z flags) +(SBC (SLL y z) x flags) => (RSCshiftLLreg x y z flags) +(SBC x (SRL y z) flags) => (SBCshiftRLreg x y z flags) +(SBC (SRL y z) x flags) => (RSCshiftRLreg x y z flags) +(SBC x (SRA y z) flags) => (SBCshiftRAreg x y z flags) +(SBC (SRA y z) x flags) => (RSCshiftRAreg x y z flags) +(SUBS x (SLLconst [c] y)) => (SUBSshiftLL x y [c]) +(SUBS (SLLconst [c] y) x) => (RSBSshiftLL x y [c]) +(SUBS x (SRLconst [c] y)) => (SUBSshiftRL x y [c]) +(SUBS (SRLconst [c] y) x) => (RSBSshiftRL x y [c]) +(SUBS x (SRAconst [c] y)) => (SUBSshiftRA x y [c]) +(SUBS (SRAconst [c] y) x) => (RSBSshiftRA x y [c]) +(SUBS x (SLL y z)) => (SUBSshiftLLreg x y z) +(SUBS (SLL y z) x) => (RSBSshiftLLreg x y z) +(SUBS x (SRL y z)) => (SUBSshiftRLreg x y z) +(SUBS (SRL y z) x) => (RSBSshiftRLreg x y z) +(SUBS x (SRA y z)) => (SUBSshiftRAreg x y z) +(SUBS (SRA y z) x) => (RSBSshiftRAreg x y z) +(RSB x (SLLconst [c] y)) => (RSBshiftLL x y [c]) +(RSB (SLLconst [c] y) x) => (SUBshiftLL x y [c]) +(RSB x (SRLconst [c] y)) => (RSBshiftRL x y [c]) +(RSB (SRLconst [c] y) x) => (SUBshiftRL x y [c]) +(RSB x (SRAconst [c] y)) => (RSBshiftRA x y [c]) +(RSB (SRAconst [c] y) x) => (SUBshiftRA x y [c]) +(RSB x (SLL y z)) => (RSBshiftLLreg x y z) +(RSB (SLL y z) x) => (SUBshiftLLreg x y z) +(RSB x (SRL y z)) => (RSBshiftRLreg x y z) +(RSB (SRL y z) x) => (SUBshiftRLreg x y z) +(RSB x (SRA y z)) => (RSBshiftRAreg x y z) +(RSB (SRA y z) x) => (SUBshiftRAreg x y z) +(AND x (SLLconst [c] y)) => (ANDshiftLL x y [c]) +(AND x (SRLconst [c] y)) => (ANDshiftRL x y [c]) +(AND x (SRAconst [c] y)) => (ANDshiftRA x y [c]) +(AND x (SLL y z)) => (ANDshiftLLreg x y z) +(AND x (SRL y z)) => (ANDshiftRLreg x y z) +(AND x (SRA y z)) => (ANDshiftRAreg x y z) +(OR x (SLLconst [c] y)) => (ORshiftLL x y [c]) +(OR x (SRLconst [c] y)) => (ORshiftRL x y [c]) +(OR x (SRAconst [c] y)) => (ORshiftRA x y [c]) +(OR x (SLL y z)) => (ORshiftLLreg x y z) +(OR x (SRL y z)) => (ORshiftRLreg x y z) +(OR x (SRA y z)) => (ORshiftRAreg x y z) +(XOR x (SLLconst [c] y)) => (XORshiftLL x y [c]) +(XOR x (SRLconst [c] y)) => (XORshiftRL x y [c]) +(XOR x (SRAconst [c] y)) => (XORshiftRA x y [c]) +(XOR x (SRRconst [c] y)) => (XORshiftRR x y [c]) +(XOR x (SLL y z)) => (XORshiftLLreg x y z) +(XOR x (SRL y z)) => (XORshiftRLreg x y z) +(XOR x (SRA y z)) => (XORshiftRAreg x y z) +(BIC x (SLLconst [c] y)) => (BICshiftLL x y [c]) +(BIC x (SRLconst [c] y)) => (BICshiftRL x y [c]) +(BIC x (SRAconst [c] y)) => (BICshiftRA x y [c]) +(BIC x (SLL y z)) => (BICshiftLLreg x y z) +(BIC x (SRL y z)) => (BICshiftRLreg x y z) +(BIC x (SRA y z)) => (BICshiftRAreg x y z) +(MVN (SLLconst [c] x)) => (MVNshiftLL x [c]) +(MVN (SRLconst [c] x)) => (MVNshiftRL x [c]) +(MVN (SRAconst [c] x)) => (MVNshiftRA x [c]) +(MVN (SLL x y)) => (MVNshiftLLreg x y) +(MVN (SRL x y)) => (MVNshiftRLreg x y) +(MVN (SRA x y)) => (MVNshiftRAreg x y) -(CMP x (SLLconst [c] y)) -> (CMPshiftLL x y [c]) -(CMP (SLLconst [c] y) x) -> (InvertFlags (CMPshiftLL x y [c])) -(CMP x (SRLconst [c] y)) -> (CMPshiftRL x y [c]) -(CMP (SRLconst [c] y) x) -> (InvertFlags (CMPshiftRL x y [c])) -(CMP x (SRAconst [c] y)) -> (CMPshiftRA x y [c]) -(CMP (SRAconst [c] y) x) -> (InvertFlags (CMPshiftRA x y [c])) -(CMP x (SLL y z)) -> (CMPshiftLLreg x y z) -(CMP (SLL y z) x) -> (InvertFlags (CMPshiftLLreg x y z)) -(CMP x (SRL y z)) -> (CMPshiftRLreg x y z) -(CMP (SRL y z) x) -> (InvertFlags (CMPshiftRLreg x y z)) -(CMP x (SRA y z)) -> (CMPshiftRAreg x y z) -(CMP (SRA y z) x) -> (InvertFlags (CMPshiftRAreg x y z)) -(TST x (SLLconst [c] y)) -> (TSTshiftLL x y [c]) -(TST x (SRLconst [c] y)) -> (TSTshiftRL x y [c]) -(TST x (SRAconst [c] y)) -> (TSTshiftRA x y [c]) -(TST x (SLL y z)) -> (TSTshiftLLreg x y z) -(TST x (SRL y z)) -> (TSTshiftRLreg x y z) -(TST x (SRA y z)) -> (TSTshiftRAreg x y z) -(TEQ x (SLLconst [c] y)) -> (TEQshiftLL x y [c]) -(TEQ x (SRLconst [c] y)) -> (TEQshiftRL x y [c]) -(TEQ x (SRAconst [c] y)) -> (TEQshiftRA x y [c]) -(TEQ x (SLL y z)) -> (TEQshiftLLreg x y z) -(TEQ x (SRL y z)) -> (TEQshiftRLreg x y z) -(TEQ x (SRA y z)) -> (TEQshiftRAreg x y z) -(CMN x (SLLconst [c] y)) -> (CMNshiftLL x y [c]) -(CMN x (SRLconst [c] y)) -> (CMNshiftRL x y [c]) -(CMN x (SRAconst [c] y)) -> (CMNshiftRA x y [c]) -(CMN x (SLL y z)) -> (CMNshiftLLreg x y z) -(CMN x (SRL y z)) -> (CMNshiftRLreg x y z) -(CMN x (SRA y z)) -> (CMNshiftRAreg x y z) +(CMP x (SLLconst [c] y)) => (CMPshiftLL x y [c]) +(CMP (SLLconst [c] y) x) => (InvertFlags (CMPshiftLL x y [c])) +(CMP x (SRLconst [c] y)) => (CMPshiftRL x y [c]) +(CMP (SRLconst [c] y) x) => (InvertFlags (CMPshiftRL x y [c])) +(CMP x (SRAconst [c] y)) => (CMPshiftRA x y [c]) +(CMP (SRAconst [c] y) x) => (InvertFlags (CMPshiftRA x y [c])) +(CMP x (SLL y z)) => (CMPshiftLLreg x y z) +(CMP (SLL y z) x) => (InvertFlags (CMPshiftLLreg x y z)) +(CMP x (SRL y z)) => (CMPshiftRLreg x y z) +(CMP (SRL y z) x) => (InvertFlags (CMPshiftRLreg x y z)) +(CMP x (SRA y z)) => (CMPshiftRAreg x y z) +(CMP (SRA y z) x) => (InvertFlags (CMPshiftRAreg x y z)) +(TST x (SLLconst [c] y)) => (TSTshiftLL x y [c]) +(TST x (SRLconst [c] y)) => (TSTshiftRL x y [c]) +(TST x (SRAconst [c] y)) => (TSTshiftRA x y [c]) +(TST x (SLL y z)) => (TSTshiftLLreg x y z) +(TST x (SRL y z)) => (TSTshiftRLreg x y z) +(TST x (SRA y z)) => (TSTshiftRAreg x y z) +(TEQ x (SLLconst [c] y)) => (TEQshiftLL x y [c]) +(TEQ x (SRLconst [c] y)) => (TEQshiftRL x y [c]) +(TEQ x (SRAconst [c] y)) => (TEQshiftRA x y [c]) +(TEQ x (SLL y z)) => (TEQshiftLLreg x y z) +(TEQ x (SRL y z)) => (TEQshiftRLreg x y z) +(TEQ x (SRA y z)) => (TEQshiftRAreg x y z) +(CMN x (SLLconst [c] y)) => (CMNshiftLL x y [c]) +(CMN x (SRLconst [c] y)) => (CMNshiftRL x y [c]) +(CMN x (SRAconst [c] y)) => (CMNshiftRA x y [c]) +(CMN x (SLL y z)) => (CMNshiftLLreg x y z) +(CMN x (SRL y z)) => (CMNshiftRLreg x y z) +(CMN x (SRA y z)) => (CMNshiftRAreg x y z) // prefer *const ops to *shift ops -(ADDshiftLL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d])) -(ADDshiftRL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SRLconst <x.Type> x [d])) -(ADDshiftRA (MOVWconst [c]) x [d]) -> (ADDconst [c] (SRAconst <x.Type> x [d])) -(ADCshiftLL (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SLLconst <x.Type> x [d]) flags) -(ADCshiftRL (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SRLconst <x.Type> x [d]) flags) -(ADCshiftRA (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SRAconst <x.Type> x [d]) flags) -(ADDSshiftLL (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SLLconst <x.Type> x [d])) -(ADDSshiftRL (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SRLconst <x.Type> x [d])) -(ADDSshiftRA (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SRAconst <x.Type> x [d])) -(SUBshiftLL (MOVWconst [c]) x [d]) -> (RSBconst [c] (SLLconst <x.Type> x [d])) -(SUBshiftRL (MOVWconst [c]) x [d]) -> (RSBconst [c] (SRLconst <x.Type> x [d])) -(SUBshiftRA (MOVWconst [c]) x [d]) -> (RSBconst [c] (SRAconst <x.Type> x [d])) -(SBCshiftLL (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SLLconst <x.Type> x [d]) flags) -(SBCshiftRL (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SRLconst <x.Type> x [d]) flags) -(SBCshiftRA (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SRAconst <x.Type> x [d]) flags) -(SUBSshiftLL (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SLLconst <x.Type> x [d])) -(SUBSshiftRL (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SRLconst <x.Type> x [d])) -(SUBSshiftRA (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SRAconst <x.Type> x [d])) -(RSBshiftLL (MOVWconst [c]) x [d]) -> (SUBconst [c] (SLLconst <x.Type> x [d])) -(RSBshiftRL (MOVWconst [c]) x [d]) -> (SUBconst [c] (SRLconst <x.Type> x [d])) -(RSBshiftRA (MOVWconst [c]) x [d]) -> (SUBconst [c] (SRAconst <x.Type> x [d])) -(RSCshiftLL (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SLLconst <x.Type> x [d]) flags) -(RSCshiftRL (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SRLconst <x.Type> x [d]) flags) -(RSCshiftRA (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SRAconst <x.Type> x [d]) flags) -(RSBSshiftLL (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SLLconst <x.Type> x [d])) -(RSBSshiftRL (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SRLconst <x.Type> x [d])) -(RSBSshiftRA (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SRAconst <x.Type> x [d])) -(ANDshiftLL (MOVWconst [c]) x [d]) -> (ANDconst [c] (SLLconst <x.Type> x [d])) -(ANDshiftRL (MOVWconst [c]) x [d]) -> (ANDconst [c] (SRLconst <x.Type> x [d])) -(ANDshiftRA (MOVWconst [c]) x [d]) -> (ANDconst [c] (SRAconst <x.Type> x [d])) -(ORshiftLL (MOVWconst [c]) x [d]) -> (ORconst [c] (SLLconst <x.Type> x [d])) -(ORshiftRL (MOVWconst [c]) x [d]) -> (ORconst [c] (SRLconst <x.Type> x [d])) -(ORshiftRA (MOVWconst [c]) x [d]) -> (ORconst [c] (SRAconst <x.Type> x [d])) -(XORshiftLL (MOVWconst [c]) x [d]) -> (XORconst [c] (SLLconst <x.Type> x [d])) -(XORshiftRL (MOVWconst [c]) x [d]) -> (XORconst [c] (SRLconst <x.Type> x [d])) -(XORshiftRA (MOVWconst [c]) x [d]) -> (XORconst [c] (SRAconst <x.Type> x [d])) -(XORshiftRR (MOVWconst [c]) x [d]) -> (XORconst [c] (SRRconst <x.Type> x [d])) -(CMPshiftLL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d]))) -(CMPshiftRL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d]))) -(CMPshiftRA (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d]))) -(TSTshiftLL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SLLconst <x.Type> x [d])) -(TSTshiftRL (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRLconst <x.Type> x [d])) -(TSTshiftRA (MOVWconst [c]) x [d]) -> (TSTconst [c] (SRAconst <x.Type> x [d])) -(TEQshiftLL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SLLconst <x.Type> x [d])) -(TEQshiftRL (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRLconst <x.Type> x [d])) -(TEQshiftRA (MOVWconst [c]) x [d]) -> (TEQconst [c] (SRAconst <x.Type> x [d])) -(CMNshiftLL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SLLconst <x.Type> x [d])) -(CMNshiftRL (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRLconst <x.Type> x [d])) -(CMNshiftRA (MOVWconst [c]) x [d]) -> (CMNconst [c] (SRAconst <x.Type> x [d])) +(ADDshiftLL (MOVWconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d])) +(ADDshiftRL (MOVWconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d])) +(ADDshiftRA (MOVWconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d])) +(ADCshiftLL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SLLconst <x.Type> x [d]) flags) +(ADCshiftRL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRLconst <x.Type> x [d]) flags) +(ADCshiftRA (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRAconst <x.Type> x [d]) flags) +(ADDSshiftLL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SLLconst <x.Type> x [d])) +(ADDSshiftRL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRLconst <x.Type> x [d])) +(ADDSshiftRA (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRAconst <x.Type> x [d])) +(SUBshiftLL (MOVWconst [c]) x [d]) => (RSBconst [c] (SLLconst <x.Type> x [d])) +(SUBshiftRL (MOVWconst [c]) x [d]) => (RSBconst [c] (SRLconst <x.Type> x [d])) +(SUBshiftRA (MOVWconst [c]) x [d]) => (RSBconst [c] (SRAconst <x.Type> x [d])) +(SBCshiftLL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SLLconst <x.Type> x [d]) flags) +(SBCshiftRL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRLconst <x.Type> x [d]) flags) +(SBCshiftRA (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRAconst <x.Type> x [d]) flags) +(SUBSshiftLL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SLLconst <x.Type> x [d])) +(SUBSshiftRL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRLconst <x.Type> x [d])) +(SUBSshiftRA (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRAconst <x.Type> x [d])) +(RSBshiftLL (MOVWconst [c]) x [d]) => (SUBconst [c] (SLLconst <x.Type> x [d])) +(RSBshiftRL (MOVWconst [c]) x [d]) => (SUBconst [c] (SRLconst <x.Type> x [d])) +(RSBshiftRA (MOVWconst [c]) x [d]) => (SUBconst [c] (SRAconst <x.Type> x [d])) +(RSCshiftLL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SLLconst <x.Type> x [d]) flags) +(RSCshiftRL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRLconst <x.Type> x [d]) flags) +(RSCshiftRA (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRAconst <x.Type> x [d]) flags) +(RSBSshiftLL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SLLconst <x.Type> x [d])) +(RSBSshiftRL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRLconst <x.Type> x [d])) +(RSBSshiftRA (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRAconst <x.Type> x [d])) +(ANDshiftLL (MOVWconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d])) +(ANDshiftRL (MOVWconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d])) +(ANDshiftRA (MOVWconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d])) +(ORshiftLL (MOVWconst [c]) x [d]) => (ORconst [c] (SLLconst <x.Type> x [d])) +(ORshiftRL (MOVWconst [c]) x [d]) => (ORconst [c] (SRLconst <x.Type> x [d])) +(ORshiftRA (MOVWconst [c]) x [d]) => (ORconst [c] (SRAconst <x.Type> x [d])) +(XORshiftLL (MOVWconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d])) +(XORshiftRL (MOVWconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d])) +(XORshiftRA (MOVWconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d])) +(XORshiftRR (MOVWconst [c]) x [d]) => (XORconst [c] (SRRconst <x.Type> x [d])) +(CMPshiftLL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d]))) +(CMPshiftRL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d]))) +(CMPshiftRA (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d]))) +(TSTshiftLL (MOVWconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d])) +(TSTshiftRL (MOVWconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d])) +(TSTshiftRA (MOVWconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d])) +(TEQshiftLL (MOVWconst [c]) x [d]) => (TEQconst [c] (SLLconst <x.Type> x [d])) +(TEQshiftRL (MOVWconst [c]) x [d]) => (TEQconst [c] (SRLconst <x.Type> x [d])) +(TEQshiftRA (MOVWconst [c]) x [d]) => (TEQconst [c] (SRAconst <x.Type> x [d])) +(CMNshiftLL (MOVWconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d])) +(CMNshiftRL (MOVWconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d])) +(CMNshiftRA (MOVWconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d])) -(ADDshiftLLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SLL <x.Type> x y)) -(ADDshiftRLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRL <x.Type> x y)) -(ADDshiftRAreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRA <x.Type> x y)) -(ADCshiftLLreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SLL <x.Type> x y) flags) -(ADCshiftRLreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SRL <x.Type> x y) flags) -(ADCshiftRAreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SRA <x.Type> x y) flags) -(ADDSshiftLLreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SLL <x.Type> x y)) -(ADDSshiftRLreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SRL <x.Type> x y)) -(ADDSshiftRAreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SRA <x.Type> x y)) -(SUBshiftLLreg (MOVWconst [c]) x y) -> (RSBconst [c] (SLL <x.Type> x y)) -(SUBshiftRLreg (MOVWconst [c]) x y) -> (RSBconst [c] (SRL <x.Type> x y)) -(SUBshiftRAreg (MOVWconst [c]) x y) -> (RSBconst [c] (SRA <x.Type> x y)) -(SBCshiftLLreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SLL <x.Type> x y) flags) -(SBCshiftRLreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SRL <x.Type> x y) flags) -(SBCshiftRAreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SRA <x.Type> x y) flags) -(SUBSshiftLLreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SLL <x.Type> x y)) -(SUBSshiftRLreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SRL <x.Type> x y)) -(SUBSshiftRAreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SRA <x.Type> x y)) -(RSBshiftLLreg (MOVWconst [c]) x y) -> (SUBconst [c] (SLL <x.Type> x y)) -(RSBshiftRLreg (MOVWconst [c]) x y) -> (SUBconst [c] (SRL <x.Type> x y)) -(RSBshiftRAreg (MOVWconst [c]) x y) -> (SUBconst [c] (SRA <x.Type> x y)) -(RSCshiftLLreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SLL <x.Type> x y) flags) -(RSCshiftRLreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SRL <x.Type> x y) flags) -(RSCshiftRAreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SRA <x.Type> x y) flags) -(RSBSshiftLLreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SLL <x.Type> x y)) -(RSBSshiftRLreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SRL <x.Type> x y)) -(RSBSshiftRAreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SRA <x.Type> x y)) -(ANDshiftLLreg (MOVWconst [c]) x y) -> (ANDconst [c] (SLL <x.Type> x y)) -(ANDshiftRLreg (MOVWconst [c]) x y) -> (ANDconst [c] (SRL <x.Type> x y)) -(ANDshiftRAreg (MOVWconst [c]) x y) -> (ANDconst [c] (SRA <x.Type> x y)) -(ORshiftLLreg (MOVWconst [c]) x y) -> (ORconst [c] (SLL <x.Type> x y)) -(ORshiftRLreg (MOVWconst [c]) x y) -> (ORconst [c] (SRL <x.Type> x y)) -(ORshiftRAreg (MOVWconst [c]) x y) -> (ORconst [c] (SRA <x.Type> x y)) -(XORshiftLLreg (MOVWconst [c]) x y) -> (XORconst [c] (SLL <x.Type> x y)) -(XORshiftRLreg (MOVWconst [c]) x y) -> (XORconst [c] (SRL <x.Type> x y)) -(XORshiftRAreg (MOVWconst [c]) x y) -> (XORconst [c] (SRA <x.Type> x y)) -(CMPshiftLLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SLL <x.Type> x y))) -(CMPshiftRLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRL <x.Type> x y))) -(CMPshiftRAreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRA <x.Type> x y))) -(TSTshiftLLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SLL <x.Type> x y)) -(TSTshiftRLreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRL <x.Type> x y)) -(TSTshiftRAreg (MOVWconst [c]) x y) -> (TSTconst [c] (SRA <x.Type> x y)) -(TEQshiftLLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SLL <x.Type> x y)) -(TEQshiftRLreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRL <x.Type> x y)) -(TEQshiftRAreg (MOVWconst [c]) x y) -> (TEQconst [c] (SRA <x.Type> x y)) -(CMNshiftLLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SLL <x.Type> x y)) -(CMNshiftRLreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRL <x.Type> x y)) -(CMNshiftRAreg (MOVWconst [c]) x y) -> (CMNconst [c] (SRA <x.Type> x y)) +(ADDshiftLLreg (MOVWconst [c]) x y) => (ADDconst [c] (SLL <x.Type> x y)) +(ADDshiftRLreg (MOVWconst [c]) x y) => (ADDconst [c] (SRL <x.Type> x y)) +(ADDshiftRAreg (MOVWconst [c]) x y) => (ADDconst [c] (SRA <x.Type> x y)) +(ADCshiftLLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SLL <x.Type> x y) flags) +(ADCshiftRLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRL <x.Type> x y) flags) +(ADCshiftRAreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRA <x.Type> x y) flags) +(ADDSshiftLLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SLL <x.Type> x y)) +(ADDSshiftRLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRL <x.Type> x y)) +(ADDSshiftRAreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRA <x.Type> x y)) +(SUBshiftLLreg (MOVWconst [c]) x y) => (RSBconst [c] (SLL <x.Type> x y)) +(SUBshiftRLreg (MOVWconst [c]) x y) => (RSBconst [c] (SRL <x.Type> x y)) +(SUBshiftRAreg (MOVWconst [c]) x y) => (RSBconst [c] (SRA <x.Type> x y)) +(SBCshiftLLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SLL <x.Type> x y) flags) +(SBCshiftRLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRL <x.Type> x y) flags) +(SBCshiftRAreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRA <x.Type> x y) flags) +(SUBSshiftLLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SLL <x.Type> x y)) +(SUBSshiftRLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRL <x.Type> x y)) +(SUBSshiftRAreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRA <x.Type> x y)) +(RSBshiftLLreg (MOVWconst [c]) x y) => (SUBconst [c] (SLL <x.Type> x y)) +(RSBshiftRLreg (MOVWconst [c]) x y) => (SUBconst [c] (SRL <x.Type> x y)) +(RSBshiftRAreg (MOVWconst [c]) x y) => (SUBconst [c] (SRA <x.Type> x y)) +(RSCshiftLLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SLL <x.Type> x y) flags) +(RSCshiftRLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRL <x.Type> x y) flags) +(RSCshiftRAreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRA <x.Type> x y) flags) +(RSBSshiftLLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SLL <x.Type> x y)) +(RSBSshiftRLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRL <x.Type> x y)) +(RSBSshiftRAreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRA <x.Type> x y)) +(ANDshiftLLreg (MOVWconst [c]) x y) => (ANDconst [c] (SLL <x.Type> x y)) +(ANDshiftRLreg (MOVWconst [c]) x y) => (ANDconst [c] (SRL <x.Type> x y)) +(ANDshiftRAreg (MOVWconst [c]) x y) => (ANDconst [c] (SRA <x.Type> x y)) +(ORshiftLLreg (MOVWconst [c]) x y) => (ORconst [c] (SLL <x.Type> x y)) +(ORshiftRLreg (MOVWconst [c]) x y) => (ORconst [c] (SRL <x.Type> x y)) +(ORshiftRAreg (MOVWconst [c]) x y) => (ORconst [c] (SRA <x.Type> x y)) +(XORshiftLLreg (MOVWconst [c]) x y) => (XORconst [c] (SLL <x.Type> x y)) +(XORshiftRLreg (MOVWconst [c]) x y) => (XORconst [c] (SRL <x.Type> x y)) +(XORshiftRAreg (MOVWconst [c]) x y) => (XORconst [c] (SRA <x.Type> x y)) +(CMPshiftLLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SLL <x.Type> x y))) +(CMPshiftRLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRL <x.Type> x y))) +(CMPshiftRAreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRA <x.Type> x y))) +(TSTshiftLLreg (MOVWconst [c]) x y) => (TSTconst [c] (SLL <x.Type> x y)) +(TSTshiftRLreg (MOVWconst [c]) x y) => (TSTconst [c] (SRL <x.Type> x y)) +(TSTshiftRAreg (MOVWconst [c]) x y) => (TSTconst [c] (SRA <x.Type> x y)) +(TEQshiftLLreg (MOVWconst [c]) x y) => (TEQconst [c] (SLL <x.Type> x y)) +(TEQshiftRLreg (MOVWconst [c]) x y) => (TEQconst [c] (SRL <x.Type> x y)) +(TEQshiftRAreg (MOVWconst [c]) x y) => (TEQconst [c] (SRA <x.Type> x y)) +(CMNshiftLLreg (MOVWconst [c]) x y) => (CMNconst [c] (SLL <x.Type> x y)) +(CMNshiftRLreg (MOVWconst [c]) x y) => (CMNconst [c] (SRL <x.Type> x y)) +(CMNshiftRAreg (MOVWconst [c]) x y) => (CMNconst [c] (SRA <x.Type> x y)) // constant folding in *shift ops -(ADDshiftLL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(uint32(c)<<uint64(d)))]) -(ADDshiftRL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(uint32(c)>>uint64(d)))]) -(ADDshiftRA x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(c)>>uint64(d))]) -(ADCshiftLL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) -(ADCshiftRL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) -(ADCshiftRA x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(c)>>uint64(d))] flags) -(ADDSshiftLL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(uint32(c)<<uint64(d)))]) -(ADDSshiftRL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(uint32(c)>>uint64(d)))]) -(ADDSshiftRA x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(c)>>uint64(d))]) -(SUBshiftLL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(uint32(c)<<uint64(d)))]) -(SUBshiftRL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(uint32(c)>>uint64(d)))]) -(SUBshiftRA x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(c)>>uint64(d))]) -(SBCshiftLL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) -(SBCshiftRL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) -(SBCshiftRA x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(c)>>uint64(d))] flags) -(SUBSshiftLL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(uint32(c)<<uint64(d)))]) -(SUBSshiftRL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(uint32(c)>>uint64(d)))]) -(SUBSshiftRA x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(c)>>uint64(d))]) -(RSBshiftLL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(uint32(c)<<uint64(d)))]) -(RSBshiftRL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(uint32(c)>>uint64(d)))]) -(RSBshiftRA x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(c)>>uint64(d))]) -(RSCshiftLL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) -(RSCshiftRL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) -(RSCshiftRA x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(c)>>uint64(d))] flags) -(RSBSshiftLL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(uint32(c)<<uint64(d)))]) -(RSBSshiftRL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(uint32(c)>>uint64(d)))]) -(RSBSshiftRA x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(c)>>uint64(d))]) -(ANDshiftLL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(uint32(c)<<uint64(d)))]) -(ANDshiftRL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(uint32(c)>>uint64(d)))]) -(ANDshiftRA x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(c)>>uint64(d))]) -(ORshiftLL x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(uint32(c)<<uint64(d)))]) -(ORshiftRL x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(uint32(c)>>uint64(d)))]) -(ORshiftRA x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(c)>>uint64(d))]) -(XORshiftLL x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)<<uint64(d)))]) -(XORshiftRL x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)>>uint64(d)))]) -(XORshiftRA x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(c)>>uint64(d))]) -(XORshiftRR x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d)))]) -(BICshiftLL x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(uint32(c)<<uint64(d)))]) -(BICshiftRL x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(uint32(c)>>uint64(d)))]) -(BICshiftRA x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(c)>>uint64(d))]) -(MVNshiftLL (MOVWconst [c]) [d]) -> (MOVWconst [^int64(uint32(c)<<uint64(d))]) -(MVNshiftRL (MOVWconst [c]) [d]) -> (MOVWconst [^int64(uint32(c)>>uint64(d))]) -(MVNshiftRA (MOVWconst [c]) [d]) -> (MOVWconst [^int64(int32(c)>>uint64(d))]) -(CMPshiftLL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(uint32(c)<<uint64(d)))]) -(CMPshiftRL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(uint32(c)>>uint64(d)))]) -(CMPshiftRA x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(c)>>uint64(d))]) -(TSTshiftLL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(uint32(c)<<uint64(d)))]) -(TSTshiftRL x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(uint32(c)>>uint64(d)))]) -(TSTshiftRA x (MOVWconst [c]) [d]) -> (TSTconst x [int64(int32(c)>>uint64(d))]) -(TEQshiftLL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(uint32(c)<<uint64(d)))]) -(TEQshiftRL x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(uint32(c)>>uint64(d)))]) -(TEQshiftRA x (MOVWconst [c]) [d]) -> (TEQconst x [int64(int32(c)>>uint64(d))]) -(CMNshiftLL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(uint32(c)<<uint64(d)))]) -(CMNshiftRL x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(uint32(c)>>uint64(d)))]) -(CMNshiftRA x (MOVWconst [c]) [d]) -> (CMNconst x [int64(int32(c)>>uint64(d))]) +(ADDshiftLL x (MOVWconst [c]) [d]) => (ADDconst x [c<<uint64(d)]) +(ADDshiftRL x (MOVWconst [c]) [d]) => (ADDconst x [int32(uint32(c)>>uint64(d))]) +(ADDshiftRA x (MOVWconst [c]) [d]) => (ADDconst x [c>>uint64(d)]) +(ADCshiftLL x (MOVWconst [c]) [d] flags) => (ADCconst x [c<<uint64(d)] flags) +(ADCshiftRL x (MOVWconst [c]) [d] flags) => (ADCconst x [int32(uint32(c)>>uint64(d))] flags) +(ADCshiftRA x (MOVWconst [c]) [d] flags) => (ADCconst x [c>>uint64(d)] flags) +(ADDSshiftLL x (MOVWconst [c]) [d]) => (ADDSconst x [c<<uint64(d)]) +(ADDSshiftRL x (MOVWconst [c]) [d]) => (ADDSconst x [int32(uint32(c)>>uint64(d))]) +(ADDSshiftRA x (MOVWconst [c]) [d]) => (ADDSconst x [c>>uint64(d)]) +(SUBshiftLL x (MOVWconst [c]) [d]) => (SUBconst x [c<<uint64(d)]) +(SUBshiftRL x (MOVWconst [c]) [d]) => (SUBconst x [int32(uint32(c)>>uint64(d))]) +(SUBshiftRA x (MOVWconst [c]) [d]) => (SUBconst x [c>>uint64(d)]) +(SBCshiftLL x (MOVWconst [c]) [d] flags) => (SBCconst x [c<<uint64(d)] flags) +(SBCshiftRL x (MOVWconst [c]) [d] flags) => (SBCconst x [int32(uint32(c)>>uint64(d))] flags) +(SBCshiftRA x (MOVWconst [c]) [d] flags) => (SBCconst x [c>>uint64(d)] flags) +(SUBSshiftLL x (MOVWconst [c]) [d]) => (SUBSconst x [c<<uint64(d)]) +(SUBSshiftRL x (MOVWconst [c]) [d]) => (SUBSconst x [int32(uint32(c)>>uint64(d))]) +(SUBSshiftRA x (MOVWconst [c]) [d]) => (SUBSconst x [c>>uint64(d)]) +(RSBshiftLL x (MOVWconst [c]) [d]) => (RSBconst x [c<<uint64(d)]) +(RSBshiftRL x (MOVWconst [c]) [d]) => (RSBconst x [int32(uint32(c)>>uint64(d))]) +(RSBshiftRA x (MOVWconst [c]) [d]) => (RSBconst x [c>>uint64(d)]) +(RSCshiftLL x (MOVWconst [c]) [d] flags) => (RSCconst x [c<<uint64(d)] flags) +(RSCshiftRL x (MOVWconst [c]) [d] flags) => (RSCconst x [int32(uint32(c)>>uint64(d))] flags) +(RSCshiftRA x (MOVWconst [c]) [d] flags) => (RSCconst x [c>>uint64(d)] flags) +(RSBSshiftLL x (MOVWconst [c]) [d]) => (RSBSconst x [c<<uint64(d)]) +(RSBSshiftRL x (MOVWconst [c]) [d]) => (RSBSconst x [int32(uint32(c)>>uint64(d))]) +(RSBSshiftRA x (MOVWconst [c]) [d]) => (RSBSconst x [c>>uint64(d)]) +(ANDshiftLL x (MOVWconst [c]) [d]) => (ANDconst x [c<<uint64(d)]) +(ANDshiftRL x (MOVWconst [c]) [d]) => (ANDconst x [int32(uint32(c)>>uint64(d))]) +(ANDshiftRA x (MOVWconst [c]) [d]) => (ANDconst x [c>>uint64(d)]) +(ORshiftLL x (MOVWconst [c]) [d]) => (ORconst x [c<<uint64(d)]) +(ORshiftRL x (MOVWconst [c]) [d]) => (ORconst x [int32(uint32(c)>>uint64(d))]) +(ORshiftRA x (MOVWconst [c]) [d]) => (ORconst x [c>>uint64(d)]) +(XORshiftLL x (MOVWconst [c]) [d]) => (XORconst x [c<<uint64(d)]) +(XORshiftRL x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d))]) +(XORshiftRA x (MOVWconst [c]) [d]) => (XORconst x [c>>uint64(d)]) +(XORshiftRR x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))]) +(BICshiftLL x (MOVWconst [c]) [d]) => (BICconst x [c<<uint64(d)]) +(BICshiftRL x (MOVWconst [c]) [d]) => (BICconst x [int32(uint32(c)>>uint64(d))]) +(BICshiftRA x (MOVWconst [c]) [d]) => (BICconst x [c>>uint64(d)]) +(MVNshiftLL (MOVWconst [c]) [d]) => (MOVWconst [^(c<<uint64(d))]) +(MVNshiftRL (MOVWconst [c]) [d]) => (MOVWconst [^int32(uint32(c)>>uint64(d))]) +(MVNshiftRA (MOVWconst [c]) [d]) => (MOVWconst [int32(c)>>uint64(d)]) +(CMPshiftLL x (MOVWconst [c]) [d]) => (CMPconst x [c<<uint64(d)]) +(CMPshiftRL x (MOVWconst [c]) [d]) => (CMPconst x [int32(uint32(c)>>uint64(d))]) +(CMPshiftRA x (MOVWconst [c]) [d]) => (CMPconst x [c>>uint64(d)]) +(TSTshiftLL x (MOVWconst [c]) [d]) => (TSTconst x [c<<uint64(d)]) +(TSTshiftRL x (MOVWconst [c]) [d]) => (TSTconst x [int32(uint32(c)>>uint64(d))]) +(TSTshiftRA x (MOVWconst [c]) [d]) => (TSTconst x [c>>uint64(d)]) +(TEQshiftLL x (MOVWconst [c]) [d]) => (TEQconst x [c<<uint64(d)]) +(TEQshiftRL x (MOVWconst [c]) [d]) => (TEQconst x [int32(uint32(c)>>uint64(d))]) +(TEQshiftRA x (MOVWconst [c]) [d]) => (TEQconst x [c>>uint64(d)]) +(CMNshiftLL x (MOVWconst [c]) [d]) => (CMNconst x [c<<uint64(d)]) +(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))]) +(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)]) -(ADDshiftLLreg x y (MOVWconst [c])) -> (ADDshiftLL x y [c]) -(ADDshiftRLreg x y (MOVWconst [c])) -> (ADDshiftRL x y [c]) -(ADDshiftRAreg x y (MOVWconst [c])) -> (ADDshiftRA x y [c]) -(ADCshiftLLreg x y (MOVWconst [c]) flags) -> (ADCshiftLL x y [c] flags) -(ADCshiftRLreg x y (MOVWconst [c]) flags) -> (ADCshiftRL x y [c] flags) -(ADCshiftRAreg x y (MOVWconst [c]) flags) -> (ADCshiftRA x y [c] flags) -(ADDSshiftLLreg x y (MOVWconst [c])) -> (ADDSshiftLL x y [c]) -(ADDSshiftRLreg x y (MOVWconst [c])) -> (ADDSshiftRL x y [c]) -(ADDSshiftRAreg x y (MOVWconst [c])) -> (ADDSshiftRA x y [c]) -(SUBshiftLLreg x y (MOVWconst [c])) -> (SUBshiftLL x y [c]) -(SUBshiftRLreg x y (MOVWconst [c])) -> (SUBshiftRL x y [c]) -(SUBshiftRAreg x y (MOVWconst [c])) -> (SUBshiftRA x y [c]) -(SBCshiftLLreg x y (MOVWconst [c]) flags) -> (SBCshiftLL x y [c] flags) -(SBCshiftRLreg x y (MOVWconst [c]) flags) -> (SBCshiftRL x y [c] flags) -(SBCshiftRAreg x y (MOVWconst [c]) flags) -> (SBCshiftRA x y [c] flags) -(SUBSshiftLLreg x y (MOVWconst [c])) -> (SUBSshiftLL x y [c]) -(SUBSshiftRLreg x y (MOVWconst [c])) -> (SUBSshiftRL x y [c]) -(SUBSshiftRAreg x y (MOVWconst [c])) -> (SUBSshiftRA x y [c]) -(RSBshiftLLreg x y (MOVWconst [c])) -> (RSBshiftLL x y [c]) -(RSBshiftRLreg x y (MOVWconst [c])) -> (RSBshiftRL x y [c]) -(RSBshiftRAreg x y (MOVWconst [c])) -> (RSBshiftRA x y [c]) -(RSCshiftLLreg x y (MOVWconst [c]) flags) -> (RSCshiftLL x y [c] flags) -(RSCshiftRLreg x y (MOVWconst [c]) flags) -> (RSCshiftRL x y [c] flags) -(RSCshiftRAreg x y (MOVWconst [c]) flags) -> (RSCshiftRA x y [c] flags) -(RSBSshiftLLreg x y (MOVWconst [c])) -> (RSBSshiftLL x y [c]) -(RSBSshiftRLreg x y (MOVWconst [c])) -> (RSBSshiftRL x y [c]) -(RSBSshiftRAreg x y (MOVWconst [c])) -> (RSBSshiftRA x y [c]) -(ANDshiftLLreg x y (MOVWconst [c])) -> (ANDshiftLL x y [c]) -(ANDshiftRLreg x y (MOVWconst [c])) -> (ANDshiftRL x y [c]) -(ANDshiftRAreg x y (MOVWconst [c])) -> (ANDshiftRA x y [c]) -(ORshiftLLreg x y (MOVWconst [c])) -> (ORshiftLL x y [c]) -(ORshiftRLreg x y (MOVWconst [c])) -> (ORshiftRL x y [c]) -(ORshiftRAreg x y (MOVWconst [c])) -> (ORshiftRA x y [c]) -(XORshiftLLreg x y (MOVWconst [c])) -> (XORshiftLL x y [c]) -(XORshiftRLreg x y (MOVWconst [c])) -> (XORshiftRL x y [c]) -(XORshiftRAreg x y (MOVWconst [c])) -> (XORshiftRA x y [c]) -(BICshiftLLreg x y (MOVWconst [c])) -> (BICshiftLL x y [c]) -(BICshiftRLreg x y (MOVWconst [c])) -> (BICshiftRL x y [c]) -(BICshiftRAreg x y (MOVWconst [c])) -> (BICshiftRA x y [c]) -(MVNshiftLLreg x (MOVWconst [c])) -> (MVNshiftLL x [c]) -(MVNshiftRLreg x (MOVWconst [c])) -> (MVNshiftRL x [c]) -(MVNshiftRAreg x (MOVWconst [c])) -> (MVNshiftRA x [c]) -(CMPshiftLLreg x y (MOVWconst [c])) -> (CMPshiftLL x y [c]) -(CMPshiftRLreg x y (MOVWconst [c])) -> (CMPshiftRL x y [c]) -(CMPshiftRAreg x y (MOVWconst [c])) -> (CMPshiftRA x y [c]) -(TSTshiftLLreg x y (MOVWconst [c])) -> (TSTshiftLL x y [c]) -(TSTshiftRLreg x y (MOVWconst [c])) -> (TSTshiftRL x y [c]) -(TSTshiftRAreg x y (MOVWconst [c])) -> (TSTshiftRA x y [c]) -(TEQshiftLLreg x y (MOVWconst [c])) -> (TEQshiftLL x y [c]) -(TEQshiftRLreg x y (MOVWconst [c])) -> (TEQshiftRL x y [c]) -(TEQshiftRAreg x y (MOVWconst [c])) -> (TEQshiftRA x y [c]) -(CMNshiftLLreg x y (MOVWconst [c])) -> (CMNshiftLL x y [c]) -(CMNshiftRLreg x y (MOVWconst [c])) -> (CMNshiftRL x y [c]) -(CMNshiftRAreg x y (MOVWconst [c])) -> (CMNshiftRA x y [c]) +(ADDshiftLLreg x y (MOVWconst [c])) => (ADDshiftLL x y [c]) +(ADDshiftRLreg x y (MOVWconst [c])) => (ADDshiftRL x y [c]) +(ADDshiftRAreg x y (MOVWconst [c])) => (ADDshiftRA x y [c]) +(ADCshiftLLreg x y (MOVWconst [c]) flags) => (ADCshiftLL x y [c] flags) +(ADCshiftRLreg x y (MOVWconst [c]) flags) => (ADCshiftRL x y [c] flags) +(ADCshiftRAreg x y (MOVWconst [c]) flags) => (ADCshiftRA x y [c] flags) +(ADDSshiftLLreg x y (MOVWconst [c])) => (ADDSshiftLL x y [c]) +(ADDSshiftRLreg x y (MOVWconst [c])) => (ADDSshiftRL x y [c]) +(ADDSshiftRAreg x y (MOVWconst [c])) => (ADDSshiftRA x y [c]) +(SUBshiftLLreg x y (MOVWconst [c])) => (SUBshiftLL x y [c]) +(SUBshiftRLreg x y (MOVWconst [c])) => (SUBshiftRL x y [c]) +(SUBshiftRAreg x y (MOVWconst [c])) => (SUBshiftRA x y [c]) +(SBCshiftLLreg x y (MOVWconst [c]) flags) => (SBCshiftLL x y [c] flags) +(SBCshiftRLreg x y (MOVWconst [c]) flags) => (SBCshiftRL x y [c] flags) +(SBCshiftRAreg x y (MOVWconst [c]) flags) => (SBCshiftRA x y [c] flags) +(SUBSshiftLLreg x y (MOVWconst [c])) => (SUBSshiftLL x y [c]) +(SUBSshiftRLreg x y (MOVWconst [c])) => (SUBSshiftRL x y [c]) +(SUBSshiftRAreg x y (MOVWconst [c])) => (SUBSshiftRA x y [c]) +(RSBshiftLLreg x y (MOVWconst [c])) => (RSBshiftLL x y [c]) +(RSBshiftRLreg x y (MOVWconst [c])) => (RSBshiftRL x y [c]) +(RSBshiftRAreg x y (MOVWconst [c])) => (RSBshiftRA x y [c]) +(RSCshiftLLreg x y (MOVWconst [c]) flags) => (RSCshiftLL x y [c] flags) +(RSCshiftRLreg x y (MOVWconst [c]) flags) => (RSCshiftRL x y [c] flags) +(RSCshiftRAreg x y (MOVWconst [c]) flags) => (RSCshiftRA x y [c] flags) +(RSBSshiftLLreg x y (MOVWconst [c])) => (RSBSshiftLL x y [c]) +(RSBSshiftRLreg x y (MOVWconst [c])) => (RSBSshiftRL x y [c]) +(RSBSshiftRAreg x y (MOVWconst [c])) => (RSBSshiftRA x y [c]) +(ANDshiftLLreg x y (MOVWconst [c])) => (ANDshiftLL x y [c]) +(ANDshiftRLreg x y (MOVWconst [c])) => (ANDshiftRL x y [c]) +(ANDshiftRAreg x y (MOVWconst [c])) => (ANDshiftRA x y [c]) +(ORshiftLLreg x y (MOVWconst [c])) => (ORshiftLL x y [c]) +(ORshiftRLreg x y (MOVWconst [c])) => (ORshiftRL x y [c]) +(ORshiftRAreg x y (MOVWconst [c])) => (ORshiftRA x y [c]) +(XORshiftLLreg x y (MOVWconst [c])) => (XORshiftLL x y [c]) +(XORshiftRLreg x y (MOVWconst [c])) => (XORshiftRL x y [c]) +(XORshiftRAreg x y (MOVWconst [c])) => (XORshiftRA x y [c]) +(BICshiftLLreg x y (MOVWconst [c])) => (BICshiftLL x y [c]) +(BICshiftRLreg x y (MOVWconst [c])) => (BICshiftRL x y [c]) +(BICshiftRAreg x y (MOVWconst [c])) => (BICshiftRA x y [c]) +(MVNshiftLLreg x (MOVWconst [c])) => (MVNshiftLL x [c]) +(MVNshiftRLreg x (MOVWconst [c])) => (MVNshiftRL x [c]) +(MVNshiftRAreg x (MOVWconst [c])) => (MVNshiftRA x [c]) +(CMPshiftLLreg x y (MOVWconst [c])) => (CMPshiftLL x y [c]) +(CMPshiftRLreg x y (MOVWconst [c])) => (CMPshiftRL x y [c]) +(CMPshiftRAreg x y (MOVWconst [c])) => (CMPshiftRA x y [c]) +(TSTshiftLLreg x y (MOVWconst [c])) => (TSTshiftLL x y [c]) +(TSTshiftRLreg x y (MOVWconst [c])) => (TSTshiftRL x y [c]) +(TSTshiftRAreg x y (MOVWconst [c])) => (TSTshiftRA x y [c]) +(TEQshiftLLreg x y (MOVWconst [c])) => (TEQshiftLL x y [c]) +(TEQshiftRLreg x y (MOVWconst [c])) => (TEQshiftRL x y [c]) +(TEQshiftRAreg x y (MOVWconst [c])) => (TEQshiftRA x y [c]) +(CMNshiftLLreg x y (MOVWconst [c])) => (CMNshiftLL x y [c]) +(CMNshiftRLreg x y (MOVWconst [c])) => (CMNshiftRL x y [c]) +(CMNshiftRAreg x y (MOVWconst [c])) => (CMNshiftRA x y [c]) // Generate rotates -(ADDshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) -( ORshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) -(XORshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) -(ADDshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) -( ORshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) -(XORshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) +(ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x) +( ORshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x) +(XORshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x) +(ADDshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [ c] x) +( ORshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [ c] x) +(XORshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [ c] x) -(RotateLeft32 x (MOVWconst [c])) -> (SRRconst [-c&31] x) -(RotateLeft16 <t> x (MOVWconst [c])) -> (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15]))) -(RotateLeft8 <t> x (MOVWconst [c])) -> (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7]))) -(RotateLeft32 x y) -> (SRR x (RSBconst [0] <y.Type> y)) +(RotateLeft32 x (MOVWconst [c])) => (SRRconst [-c&31] x) +(RotateLeft16 <t> x (MOVWconst [c])) => (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15]))) +(RotateLeft8 <t> x (MOVWconst [c])) => (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7]))) +(RotateLeft32 x y) => (SRR x (RSBconst [0] <y.Type> y)) // ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+". // UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by // ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL. ((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x) -((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && objabi.GOARM>=6 -> (REV16 x) +((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && objabi.GOARM>=6 => (REV16 x) // use indexed loads and stores -(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVWloadidx ptr idx mem) -(MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil -> (MOVWstoreidx ptr idx val mem) -(MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftLL ptr idx [c] mem) -(MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftRL ptr idx [c] mem) -(MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftRA ptr idx [c] mem) -(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftLL ptr idx [c] val mem) -(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftRL ptr idx [c] val mem) -(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftRA ptr idx [c] val mem) -(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVBUloadidx ptr idx mem) -(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVBloadidx ptr idx mem) -(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil -> (MOVBstoreidx ptr idx val mem) -(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVHUloadidx ptr idx mem) -(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVHloadidx ptr idx mem) -(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil -> (MOVHstoreidx ptr idx val mem) +(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem) +(MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVWstoreidx ptr idx val mem) +(MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftLL ptr idx [c] mem) +(MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRL ptr idx [c] mem) +(MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRA ptr idx [c] mem) +(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRA ptr idx [c] val mem) +(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBUloadidx ptr idx mem) +(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBloadidx ptr idx mem) +(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVBstoreidx ptr idx val mem) +(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHUloadidx ptr idx mem) +(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHloadidx ptr idx mem) +(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVHstoreidx ptr idx val mem) // constant folding in indexed loads and stores -(MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem) -(MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem) -(MOVBloadidx ptr (MOVWconst [c]) mem) -> (MOVBload [c] ptr mem) -(MOVBloadidx (MOVWconst [c]) ptr mem) -> (MOVBload [c] ptr mem) -(MOVBUloadidx ptr (MOVWconst [c]) mem) -> (MOVBUload [c] ptr mem) -(MOVBUloadidx (MOVWconst [c]) ptr mem) -> (MOVBUload [c] ptr mem) -(MOVHUloadidx ptr (MOVWconst [c]) mem) -> (MOVHUload [c] ptr mem) -(MOVHUloadidx (MOVWconst [c]) ptr mem) -> (MOVHUload [c] ptr mem) -(MOVHloadidx ptr (MOVWconst [c]) mem) -> (MOVHload [c] ptr mem) -(MOVHloadidx (MOVWconst [c]) ptr mem) -> (MOVHload [c] ptr mem) +(MOVWloadidx ptr (MOVWconst [c]) mem) => (MOVWload [c] ptr mem) +(MOVWloadidx (MOVWconst [c]) ptr mem) => (MOVWload [c] ptr mem) +(MOVBloadidx ptr (MOVWconst [c]) mem) => (MOVBload [c] ptr mem) +(MOVBloadidx (MOVWconst [c]) ptr mem) => (MOVBload [c] ptr mem) +(MOVBUloadidx ptr (MOVWconst [c]) mem) => (MOVBUload [c] ptr mem) +(MOVBUloadidx (MOVWconst [c]) ptr mem) => (MOVBUload [c] ptr mem) +(MOVHUloadidx ptr (MOVWconst [c]) mem) => (MOVHUload [c] ptr mem) +(MOVHUloadidx (MOVWconst [c]) ptr mem) => (MOVHUload [c] ptr mem) +(MOVHloadidx ptr (MOVWconst [c]) mem) => (MOVHload [c] ptr mem) +(MOVHloadidx (MOVWconst [c]) ptr mem) => (MOVHload [c] ptr mem) -(MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem) -(MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem) -(MOVBstoreidx ptr (MOVWconst [c]) val mem) -> (MOVBstore [c] ptr val mem) -(MOVBstoreidx (MOVWconst [c]) ptr val mem) -> (MOVBstore [c] ptr val mem) -(MOVHstoreidx ptr (MOVWconst [c]) val mem) -> (MOVHstore [c] ptr val mem) -(MOVHstoreidx (MOVWconst [c]) ptr val mem) -> (MOVHstore [c] ptr val mem) +(MOVWstoreidx ptr (MOVWconst [c]) val mem) => (MOVWstore [c] ptr val mem) +(MOVWstoreidx (MOVWconst [c]) ptr val mem) => (MOVWstore [c] ptr val mem) +(MOVBstoreidx ptr (MOVWconst [c]) val mem) => (MOVBstore [c] ptr val mem) +(MOVBstoreidx (MOVWconst [c]) ptr val mem) => (MOVBstore [c] ptr val mem) +(MOVHstoreidx ptr (MOVWconst [c]) val mem) => (MOVHstore [c] ptr val mem) +(MOVHstoreidx (MOVWconst [c]) ptr val mem) => (MOVHstore [c] ptr val mem) -(MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem) -(MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem) -(MOVWloadidx ptr (SRLconst idx [c]) mem) -> (MOVWloadshiftRL ptr idx [c] mem) -(MOVWloadidx (SRLconst idx [c]) ptr mem) -> (MOVWloadshiftRL ptr idx [c] mem) -(MOVWloadidx ptr (SRAconst idx [c]) mem) -> (MOVWloadshiftRA ptr idx [c] mem) -(MOVWloadidx (SRAconst idx [c]) ptr mem) -> (MOVWloadshiftRA ptr idx [c] mem) +(MOVWloadidx ptr (SLLconst idx [c]) mem) => (MOVWloadshiftLL ptr idx [c] mem) +(MOVWloadidx (SLLconst idx [c]) ptr mem) => (MOVWloadshiftLL ptr idx [c] mem) +(MOVWloadidx ptr (SRLconst idx [c]) mem) => (MOVWloadshiftRL ptr idx [c] mem) +(MOVWloadidx (SRLconst idx [c]) ptr mem) => (MOVWloadshiftRL ptr idx [c] mem) +(MOVWloadidx ptr (SRAconst idx [c]) mem) => (MOVWloadshiftRA ptr idx [c] mem) +(MOVWloadidx (SRAconst idx [c]) ptr mem) => (MOVWloadshiftRA ptr idx [c] mem) -(MOVWstoreidx ptr (SLLconst idx [c]) val mem) -> (MOVWstoreshiftLL ptr idx [c] val mem) -(MOVWstoreidx (SLLconst idx [c]) ptr val mem) -> (MOVWstoreshiftLL ptr idx [c] val mem) -(MOVWstoreidx ptr (SRLconst idx [c]) val mem) -> (MOVWstoreshiftRL ptr idx [c] val mem) -(MOVWstoreidx (SRLconst idx [c]) ptr val mem) -> (MOVWstoreshiftRL ptr idx [c] val mem) -(MOVWstoreidx ptr (SRAconst idx [c]) val mem) -> (MOVWstoreshiftRA ptr idx [c] val mem) -(MOVWstoreidx (SRAconst idx [c]) ptr val mem) -> (MOVWstoreshiftRA ptr idx [c] val mem) +(MOVWstoreidx ptr (SLLconst idx [c]) val mem) => (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstoreidx (SLLconst idx [c]) ptr val mem) => (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstoreidx ptr (SRLconst idx [c]) val mem) => (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstoreidx (SRLconst idx [c]) ptr val mem) => (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstoreidx ptr (SRAconst idx [c]) val mem) => (MOVWstoreshiftRA ptr idx [c] val mem) +(MOVWstoreidx (SRAconst idx [c]) ptr val mem) => (MOVWstoreshiftRA ptr idx [c] val mem) -(MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) -> (MOVWload [int64(uint32(c)<<uint64(d))] ptr mem) -(MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) -> (MOVWload [int64(uint32(c)>>uint64(d))] ptr mem) -(MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) -> (MOVWload [int64(int32(c)>>uint64(d))] ptr mem) +(MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)<<uint64(d))] ptr mem) +(MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)>>uint64(d))] ptr mem) +(MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) => (MOVWload [c>>uint64(d)] ptr mem) -(MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) -> (MOVWstore [int64(uint32(c)<<uint64(d))] ptr val mem) -(MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) -> (MOVWstore [int64(uint32(c)>>uint64(d))] ptr val mem) -(MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) -> (MOVWstore [int64(int32(c)>>uint64(d))] ptr val mem) +(MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)<<uint64(d))] ptr val mem) +(MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)>>uint64(d))] ptr val mem) +(MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [c>>uint64(d)] ptr val mem) // generic simplifications -(ADD x (RSBconst [0] y)) -> (SUB x y) -(ADD <t> (RSBconst [c] x) (RSBconst [d] y)) -> (RSBconst [c+d] (ADD <t> x y)) -(SUB x x) -> (MOVWconst [0]) -(RSB x x) -> (MOVWconst [0]) -(AND x x) -> x -(OR x x) -> x -(XOR x x) -> (MOVWconst [0]) -(BIC x x) -> (MOVWconst [0]) +(ADD x (RSBconst [0] y)) => (SUB x y) +(ADD <t> (RSBconst [c] x) (RSBconst [d] y)) => (RSBconst [c+d] (ADD <t> x y)) +(SUB x x) => (MOVWconst [0]) +(RSB x x) => (MOVWconst [0]) +(AND x x) => x +(OR x x) => x +(XOR x x) => (MOVWconst [0]) +(BIC x x) => (MOVWconst [0]) -(ADD (MUL x y) a) -> (MULA x y a) -(SUB a (MUL x y)) && objabi.GOARM == 7 -> (MULS x y a) -(RSB (MUL x y) a) && objabi.GOARM == 7 -> (MULS x y a) +(ADD (MUL x y) a) => (MULA x y a) +(SUB a (MUL x y)) && objabi.GOARM == 7 => (MULS x y a) +(RSB (MUL x y) a) && objabi.GOARM == 7 => (MULS x y a) -(NEGF (MULF x y)) && objabi.GOARM >= 6 -> (NMULF x y) -(NEGD (MULD x y)) && objabi.GOARM >= 6 -> (NMULD x y) -(MULF (NEGF x) y) && objabi.GOARM >= 6 -> (NMULF x y) -(MULD (NEGD x) y) && objabi.GOARM >= 6 -> (NMULD x y) -(NMULF (NEGF x) y) -> (MULF x y) -(NMULD (NEGD x) y) -> (MULD x y) +(NEGF (MULF x y)) && objabi.GOARM >= 6 => (NMULF x y) +(NEGD (MULD x y)) && objabi.GOARM >= 6 => (NMULD x y) +(MULF (NEGF x) y) && objabi.GOARM >= 6 => (NMULF x y) +(MULD (NEGD x) y) && objabi.GOARM >= 6 => (NMULD x y) +(NMULF (NEGF x) y) => (MULF x y) +(NMULD (NEGD x) y) => (MULD x y) // the result will overwrite the addend, since they are in the same register -(ADDF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y) -(ADDF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y) -(ADDD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y) -(ADDD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y) -(SUBF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y) -(SUBF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y) -(SUBD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y) -(SUBD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y) +(ADDF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULAF a x y) +(ADDF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULSF a x y) +(ADDD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULAD a x y) +(ADDD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULSD a x y) +(SUBF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULSF a x y) +(SUBF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULAF a x y) +(SUBD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULSD a x y) +(SUBD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 => (MULAD a x y) -(AND x (MVN y)) -> (BIC x y) +(AND x (MVN y)) => (BIC x y) // simplification with *shift ops -(SUBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(SUBshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(SUBshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(RSBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(RSBshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(RSBshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d -> y -(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d -> y -(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d -> y -(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d -> y -(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d -> y -(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d -> y -(XORshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(XORshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(XORshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(BICshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(BICshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(BICshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) -(AND x (MVNshiftLL y [c])) -> (BICshiftLL x y [c]) -(AND x (MVNshiftRL y [c])) -> (BICshiftRL x y [c]) -(AND x (MVNshiftRA y [c])) -> (BICshiftRA x y [c]) +(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(SUBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(SUBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0]) +(RSBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(RSBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(RSBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0]) +(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y +(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y +(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y +(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y +(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y +(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y +(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0]) +(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0]) +(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0]) +(AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c]) +(AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c]) +(AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c]) // floating point optimizations -(CMPF x (MOVFconst [0])) -> (CMPF0 x) -(CMPD x (MOVDconst [0])) -> (CMPD0 x) +(CMPF x (MOVFconst [0])) => (CMPF0 x) +(CMPD x (MOVDconst [0])) => (CMPD0 x) // bit extraction -(SRAconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFX [(d-c)|(32-d)<<8] x) -(SRLconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 -> (BFXU [(d-c)|(32-d)<<8] x) +(SRAconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x) +(SRLconst (SLLconst x [c]) [d]) && objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x) // comparison simplification -(CMP x (RSBconst [0] y)) -> (CMN x y) -(CMN x (RSBconst [0] y)) -> (CMP x y) -(EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (EQ (CMP x y) yes no) -(EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (EQ (CMP a (MUL <x.Type> x y)) yes no) -(EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (EQ (CMPconst [c] x) yes no) -(EQ (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (EQ (CMPshiftLL x y [c]) yes no) -(EQ (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (EQ (CMPshiftRL x y [c]) yes no) -(EQ (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (EQ (CMPshiftRA x y [c]) yes no) -(EQ (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (EQ (CMPshiftLLreg x y z) yes no) -(EQ (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (EQ (CMPshiftRLreg x y z) yes no) -(EQ (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (EQ (CMPshiftRAreg x y z) yes no) -(NE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (NE (CMP x y) yes no) -(NE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (NE (CMP a (MUL <x.Type> x y)) yes no) -(NE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (NE (CMPconst [c] x) yes no) -(NE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (NE (CMPshiftLL x y [c]) yes no) -(NE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (NE (CMPshiftRL x y [c]) yes no) -(NE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (NE (CMPshiftRA x y [c]) yes no) -(NE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (NE (CMPshiftLLreg x y z) yes no) -(NE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (NE (CMPshiftRLreg x y z) yes no) -(NE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (NE (CMPshiftRAreg x y z) yes no) -(EQ (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (EQ (CMN x y) yes no) -(EQ (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (EQ (CMN a (MUL <x.Type> x y)) yes no) -(EQ (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (EQ (CMNconst [c] x) yes no) -(EQ (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (EQ (CMNshiftLL x y [c]) yes no) -(EQ (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (EQ (CMNshiftRL x y [c]) yes no) -(EQ (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (EQ (CMNshiftRA x y [c]) yes no) -(EQ (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (EQ (CMNshiftLLreg x y z) yes no) -(EQ (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (EQ (CMNshiftRLreg x y z) yes no) -(EQ (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (EQ (CMNshiftRAreg x y z) yes no) -(NE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (NE (CMN x y) yes no) -(NE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (NE (CMN a (MUL <x.Type> x y)) yes no) -(NE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (NE (CMNconst [c] x) yes no) -(NE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (NE (CMNshiftLL x y [c]) yes no) -(NE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (NE (CMNshiftRL x y [c]) yes no) -(NE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (NE (CMNshiftRA x y [c]) yes no) -(NE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (NE (CMNshiftLLreg x y z) yes no) -(NE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (NE (CMNshiftRLreg x y z) yes no) -(NE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (NE (CMNshiftRAreg x y z) yes no) -(EQ (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (EQ (TST x y) yes no) -(EQ (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (EQ (TSTconst [c] x) yes no) -(EQ (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (EQ (TSTshiftLL x y [c]) yes no) -(EQ (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (EQ (TSTshiftRL x y [c]) yes no) -(EQ (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (EQ (TSTshiftRA x y [c]) yes no) -(EQ (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (EQ (TSTshiftLLreg x y z) yes no) -(EQ (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (EQ (TSTshiftRLreg x y z) yes no) -(EQ (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (EQ (TSTshiftRAreg x y z) yes no) -(NE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (NE (TST x y) yes no) -(NE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (NE (TSTconst [c] x) yes no) -(NE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (NE (TSTshiftLL x y [c]) yes no) -(NE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (NE (TSTshiftRL x y [c]) yes no) -(NE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (NE (TSTshiftRA x y [c]) yes no) -(NE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (NE (TSTshiftLLreg x y z) yes no) -(NE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (NE (TSTshiftRLreg x y z) yes no) -(NE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (NE (TSTshiftRAreg x y z) yes no) -(EQ (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (EQ (TEQ x y) yes no) -(EQ (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (EQ (TEQconst [c] x) yes no) -(EQ (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (EQ (TEQshiftLL x y [c]) yes no) -(EQ (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (EQ (TEQshiftRL x y [c]) yes no) -(EQ (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (EQ (TEQshiftRA x y [c]) yes no) -(EQ (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (EQ (TEQshiftLLreg x y z) yes no) -(EQ (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (EQ (TEQshiftRLreg x y z) yes no) -(EQ (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (EQ (TEQshiftRAreg x y z) yes no) -(NE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (NE (TEQ x y) yes no) -(NE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (NE (TEQconst [c] x) yes no) -(NE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (NE (TEQshiftLL x y [c]) yes no) -(NE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (NE (TEQshiftRL x y [c]) yes no) -(NE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (NE (TEQshiftRA x y [c]) yes no) -(NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftLLreg x y z) yes no) -(NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftRLreg x y z) yes no) -(NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (NE (TEQshiftRAreg x y z) yes no) -(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LTnoov (CMP x y) yes no) -(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LTnoov (CMP a (MUL <x.Type> x y)) yes no) -(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (CMPconst [c] x) yes no) -(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftLL x y [c]) yes no) -(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRL x y [c]) yes no) -(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRA x y [c]) yes no) -(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftLLreg x y z) yes no) -(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRLreg x y z) yes no) -(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMPshiftRAreg x y z) yes no) -(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (LEnoov (CMP x y) yes no) -(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (LEnoov (CMP a (MUL <x.Type> x y)) yes no) -(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (CMPconst [c] x) yes no) -(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftLL x y [c]) yes no) -(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRL x y [c]) yes no) -(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRA x y [c]) yes no) -(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftLLreg x y z) yes no) -(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRLreg x y z) yes no) -(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMPshiftRAreg x y z) yes no) -(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LTnoov (CMN x y) yes no) -(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LTnoov (CMN a (MUL <x.Type> x y)) yes no) -(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (CMNconst [c] x) yes no) -(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftLL x y [c]) yes no) -(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRL x y [c]) yes no) -(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRA x y [c]) yes no) -(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftLLreg x y z) yes no) -(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRLreg x y z) yes no) -(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (CMNshiftRAreg x y z) yes no) -(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (LEnoov (CMN x y) yes no) -(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (LEnoov (CMN a (MUL <x.Type> x y)) yes no) -(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (CMNconst [c] x) yes no) -(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLL x y [c]) yes no) -(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRL x y [c]) yes no) -(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRA x y [c]) yes no) -(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLLreg x y z) yes no) -(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRLreg x y z) yes no) -(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRAreg x y z) yes no) -(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LT (TST x y) yes no) -(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LT (TSTconst [c] x) yes no) -(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftLL x y [c]) yes no) -(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRL x y [c]) yes no) -(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRA x y [c]) yes no) -(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftLLreg x y z) yes no) -(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRLreg x y z) yes no) -(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRAreg x y z) yes no) -(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LE (TST x y) yes no) -(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LE (TSTconst [c] x) yes no) -(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftLL x y [c]) yes no) -(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRL x y [c]) yes no) -(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRA x y [c]) yes no) -(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftLLreg x y z) yes no) -(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRLreg x y z) yes no) -(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRAreg x y z) yes no) -(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LT (TEQ x y) yes no) -(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LT (TEQconst [c] x) yes no) -(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftLL x y [c]) yes no) -(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRL x y [c]) yes no) -(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRA x y [c]) yes no) -(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftLLreg x y z) yes no) -(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRLreg x y z) yes no) -(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRAreg x y z) yes no) -(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LE (TEQ x y) yes no) -(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LE (TEQconst [c] x) yes no) -(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftLL x y [c]) yes no) -(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRL x y [c]) yes no) -(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRA x y [c]) yes no) -(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftLLreg x y z) yes no) -(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRLreg x y z) yes no) -(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRAreg x y z) yes no) -(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GTnoov (CMP x y) yes no) -(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GTnoov (CMP a (MUL <x.Type> x y)) yes no) -(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMPconst [c] x) yes no) -(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftLL x y [c]) yes no) -(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRL x y [c]) yes no) -(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRA x y [c]) yes no) -(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftLLreg x y z) yes no) -(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRLreg x y z) yes no) -(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMPshiftRAreg x y z) yes no) -(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GEnoov (CMP x y) yes no) -(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GEnoov (CMP a (MUL <x.Type> x y)) yes no) -(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (CMPconst [c] x) yes no) -(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftLL x y [c]) yes no) -(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRL x y [c]) yes no) -(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRA x y [c]) yes no) -(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftLLreg x y z) yes no) -(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRLreg x y z) yes no) -(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMPshiftRAreg x y z) yes no) -(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GTnoov (CMN x y) yes no) -(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMNconst [c] x) yes no) -(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftLL x y [c]) yes no) -(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRL x y [c]) yes no) -(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRA x y [c]) yes no) -(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftLLreg x y z) yes no) -(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRLreg x y z) yes no) -(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (CMNshiftRAreg x y z) yes no) -(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 -> (GEnoov (CMN x y) yes no) -(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GEnoov (CMN a (MUL <x.Type> x y)) yes no) -(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (CMNconst [c] x) yes no) -(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLL x y [c]) yes no) -(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRL x y [c]) yes no) -(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRA x y [c]) yes no) -(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLLreg x y z) yes no) -(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRLreg x y z) yes no) -(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRAreg x y z) yes no) -(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GT (TST x y) yes no) -(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GTnoov (CMN a (MUL <x.Type> x y)) yes no) -(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GT (TSTconst [c] x) yes no) -(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftLL x y [c]) yes no) -(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRL x y [c]) yes no) -(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRA x y [c]) yes no) -(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftLLreg x y z) yes no) -(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRLreg x y z) yes no) -(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRAreg x y z) yes no) -(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GE (TST x y) yes no) -(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GE (TSTconst [c] x) yes no) -(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftLL x y [c]) yes no) -(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRL x y [c]) yes no) -(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRA x y [c]) yes no) -(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftLLreg x y z) yes no) -(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRLreg x y z) yes no) -(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRAreg x y z) yes no) -(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GT (TEQ x y) yes no) -(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GT (TEQconst [c] x) yes no) -(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftLL x y [c]) yes no) -(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRL x y [c]) yes no) -(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRA x y [c]) yes no) -(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftLLreg x y z) yes no) -(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRLreg x y z) yes no) -(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRAreg x y z) yes no) -(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GE (TEQ x y) yes no) -(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GE (TEQconst [c] x) yes no) -(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftLL x y [c]) yes no) -(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRL x y [c]) yes no) -(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRA x y [c]) yes no) -(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftLLreg x y z) yes no) -(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRLreg x y z) yes no) -(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRAreg x y z) yes no) +((LT|LE|EQ|NE|GE|GT) (CMP x (RSBconst [0] y))) => ((LT|LE|EQ|NE|GE|GT) (CMN x y)) // sense of carry bit not preserved +((LT|LE|EQ|NE|GE|GT) (CMN x (RSBconst [0] y))) => ((LT|LE|EQ|NE|GE|GT) (CMP x y)) // sense of carry bit not preserved +(EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (EQ (CMP x y) yes no) +(EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no) +(EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (EQ (CMPconst [c] x) yes no) +(EQ (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftLL x y [c]) yes no) +(EQ (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRL x y [c]) yes no) +(EQ (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRA x y [c]) yes no) +(EQ (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftLLreg x y z) yes no) +(EQ (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRLreg x y z) yes no) +(EQ (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRAreg x y z) yes no) +(NE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (NE (CMP x y) yes no) +(NE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no) +(NE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (NE (CMPconst [c] x) yes no) +(NE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftLL x y [c]) yes no) +(NE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRL x y [c]) yes no) +(NE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRA x y [c]) yes no) +(NE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftLLreg x y z) yes no) +(NE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRLreg x y z) yes no) +(NE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRAreg x y z) yes no) +(EQ (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (EQ (CMN x y) yes no) +(EQ (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no) +(EQ (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (EQ (CMNconst [c] x) yes no) +(EQ (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftLL x y [c]) yes no) +(EQ (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRL x y [c]) yes no) +(EQ (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRA x y [c]) yes no) +(EQ (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftLLreg x y z) yes no) +(EQ (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRLreg x y z) yes no) +(EQ (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRAreg x y z) yes no) +(NE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (NE (CMN x y) yes no) +(NE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no) +(NE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (NE (CMNconst [c] x) yes no) +(NE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftLL x y [c]) yes no) +(NE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRL x y [c]) yes no) +(NE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRA x y [c]) yes no) +(NE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftLLreg x y z) yes no) +(NE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRLreg x y z) yes no) +(NE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRAreg x y z) yes no) +(EQ (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (EQ (TST x y) yes no) +(EQ (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (EQ (TSTconst [c] x) yes no) +(EQ (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftLL x y [c]) yes no) +(EQ (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRL x y [c]) yes no) +(EQ (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRA x y [c]) yes no) +(EQ (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftLLreg x y z) yes no) +(EQ (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRLreg x y z) yes no) +(EQ (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRAreg x y z) yes no) +(NE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (NE (TST x y) yes no) +(NE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (NE (TSTconst [c] x) yes no) +(NE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftLL x y [c]) yes no) +(NE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRL x y [c]) yes no) +(NE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRA x y [c]) yes no) +(NE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftLLreg x y z) yes no) +(NE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRLreg x y z) yes no) +(NE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRAreg x y z) yes no) +(EQ (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (EQ (TEQ x y) yes no) +(EQ (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (EQ (TEQconst [c] x) yes no) +(EQ (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftLL x y [c]) yes no) +(EQ (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRL x y [c]) yes no) +(EQ (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRA x y [c]) yes no) +(EQ (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftLLreg x y z) yes no) +(EQ (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRLreg x y z) yes no) +(EQ (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRAreg x y z) yes no) +(NE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (NE (TEQ x y) yes no) +(NE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (NE (TEQconst [c] x) yes no) +(NE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftLL x y [c]) yes no) +(NE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRL x y [c]) yes no) +(NE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRA x y [c]) yes no) +(NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftLLreg x y z) yes no) +(NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRLreg x y z) yes no) +(NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRAreg x y z) yes no) +(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LTnoov (CMP x y) yes no) +(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no) +(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMPconst [c] x) yes no) +(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftLL x y [c]) yes no) +(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRL x y [c]) yes no) +(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRA x y [c]) yes no) +(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftLLreg x y z) yes no) +(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRLreg x y z) yes no) +(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRAreg x y z) yes no) +(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LEnoov (CMP x y) yes no) +(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no) +(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LEnoov (CMPconst [c] x) yes no) +(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftLL x y [c]) yes no) +(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRL x y [c]) yes no) +(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRA x y [c]) yes no) +(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftLLreg x y z) yes no) +(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRLreg x y z) yes no) +(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRAreg x y z) yes no) +(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LTnoov (CMN x y) yes no) +(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no) +(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMNconst [c] x) yes no) +(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftLL x y [c]) yes no) +(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRL x y [c]) yes no) +(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRA x y [c]) yes no) +(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftLLreg x y z) yes no) +(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRLreg x y z) yes no) +(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRAreg x y z) yes no) +(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LEnoov (CMN x y) yes no) +(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no) +(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (LEnoov (CMNconst [c] x) yes no) +(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftLL x y [c]) yes no) +(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRL x y [c]) yes no) +(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRA x y [c]) yes no) +(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftLLreg x y z) yes no) +(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRLreg x y z) yes no) +(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRAreg x y z) yes no) +(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LTnoov (TST x y) yes no) +(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TSTconst [c] x) yes no) +(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftLL x y [c]) yes no) +(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRL x y [c]) yes no) +(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRA x y [c]) yes no) +(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftLLreg x y z) yes no) +(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRLreg x y z) yes no) +(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRAreg x y z) yes no) +(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LEnoov (TST x y) yes no) +(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LEnoov (TSTconst [c] x) yes no) +(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftLL x y [c]) yes no) +(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRL x y [c]) yes no) +(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRA x y [c]) yes no) +(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftLLreg x y z) yes no) +(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRLreg x y z) yes no) +(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRAreg x y z) yes no) +(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LTnoov (TEQ x y) yes no) +(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TEQconst [c] x) yes no) +(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftLL x y [c]) yes no) +(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRL x y [c]) yes no) +(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRA x y [c]) yes no) +(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftLLreg x y z) yes no) +(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRLreg x y z) yes no) +(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRAreg x y z) yes no) +(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LEnoov (TEQ x y) yes no) +(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (LEnoov (TEQconst [c] x) yes no) +(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftLL x y [c]) yes no) +(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRL x y [c]) yes no) +(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRA x y [c]) yes no) +(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftLLreg x y z) yes no) +(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRLreg x y z) yes no) +(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRAreg x y z) yes no) +(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GTnoov (CMP x y) yes no) +(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no) +(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMPconst [c] x) yes no) +(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftLL x y [c]) yes no) +(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRL x y [c]) yes no) +(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRA x y [c]) yes no) +(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftLLreg x y z) yes no) +(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRLreg x y z) yes no) +(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRAreg x y z) yes no) +(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GEnoov (CMP x y) yes no) +(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no) +(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMPconst [c] x) yes no) +(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftLL x y [c]) yes no) +(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRL x y [c]) yes no) +(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRA x y [c]) yes no) +(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftLLreg x y z) yes no) +(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRLreg x y z) yes no) +(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRAreg x y z) yes no) +(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GTnoov (CMN x y) yes no) +(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMNconst [c] x) yes no) +(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftLL x y [c]) yes no) +(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRL x y [c]) yes no) +(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRA x y [c]) yes no) +(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftLLreg x y z) yes no) +(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRLreg x y z) yes no) +(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRAreg x y z) yes no) +(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GEnoov (CMN x y) yes no) +(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no) +(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMNconst [c] x) yes no) +(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftLL x y [c]) yes no) +(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRL x y [c]) yes no) +(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRA x y [c]) yes no) +(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftLLreg x y z) yes no) +(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRLreg x y z) yes no) +(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRAreg x y z) yes no) +(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no) +(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GTnoov (TST x y) yes no) +(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TSTconst [c] x) yes no) +(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftLL x y [c]) yes no) +(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRL x y [c]) yes no) +(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRA x y [c]) yes no) +(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftLLreg x y z) yes no) +(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRLreg x y z) yes no) +(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRAreg x y z) yes no) +(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GEnoov (TST x y) yes no) +(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TSTconst [c] x) yes no) +(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftLL x y [c]) yes no) +(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRL x y [c]) yes no) +(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRA x y [c]) yes no) +(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftLLreg x y z) yes no) +(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRLreg x y z) yes no) +(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRAreg x y z) yes no) +(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GTnoov (TEQ x y) yes no) +(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TEQconst [c] x) yes no) +(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftLL x y [c]) yes no) +(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRL x y [c]) yes no) +(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRA x y [c]) yes no) +(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftLLreg x y z) yes no) +(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRLreg x y z) yes no) +(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRAreg x y z) yes no) +(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GEnoov (TEQ x y) yes no) +(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TEQconst [c] x) yes no) +(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftLL x y [c]) yes no) +(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRL x y [c]) yes no) +(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRA x y [c]) yes no) +(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftLLreg x y z) yes no) +(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRLreg x y z) yes no) +(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRAreg x y z) yes no) -(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read8(sym, off))]) -(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))]) -(MOVWload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(int32(read32(sym, off, config.ctxt.Arch.ByteOrder)))]) +(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read8(sym, int64(off)))]) +(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))]) +(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))]) diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index 311067e87a..3f4d0c1c52 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -543,15 +543,24 @@ (AtomicStore64 ...) => (STLR ...) (AtomicStorePtrNoWB ...) => (STLR ...) -(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...) -(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...) +(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...) +(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...) (AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...) +(AtomicAdd(32|64)Variant ...) => (LoweredAtomicAdd(32|64)Variant ...) +(AtomicExchange(32|64)Variant ...) => (LoweredAtomicExchange(32|64)Variant ...) +(AtomicCompareAndSwap(32|64)Variant ...) => (LoweredAtomicCas(32|64)Variant ...) + // Currently the updated value is not used, but we need a register to temporarily hold it. -(AtomicAnd8 ptr val mem) => (Select1 (LoweredAtomicAnd8 ptr val mem)) -(AtomicOr8 ptr val mem) => (Select1 (LoweredAtomicOr8 ptr val mem)) +(AtomicAnd8 ptr val mem) => (Select1 (LoweredAtomicAnd8 ptr val mem)) +(AtomicAnd32 ptr val mem) => (Select1 (LoweredAtomicAnd32 ptr val mem)) +(AtomicOr8 ptr val mem) => (Select1 (LoweredAtomicOr8 ptr val mem)) +(AtomicOr32 ptr val mem) => (Select1 (LoweredAtomicOr32 ptr val mem)) -(AtomicAdd(32|64)Variant ...) => (LoweredAtomicAdd(32|64)Variant ...) +(AtomicAnd8Variant ptr val mem) => (Select1 (LoweredAtomicAnd8Variant ptr val mem)) +(AtomicAnd32Variant ptr val mem) => (Select1 (LoweredAtomicAnd32Variant ptr val mem)) +(AtomicOr8Variant ptr val mem) => (Select1 (LoweredAtomicOr8Variant ptr val mem)) +(AtomicOr32Variant ptr val mem) => (Select1 (LoweredAtomicOr32Variant ptr val mem)) // Write barrier. (WB ...) => (LoweredWB ...) @@ -859,88 +868,88 @@ (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVWUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (STP [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val1 val2 mem) + (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem) (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => - (MOVQstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) // store zero (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem) @@ -1116,280 +1125,282 @@ // if a register move has only 1 use, just use the same register without emitting instruction // MOVDnop doesn't emit instruction, only for ensuring the type. -(MOVDreg x) && x.Uses == 1 -> (MOVDnop x) +(MOVDreg x) && x.Uses == 1 => (MOVDnop x) // fold constant into arithmatic ops -(ADD x (MOVDconst [c])) -> (ADDconst [c] x) -(SUB x (MOVDconst [c])) -> (SUBconst [c] x) -(AND x (MOVDconst [c])) -> (ANDconst [c] x) -(OR x (MOVDconst [c])) -> (ORconst [c] x) -(XOR x (MOVDconst [c])) -> (XORconst [c] x) -(TST x (MOVDconst [c])) -> (TSTconst [c] x) -(TSTW x (MOVDconst [c])) -> (TSTWconst [c] x) -(CMN x (MOVDconst [c])) -> (CMNconst [c] x) -(CMNW x (MOVDconst [c])) -> (CMNWconst [c] x) -(BIC x (MOVDconst [c])) -> (ANDconst [^c] x) -(EON x (MOVDconst [c])) -> (XORconst [^c] x) -(ORN x (MOVDconst [c])) -> (ORconst [^c] x) +(ADD x (MOVDconst [c])) => (ADDconst [c] x) +(SUB x (MOVDconst [c])) => (SUBconst [c] x) +(AND x (MOVDconst [c])) => (ANDconst [c] x) +(OR x (MOVDconst [c])) => (ORconst [c] x) +(XOR x (MOVDconst [c])) => (XORconst [c] x) +(TST x (MOVDconst [c])) => (TSTconst [c] x) +(TSTW x (MOVDconst [c])) => (TSTWconst [int32(c)] x) +(CMN x (MOVDconst [c])) => (CMNconst [c] x) +(CMNW x (MOVDconst [c])) => (CMNWconst [int32(c)] x) +(BIC x (MOVDconst [c])) => (ANDconst [^c] x) +(EON x (MOVDconst [c])) => (XORconst [^c] x) +(ORN x (MOVDconst [c])) => (ORconst [^c] x) -(SLL x (MOVDconst [c])) -> (SLLconst x [c&63]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=64) -(SRL x (MOVDconst [c])) -> (SRLconst x [c&63]) -(SRA x (MOVDconst [c])) -> (SRAconst x [c&63]) +(SLL x (MOVDconst [c])) => (SLLconst x [c&63]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=64) +(SRL x (MOVDconst [c])) => (SRLconst x [c&63]) +(SRA x (MOVDconst [c])) => (SRAconst x [c&63]) -(CMP x (MOVDconst [c])) -> (CMPconst [c] x) -(CMP (MOVDconst [c]) x) -> (InvertFlags (CMPconst [c] x)) +(CMP x (MOVDconst [c])) => (CMPconst [c] x) +(CMP (MOVDconst [c]) x) => (InvertFlags (CMPconst [c] x)) (CMPW x (MOVDconst [c])) => (CMPWconst [int32(c)] x) (CMPW (MOVDconst [c]) x) => (InvertFlags (CMPWconst [int32(c)] x)) // Canonicalize the order of arguments to comparisons - helps with CSE. -((CMP|CMPW) x y) && x.ID > y.ID -> (InvertFlags ((CMP|CMPW) y x)) +((CMP|CMPW) x y) && x.ID > y.ID => (InvertFlags ((CMP|CMPW) y x)) -// mul-neg -> mneg -(NEG (MUL x y)) -> (MNEG x y) -(NEG (MULW x y)) -> (MNEGW x y) -(MUL (NEG x) y) -> (MNEG x y) -(MULW (NEG x) y) -> (MNEGW x y) +// mul-neg => mneg +(NEG (MUL x y)) => (MNEG x y) +(NEG (MULW x y)) => (MNEGW x y) +(MUL (NEG x) y) => (MNEG x y) +(MULW (NEG x) y) => (MNEGW x y) // madd/msub -(ADD a l:(MUL x y)) && l.Uses==1 && clobber(l) -> (MADD a x y) -(SUB a l:(MUL x y)) && l.Uses==1 && clobber(l) -> (MSUB a x y) -(ADD a l:(MNEG x y)) && l.Uses==1 && clobber(l) -> (MSUB a x y) -(SUB a l:(MNEG x y)) && l.Uses==1 && clobber(l) -> (MADD a x y) +(ADD a l:(MUL x y)) && l.Uses==1 && clobber(l) => (MADD a x y) +(SUB a l:(MUL x y)) && l.Uses==1 && clobber(l) => (MSUB a x y) +(ADD a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MSUB a x y) +(SUB a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MADD a x y) -(ADD a l:(MULW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) -> (MADDW a x y) -(SUB a l:(MULW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) -> (MSUBW a x y) -(ADD a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) -> (MSUBW a x y) -(SUB a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) -> (MADDW a x y) +(ADD a l:(MULW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y) +(SUB a l:(MULW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y) +(ADD a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y) +(SUB a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y) // optimize ADCSflags, SBCSflags and friends -(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c)))) -> (ADCSflags x y c) -(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (MOVDconst [0])))) -> (ADDSflags x y) -(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> bo))))) -> (SBCSflags x y bo) -(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (MOVDconst [0])))) -> (SUBSflags x y) +(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c)))) => (ADCSflags x y c) +(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (MOVDconst [0])))) => (ADDSflags x y) +(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> bo))))) => (SBCSflags x y bo) +(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (MOVDconst [0])))) => (SUBSflags x y) // mul by constant -(MUL x (MOVDconst [-1])) -> (NEG x) -(MUL _ (MOVDconst [0])) -> (MOVDconst [0]) -(MUL x (MOVDconst [1])) -> x -(MUL x (MOVDconst [c])) && isPowerOfTwo(c) -> (SLLconst [log2(c)] x) -(MUL x (MOVDconst [c])) && isPowerOfTwo(c-1) && c >= 3 -> (ADDshiftLL x x [log2(c-1)]) -(MUL x (MOVDconst [c])) && isPowerOfTwo(c+1) && c >= 7 -> (ADDshiftLL (NEG <x.Type> x) x [log2(c+1)]) -(MUL x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) -(MUL x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) -(MUL x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (SLLconst [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) -(MUL x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) +(MUL x (MOVDconst [-1])) => (NEG x) +(MUL _ (MOVDconst [0])) => (MOVDconst [0]) +(MUL x (MOVDconst [1])) => x +(MUL x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x) +(MUL x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (ADDshiftLL x x [log64(c-1)]) +(MUL x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)]) +(MUL x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1])) +(MUL x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2])) +(MUL x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) +(MUL x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3])) -(MULW x (MOVDconst [c])) && int32(c)==-1 -> (NEG x) -(MULW _ (MOVDconst [c])) && int32(c)==0 -> (MOVDconst [0]) -(MULW x (MOVDconst [c])) && int32(c)==1 -> x -(MULW x (MOVDconst [c])) && isPowerOfTwo(c) -> (SLLconst [log2(c)] x) -(MULW x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADDshiftLL x x [log2(c-1)]) -(MULW x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (ADDshiftLL (NEG <x.Type> x) x [log2(c+1)]) -(MULW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) -(MULW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) -(MULW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) -(MULW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) +(MULW x (MOVDconst [c])) && int32(c)==-1 => (NEG x) +(MULW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0]) +(MULW x (MOVDconst [c])) && int32(c)==1 => x +(MULW x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x) +(MULW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (ADDshiftLL x x [log64(c-1)]) +(MULW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)]) +(MULW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1])) +(MULW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2])) +(MULW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) +(MULW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3])) // mneg by constant -(MNEG x (MOVDconst [-1])) -> x -(MNEG _ (MOVDconst [0])) -> (MOVDconst [0]) -(MNEG x (MOVDconst [1])) -> (NEG x) -(MNEG x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x)) -(MNEG x (MOVDconst [c])) && isPowerOfTwo(c-1) && c >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MNEG x (MOVDconst [c])) && isPowerOfTwo(c+1) && c >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) -(MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2])) -(MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) -(MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3])) -(MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) +(MNEG x (MOVDconst [-1])) => x +(MNEG _ (MOVDconst [0])) => (MOVDconst [0]) +(MNEG x (MOVDconst [1])) => (NEG x) +(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x)) +(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)])) +(MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2])) +(MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))) +(MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3])) +(MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))) + + +(MNEGW x (MOVDconst [c])) && int32(c)==-1 => x +(MNEGW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0]) +(MNEGW x (MOVDconst [c])) && int32(c)==1 => (NEG x) +(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x)) +(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)])) +(MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2])) +(MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))) +(MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3])) +(MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))) -(MNEGW x (MOVDconst [c])) && int32(c)==-1 -> x -(MNEGW _ (MOVDconst [c])) && int32(c)==0 -> (MOVDconst [0]) -(MNEGW x (MOVDconst [c])) && int32(c)==1 -> (NEG x) -(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c) -> (NEG (SLLconst <x.Type> [log2(c)] x)) -(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MNEGW x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) -(MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2])) -(MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) -(MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3])) -(MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) -(MADD a x (MOVDconst [-1])) -> (SUB a x) -(MADD a _ (MOVDconst [0])) -> a -(MADD a x (MOVDconst [1])) -> (ADD a x) -(MADD a x (MOVDconst [c])) && isPowerOfTwo(c) -> (ADDshiftLL a x [log2(c)]) -(MADD a x (MOVDconst [c])) && isPowerOfTwo(c-1) && c>=3 -> (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MADD a x (MOVDconst [c])) && isPowerOfTwo(c+1) && c>=7 -> (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MADD a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MADD a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MADD a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MADD a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MADD a x (MOVDconst [-1])) => (SUB a x) +(MADD a _ (MOVDconst [0])) => a +(MADD a x (MOVDconst [1])) => (ADD a x) +(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)]) +(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MADD a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MADD a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MADD a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MADD a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MADD a (MOVDconst [-1]) x) -> (SUB a x) -(MADD a (MOVDconst [0]) _) -> a -(MADD a (MOVDconst [1]) x) -> (ADD a x) -(MADD a (MOVDconst [c]) x) && isPowerOfTwo(c) -> (ADDshiftLL a x [log2(c)]) -(MADD a (MOVDconst [c]) x) && isPowerOfTwo(c-1) && c>=3 -> (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MADD a (MOVDconst [c]) x) && isPowerOfTwo(c+1) && c>=7 -> (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MADD a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo(c/3) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MADD a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo(c/5) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MADD a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo(c/7) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MADD a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo(c/9) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MADD a (MOVDconst [-1]) x) => (SUB a x) +(MADD a (MOVDconst [0]) _) => a +(MADD a (MOVDconst [1]) x) => (ADD a x) +(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)]) +(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MADD a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MADD a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MADD a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MADD a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MADDW a x (MOVDconst [c])) && int32(c)==-1 -> (SUB a x) -(MADDW a _ (MOVDconst [c])) && int32(c)==0 -> a -(MADDW a x (MOVDconst [c])) && int32(c)==1 -> (ADD a x) -(MADDW a x (MOVDconst [c])) && isPowerOfTwo(c) -> (ADDshiftLL a x [log2(c)]) -(MADDW a x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c)>=3 -> (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MADDW a x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c)>=7 -> (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MADDW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MADDW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MADDW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MADDW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MADDW a x (MOVDconst [c])) && int32(c)==-1 => (SUB a x) +(MADDW a _ (MOVDconst [c])) && int32(c)==0 => a +(MADDW a x (MOVDconst [c])) && int32(c)==1 => (ADD a x) +(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)]) +(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MADDW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MADDW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MADDW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MADDW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MADDW a (MOVDconst [c]) x) && int32(c)==-1 -> (SUB a x) -(MADDW a (MOVDconst [c]) _) && int32(c)==0 -> a -(MADDW a (MOVDconst [c]) x) && int32(c)==1 -> (ADD a x) -(MADDW a (MOVDconst [c]) x) && isPowerOfTwo(c) -> (ADDshiftLL a x [log2(c)]) -(MADDW a (MOVDconst [c]) x) && isPowerOfTwo(c-1) && int32(c)>=3 -> (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MADDW a (MOVDconst [c]) x) && isPowerOfTwo(c+1) && int32(c)>=7 -> (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MADDW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MADDW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MADDW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MADDW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MADDW a (MOVDconst [c]) x) && int32(c)==-1 => (SUB a x) +(MADDW a (MOVDconst [c]) _) && int32(c)==0 => a +(MADDW a (MOVDconst [c]) x) && int32(c)==1 => (ADD a x) +(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)]) +(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MADDW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MADDW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MADDW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MADDW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MSUB a x (MOVDconst [-1])) -> (ADD a x) -(MSUB a _ (MOVDconst [0])) -> a -(MSUB a x (MOVDconst [1])) -> (SUB a x) -(MSUB a x (MOVDconst [c])) && isPowerOfTwo(c) -> (SUBshiftLL a x [log2(c)]) -(MSUB a x (MOVDconst [c])) && isPowerOfTwo(c-1) && c>=3 -> (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MSUB a x (MOVDconst [c])) && isPowerOfTwo(c+1) && c>=7 -> (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MSUB a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MSUB a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MSUB a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MSUB a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MSUB a x (MOVDconst [-1])) => (ADD a x) +(MSUB a _ (MOVDconst [0])) => a +(MSUB a x (MOVDconst [1])) => (SUB a x) +(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)]) +(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MSUB a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MSUB a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MSUB a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MSUB a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MSUB a (MOVDconst [-1]) x) -> (ADD a x) -(MSUB a (MOVDconst [0]) _) -> a -(MSUB a (MOVDconst [1]) x) -> (SUB a x) -(MSUB a (MOVDconst [c]) x) && isPowerOfTwo(c) -> (SUBshiftLL a x [log2(c)]) -(MSUB a (MOVDconst [c]) x) && isPowerOfTwo(c-1) && c>=3 -> (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MSUB a (MOVDconst [c]) x) && isPowerOfTwo(c+1) && c>=7 -> (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MSUB a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo(c/3) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MSUB a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo(c/5) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MSUB a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo(c/7) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MSUB a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo(c/9) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MSUB a (MOVDconst [-1]) x) => (ADD a x) +(MSUB a (MOVDconst [0]) _) => a +(MSUB a (MOVDconst [1]) x) => (SUB a x) +(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)]) +(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MSUB a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MSUB a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MSUB a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MSUB a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MSUBW a x (MOVDconst [c])) && int32(c)==-1 -> (ADD a x) -(MSUBW a _ (MOVDconst [c])) && int32(c)==0 -> a -(MSUBW a x (MOVDconst [c])) && int32(c)==1 -> (SUB a x) -(MSUBW a x (MOVDconst [c])) && isPowerOfTwo(c) -> (SUBshiftLL a x [log2(c)]) -(MSUBW a x (MOVDconst [c])) && isPowerOfTwo(c-1) && int32(c)>=3 -> (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MSUBW a x (MOVDconst [c])) && isPowerOfTwo(c+1) && int32(c)>=7 -> (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MSUBW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MSUBW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MSUBW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MSUBW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MSUBW a x (MOVDconst [c])) && int32(c)==-1 => (ADD a x) +(MSUBW a _ (MOVDconst [c])) && int32(c)==0 => a +(MSUBW a x (MOVDconst [c])) && int32(c)==1 => (SUB a x) +(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)]) +(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MSUBW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MSUBW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MSUBW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MSUBW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) -(MSUBW a (MOVDconst [c]) x) && int32(c)==-1 -> (ADD a x) -(MSUBW a (MOVDconst [c]) _) && int32(c)==0 -> a -(MSUBW a (MOVDconst [c]) x) && int32(c)==1 -> (SUB a x) -(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo(c) -> (SUBshiftLL a x [log2(c)]) -(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo(c-1) && int32(c)>=3 -> (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) -(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo(c+1) && int32(c)>=7 -> (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) -(MSUBW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) -(MSUBW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) -(MSUBW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) -(MSUBW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) +(MSUBW a (MOVDconst [c]) x) && int32(c)==-1 => (ADD a x) +(MSUBW a (MOVDconst [c]) _) && int32(c)==0 => a +(MSUBW a (MOVDconst [c]) x) && int32(c)==1 => (SUB a x) +(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)]) +(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) +(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) +(MSUBW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) +(MSUBW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) +(MSUBW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) +(MSUBW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) // div by constant -(UDIV x (MOVDconst [1])) -> x -(UDIV x (MOVDconst [c])) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x) -(UDIVW x (MOVDconst [c])) && uint32(c)==1 -> x -(UDIVW x (MOVDconst [c])) && isPowerOfTwo(c) && is32Bit(c) -> (SRLconst [log2(c)] x) -(UMOD _ (MOVDconst [1])) -> (MOVDconst [0]) -(UMOD x (MOVDconst [c])) && isPowerOfTwo(c) -> (ANDconst [c-1] x) -(UMODW _ (MOVDconst [c])) && uint32(c)==1 -> (MOVDconst [0]) -(UMODW x (MOVDconst [c])) && isPowerOfTwo(c) && is32Bit(c) -> (ANDconst [c-1] x) +(UDIV x (MOVDconst [1])) => x +(UDIV x (MOVDconst [c])) && isPowerOfTwo64(c) => (SRLconst [log64(c)] x) +(UDIVW x (MOVDconst [c])) && uint32(c)==1 => x +(UDIVW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (SRLconst [log64(c)] x) +(UMOD _ (MOVDconst [1])) => (MOVDconst [0]) +(UMOD x (MOVDconst [c])) && isPowerOfTwo64(c) => (ANDconst [c-1] x) +(UMODW _ (MOVDconst [c])) && uint32(c)==1 => (MOVDconst [0]) +(UMODW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (ANDconst [c-1] x) // generic simplifications -(ADD x (NEG y)) -> (SUB x y) -(SUB x x) -> (MOVDconst [0]) -(AND x x) -> x -(OR x x) -> x -(XOR x x) -> (MOVDconst [0]) -(BIC x x) -> (MOVDconst [0]) -(EON x x) -> (MOVDconst [-1]) -(ORN x x) -> (MOVDconst [-1]) -(AND x (MVN y)) -> (BIC x y) -(XOR x (MVN y)) -> (EON x y) -(OR x (MVN y)) -> (ORN x y) -(MVN (XOR x y)) -> (EON x y) +(ADD x (NEG y)) => (SUB x y) +(SUB x x) => (MOVDconst [0]) +(AND x x) => x +(OR x x) => x +(XOR x x) => (MOVDconst [0]) +(BIC x x) => (MOVDconst [0]) +(EON x x) => (MOVDconst [-1]) +(ORN x x) => (MOVDconst [-1]) +(AND x (MVN y)) => (BIC x y) +(XOR x (MVN y)) => (EON x y) +(OR x (MVN y)) => (ORN x y) +(MVN (XOR x y)) => (EON x y) (CSEL [cc] x (MOVDconst [0]) flag) => (CSEL0 [cc] x flag) (CSEL [cc] (MOVDconst [0]) y flag) => (CSEL0 [arm64Negate(cc)] y flag) -(SUB x (SUB y z)) -> (SUB (ADD <v.Type> x z) y) -(SUB (SUB x y) z) -> (SUB x (ADD <y.Type> y z)) +(SUB x (SUB y z)) => (SUB (ADD <v.Type> x z) y) +(SUB (SUB x y) z) => (SUB x (ADD <y.Type> y z)) // remove redundant *const ops -(ADDconst [0] x) -> x -(SUBconst [0] x) -> x -(ANDconst [0] _) -> (MOVDconst [0]) -(ANDconst [-1] x) -> x -(ORconst [0] x) -> x -(ORconst [-1] _) -> (MOVDconst [-1]) -(XORconst [0] x) -> x -(XORconst [-1] x) -> (MVN x) +(ADDconst [0] x) => x +(SUBconst [0] x) => x +(ANDconst [0] _) => (MOVDconst [0]) +(ANDconst [-1] x) => x +(ORconst [0] x) => x +(ORconst [-1] _) => (MOVDconst [-1]) +(XORconst [0] x) => x +(XORconst [-1] x) => (MVN x) // generic constant folding -(ADDconst [c] (MOVDconst [d])) -> (MOVDconst [c+d]) -(ADDconst [c] (ADDconst [d] x)) -> (ADDconst [c+d] x) -(ADDconst [c] (SUBconst [d] x)) -> (ADDconst [c-d] x) -(SUBconst [c] (MOVDconst [d])) -> (MOVDconst [d-c]) -(SUBconst [c] (SUBconst [d] x)) -> (ADDconst [-c-d] x) -(SUBconst [c] (ADDconst [d] x)) -> (ADDconst [-c+d] x) -(SLLconst [c] (MOVDconst [d])) -> (MOVDconst [d<<uint64(c)]) -(SRLconst [c] (MOVDconst [d])) -> (MOVDconst [int64(uint64(d)>>uint64(c))]) -(SRAconst [c] (MOVDconst [d])) -> (MOVDconst [d>>uint64(c)]) -(MUL (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c*d]) -(MULW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(int32(c)*int32(d))]) -(MNEG (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [-c*d]) -(MNEGW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [-int64(int32(c)*int32(d))]) -(MADD (MOVDconst [c]) x y) -> (ADDconst [c] (MUL <x.Type> x y)) -(MADDW (MOVDconst [c]) x y) -> (ADDconst [c] (MULW <x.Type> x y)) -(MSUB (MOVDconst [c]) x y) -> (ADDconst [c] (MNEG <x.Type> x y)) -(MSUBW (MOVDconst [c]) x y) -> (ADDconst [c] (MNEGW <x.Type> x y)) -(MADD a (MOVDconst [c]) (MOVDconst [d])) -> (ADDconst [c*d] a) -(MADDW a (MOVDconst [c]) (MOVDconst [d])) -> (ADDconst [int64(int32(c)*int32(d))] a) -(MSUB a (MOVDconst [c]) (MOVDconst [d])) -> (SUBconst [c*d] a) -(MSUBW a (MOVDconst [c]) (MOVDconst [d])) -> (SUBconst [int64(int32(c)*int32(d))] a) -(DIV (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c/d]) -(UDIV (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(uint64(c)/uint64(d))]) -(DIVW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(int32(c)/int32(d))]) -(UDIVW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(uint32(c)/uint32(d))]) -(MOD (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c%d]) -(UMOD (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(uint64(c)%uint64(d))]) -(MODW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(int32(c)%int32(d))]) -(UMODW (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [int64(uint32(c)%uint32(d))]) -(ANDconst [c] (MOVDconst [d])) -> (MOVDconst [c&d]) -(ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x) -(ANDconst [c] (MOVWUreg x)) -> (ANDconst [c&(1<<32-1)] x) -(ANDconst [c] (MOVHUreg x)) -> (ANDconst [c&(1<<16-1)] x) -(ANDconst [c] (MOVBUreg x)) -> (ANDconst [c&(1<<8-1)] x) -(MOVWUreg (ANDconst [c] x)) -> (ANDconst [c&(1<<32-1)] x) -(MOVHUreg (ANDconst [c] x)) -> (ANDconst [c&(1<<16-1)] x) -(MOVBUreg (ANDconst [c] x)) -> (ANDconst [c&(1<<8-1)] x) -(ORconst [c] (MOVDconst [d])) -> (MOVDconst [c|d]) -(ORconst [c] (ORconst [d] x)) -> (ORconst [c|d] x) -(XORconst [c] (MOVDconst [d])) -> (MOVDconst [c^d]) -(XORconst [c] (XORconst [d] x)) -> (XORconst [c^d] x) -(MVN (MOVDconst [c])) -> (MOVDconst [^c]) -(NEG (MOVDconst [c])) -> (MOVDconst [-c]) -(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64(int8(c))]) -(MOVBUreg (MOVDconst [c])) -> (MOVDconst [int64(uint8(c))]) -(MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))]) -(MOVHUreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))]) -(MOVWreg (MOVDconst [c])) -> (MOVDconst [int64(int32(c))]) -(MOVWUreg (MOVDconst [c])) -> (MOVDconst [int64(uint32(c))]) -(MOVDreg (MOVDconst [c])) -> (MOVDconst [c]) +(ADDconst [c] (MOVDconst [d])) => (MOVDconst [c+d]) +(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x) +(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x) +(SUBconst [c] (MOVDconst [d])) => (MOVDconst [d-c]) +(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x) +(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x) +(SLLconst [c] (MOVDconst [d])) => (MOVDconst [d<<uint64(c)]) +(SRLconst [c] (MOVDconst [d])) => (MOVDconst [int64(uint64(d)>>uint64(c))]) +(SRAconst [c] (MOVDconst [d])) => (MOVDconst [d>>uint64(c)]) +(MUL (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c*d]) +(MULW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)*int32(d))]) +(MNEG (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-c*d]) +(MNEGW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-int64(int32(c)*int32(d))]) +(MADD (MOVDconst [c]) x y) => (ADDconst [c] (MUL <x.Type> x y)) +(MADDW (MOVDconst [c]) x y) => (ADDconst [c] (MULW <x.Type> x y)) +(MSUB (MOVDconst [c]) x y) => (ADDconst [c] (MNEG <x.Type> x y)) +(MSUBW (MOVDconst [c]) x y) => (ADDconst [c] (MNEGW <x.Type> x y)) +(MADD a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [c*d] a) +(MADDW a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [int64(int32(c)*int32(d))] a) +(MSUB a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [c*d] a) +(MSUBW a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [int64(int32(c)*int32(d))] a) +(DIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c/d]) +(UDIV (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)/uint64(d))]) +(DIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)/int32(d))]) +(UDIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)/uint32(d))]) +(MOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c%d]) +(UMOD (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)%uint64(d))]) +(MODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)%int32(d))]) +(UMODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)%uint32(d))]) +(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d]) +(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) +(ANDconst [c] (MOVWUreg x)) => (ANDconst [c&(1<<32-1)] x) +(ANDconst [c] (MOVHUreg x)) => (ANDconst [c&(1<<16-1)] x) +(ANDconst [c] (MOVBUreg x)) => (ANDconst [c&(1<<8-1)] x) +(MOVWUreg (ANDconst [c] x)) => (ANDconst [c&(1<<32-1)] x) +(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&(1<<16-1)] x) +(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&(1<<8-1)] x) +(ORconst [c] (MOVDconst [d])) => (MOVDconst [c|d]) +(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x) +(XORconst [c] (MOVDconst [d])) => (MOVDconst [c^d]) +(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x) +(MVN (MOVDconst [c])) => (MOVDconst [^c]) +(NEG (MOVDconst [c])) => (MOVDconst [-c]) +(MOVBreg (MOVDconst [c])) => (MOVDconst [int64(int8(c))]) +(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))]) +(MOVHreg (MOVDconst [c])) => (MOVDconst [int64(int16(c))]) +(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))]) +(MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))]) +(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))]) +(MOVDreg (MOVDconst [c])) => (MOVDconst [c]) // constant comparisons (CMPconst (MOVDconst [x]) [y]) => (FlagConstant [subFlags64(x,y)]) diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go index e9af261a6a..87db2b7c9d 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go @@ -471,9 +471,9 @@ func init() { {name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"}, // auxint(flags) ? arg0 : 0 // function calls - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R26"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R26"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // pseudo-ops {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem. @@ -621,6 +621,12 @@ func init() { {name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, {name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + // atomic exchange variant. + // store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero. + // SWPALD Rarg1, (Rarg0), Rout + {name: "LoweredAtomicExchange64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicExchange32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true}, + // atomic add. // *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero. // LDAXR (Rarg0), Rout @@ -654,14 +660,45 @@ func init() { {name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, {name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + // atomic compare and swap variant. + // arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero. + // if *arg0 == arg1 { + // *arg0 = arg2 + // return (true, memory) + // } else { + // return (false, memory) + // } + // MOV Rarg1, Rtmp + // CASAL Rtmp, (Rarg0), Rarg2 + // CMP Rarg1, Rtmp + // CSET EQ, Rout + {name: "LoweredAtomicCas64Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicCas32Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + // atomic and/or. // *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero. - // LDAXRB (Rarg0), Rout + // LDAXR (Rarg0), Rout // AND/OR Rarg1, Rout - // STLXRB Rout, (Rarg0), Rtmp + // STLXR Rout, (Rarg0), Rtmp // CBNZ Rtmp, -3(PC) {name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, {name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + + // atomic and/or variant. + // *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero. + // AND: + // MNV Rarg1, Rtemp + // LDANDALB Rtemp, (Rarg0), Rout + // AND Rarg1, Rout + // OR: + // LDORALB Rarg1, (Rarg0), Rout + // ORR Rarg1, Rout + {name: "LoweredAtomicAnd8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicAnd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicOr8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicOr32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true}, // LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier // It saves all GP registers if necessary, diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go index 068fecf74c..70c789937a 100644 --- a/src/cmd/compile/internal/ssa/gen/ARMOps.go +++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go @@ -428,9 +428,9 @@ func init() { {name: "SRAcond", argLength: 3, reg: gp2flags1, asm: "SRA"}, // arg0 >> 31 if flags indicates HS, arg0 >> arg1 otherwise, signed shift, arg2=flags // function calls - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R7"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R7"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // pseudo-ops {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem. diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules index 96feaf9234..8ad2c90ac3 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS.rules +++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules @@ -96,17 +96,17 @@ (Rsh8Ux16 <t> x y) => (CMOVZ (SRL <t> (ZeroExt8to32 x) (ZeroExt16to32 y) ) (MOVWconst [0]) (SGTUconst [32] (ZeroExt16to32 y))) (Rsh8Ux8 <t> x y) => (CMOVZ (SRL <t> (ZeroExt8to32 x) (ZeroExt8to32 y) ) (MOVWconst [0]) (SGTUconst [32] (ZeroExt8to32 y))) -(Rsh32x32 x y) => (SRA x ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) -(Rsh32x16 x y) => (SRA x ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) -(Rsh32x8 x y) => (SRA x ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) +(Rsh32x32 x y) => (SRA x ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) +(Rsh32x16 x y) => (SRA x ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) +(Rsh32x8 x y) => (SRA x ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) -(Rsh16x32 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) -(Rsh16x16 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) -(Rsh16x8 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) +(Rsh16x32 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) +(Rsh16x16 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) +(Rsh16x8 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) -(Rsh8x32 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) -(Rsh8x16 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) -(Rsh8x8 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) +(Rsh8x32 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) +(Rsh8x16 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) +(Rsh8x8 x y) => (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) // rotates (RotateLeft8 <t> x (MOVWconst [c])) => (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7]))) @@ -143,7 +143,7 @@ (Const(32|16|8) [val]) => (MOVWconst [int32(val)]) (Const(32|64)F ...) => (MOV(F|D)const ...) (ConstNil) => (MOVWconst [0]) -(ConstBool [b]) => (MOVWconst [int32(b2i(b))]) +(ConstBool [b]) => (MOVWconst [b2i32(b)]) // truncations // Because we ignore high parts of registers, truncates are just copies. @@ -383,6 +383,9 @@ (ANDconst <typ.UInt32> [3] (XORconst <typ.UInt32> [3] ptr)))))) mem) +(AtomicAnd32 ...) => (LoweredAtomicAnd ...) +(AtomicOr32 ...) => (LoweredAtomicOr ...) + // checks (NilCheck ...) => (LoweredNilCheck ...) @@ -459,36 +462,36 @@ (MOVWstorezero [off1] {sym} x:(ADDconst [off2] ptr) mem) && (is16Bit(int64(off1+off2)) || x.Uses == 1) => (MOVWstorezero [off1+off2] {sym} ptr mem) (MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVFload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => - (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => - (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => - (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => - (MOVFstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) => - (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVBstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) => - (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) // replace load from same location as preceding store with zero/sign extension (or copy in case of full width) (MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBreg x) @@ -564,10 +567,9 @@ (XOR x (MOVWconst [c])) => (XORconst [c] x) (NOR x (MOVWconst [c])) => (NORconst [c] x) -(SRA x (MOVWconst [c])) && c >= 32 => (SRAconst x [31]) -(SLL x (MOVWconst [c])) => (SLLconst x [c]) -(SRL x (MOVWconst [c])) => (SRLconst x [c]) -(SRA x (MOVWconst [c])) => (SRAconst x [c]) +(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) +(SRL x (MOVWconst [c])) => (SRLconst x [c&31]) +(SRA x (MOVWconst [c])) => (SRAconst x [c&31]) (SGT (MOVWconst [c]) x) => (SGTconst [c] x) (SGTU (MOVWconst [c]) x) => (SGTUconst [c] x) @@ -581,13 +583,13 @@ (Select0 (MULTU (MOVWconst [1]) _ )) => (MOVWconst [0]) (Select1 (MULTU (MOVWconst [-1]) x )) => (NEG <x.Type> x) (Select0 (MULTU (MOVWconst [-1]) x )) => (CMOVZ (ADDconst <x.Type> [-1] x) (MOVWconst [0]) x) -(Select1 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x) -(Select0 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo(int64(uint32(c))) => (SRLconst [int32(32-log2uint32(int64(c)))] x) +(Select1 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo64(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x) +(Select0 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo64(int64(uint32(c))) => (SRLconst [int32(32-log2uint32(int64(c)))] x) (MUL (MOVWconst [0]) _ ) => (MOVWconst [0]) (MUL (MOVWconst [1]) x ) => x (MUL (MOVWconst [-1]) x ) => (NEG x) -(MUL (MOVWconst [c]) x ) && isPowerOfTwo(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x) +(MUL (MOVWconst [c]) x ) && isPowerOfTwo64(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x) // generic simplifications (ADD x (NEG y)) => (SUB x y) @@ -624,10 +626,10 @@ (MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d]) (Select1 (MULTU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)*uint32(d))]) (Select0 (MULTU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32((int64(uint32(c))*int64(uint32(d)))>>32)]) -(Select1 (DIV (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [c/d]) -(Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)/uint32(d))]) -(Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [c%d]) -(Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) => (MOVWconst [int32(uint32(c)%uint32(d))]) +(Select1 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c/d]) +(Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))]) +(Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [c%d]) +(Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))]) (ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d]) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d]) diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules index e008ec8703..088c9b1ac4 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules +++ b/src/cmd/compile/internal/ssa/gen/MIPS64.rules @@ -462,44 +462,44 @@ (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) (MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVFload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVDload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVFstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVDstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) (MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) (MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVVstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) // store zero (MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem) @@ -580,13 +580,13 @@ (Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x) (Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0]) (Select1 (MULVU x (MOVVconst [1]))) => x -(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo(c) => (SLLVconst [log2(c)] x) +(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x) // div by constant (Select1 (DIVVU x (MOVVconst [1]))) => x -(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo(c) => (SRLVconst [log2(c)] x) +(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x) (Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0]) // mod -(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo(c) => (ANDconst [c-1] x) // mod +(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod // generic simplifications (ADDV x (NEGV y)) => (SUBV x y) @@ -617,10 +617,10 @@ (SRLVconst [c] (MOVVconst [d])) => (MOVVconst [int64(uint64(d)>>uint64(c))]) (SRAVconst [c] (MOVVconst [d])) => (MOVVconst [d>>uint64(c)]) (Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d]) -(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c/d]) -(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [int64(uint64(c)/uint64(d))]) -(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c%d]) // mod -(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod +(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d]) +(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))]) +(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d]) // mod +(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod (ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d]) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d]) diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go index 5f00c080af..e1e3933502 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go @@ -273,9 +273,9 @@ func init() { {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"}, // float64 -> float32 // function calls - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // duffzero // arg0 = address of memory to zero diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go index a5f6c8df54..75ab99ea26 100644 --- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go +++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go @@ -185,11 +185,11 @@ func init() { // shifts {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32 - {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt + {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, shift amount must be 0 through 31 inclusive {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 32 - {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned + {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, shift amount must be 0 through 31 inclusive {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 32 - {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed + {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, shift amount must be 0 through 31 inclusive {name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"}, @@ -255,9 +255,9 @@ func init() { {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"}, // float64 -> float32 // function calls - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // atomic ops diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index e5fb1e98c2..c064046172 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -79,6 +79,23 @@ (Abs ...) => (FABS ...) (FMA ...) => (FMADD ...) +// Lowering extension +// Note: we always extend to 64 bits even though some ops don't need that many result bits. +(SignExt8to(16|32|64) ...) => (MOVBreg ...) +(SignExt16to(32|64) ...) => (MOVHreg ...) +(SignExt32to64 ...) => (MOVWreg ...) + +(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...) +(ZeroExt16to(32|64) ...) => (MOVHZreg ...) +(ZeroExt32to64 ...) => (MOVWZreg ...) + +(Trunc(16|32|64)to8 <t> x) && isSigned(t) => (MOVBreg x) +(Trunc(16|32|64)to8 x) => (MOVBZreg x) +(Trunc(32|64)to16 <t> x) && isSigned(t) => (MOVHreg x) +(Trunc(32|64)to16 x) => (MOVHZreg x) +(Trunc64to32 <t> x) && isSigned(t) => (MOVWreg x) +(Trunc64to32 x) => (MOVWZreg x) + // Lowering constants (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)]) (Const(32|64)F ...) => (FMOV(S|D)const ...) @@ -133,6 +150,31 @@ (ROTLW x (MOVDconst [c])) => (ROTLWconst x [c&31]) (ROTL x (MOVDconst [c])) => (ROTLconst x [c&63]) +// Combine rotate and mask operations +(ANDconst [m] (ROTLWconst [r] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x) +(AND (MOVDconst [m]) (ROTLWconst [r] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x) +(ANDconst [m] (ROTLW x r)) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r) +(AND (MOVDconst [m]) (ROTLW x r)) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r) + +// Note, any rotated word bitmask is still a valid word bitmask. +(ROTLWconst [r] (AND (MOVDconst [m]) x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x) +(ROTLWconst [r] (ANDconst [m] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x) + +(ANDconst [m] (SRWconst x [s])) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0]) +(ANDconst [m] (SRWconst x [s])) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x) +(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0]) +(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x) + +(SRWconst (ANDconst [m] x) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0]) +(SRWconst (ANDconst [m] x) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x) +(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0]) +(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x) + +// Merge shift right + shift left and clear left (e.g for a table lookup) +(CLRLSLDI [c] (SRWconst [s] x)) && mergePPC64ClrlsldiSrw(int64(c),s) != 0 => (RLWINM [mergePPC64ClrlsldiSrw(int64(c),s)] x) +(SLDconst [l] (SRWconst [r] x)) && mergePPC64SldiSrw(l,r) != 0 => (RLWINM [mergePPC64SldiSrw(l,r)] x) +// The following reduction shows up frequently too. e.g b[(x>>14)&0xFF] +(CLRLSLDI [c] i:(RLWINM [s] x)) && mergePPC64ClrlsldiRlwinm(c,s) != 0 => (RLWINM [mergePPC64ClrlsldiRlwinm(c,s)] x) // large constant shifts (Lsh64x64 _ (MOVDconst [c])) && uint64(c) >= 64 => (MOVDconst [0]) @@ -780,6 +822,21 @@ (MOVWreg y:(MOVWZreg x)) => (MOVWreg x) (MOVWZreg y:(MOVWreg x)) => (MOVWZreg x) +// Truncate then logical then truncate: omit first, lesser or equal truncate +(MOVWZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVWZreg ((OR|XOR|AND) <t> x y)) +(MOVHZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y)) +(MOVHZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y)) +(MOVBZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y)) +(MOVBZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y)) +(MOVBZreg ((OR|XOR|AND) <t> x (MOVBZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y)) + +(MOV(B|H|W)Zreg z:(ANDconst [c] (MOVBZload ptr x))) => z +(MOVBZreg z:(AND y (MOVBZload ptr x))) => z +(MOV(H|W)Zreg z:(ANDconst [c] (MOVHZload ptr x))) => z +(MOVHZreg z:(AND y (MOVHZload ptr x))) => z +(MOVWZreg z:(ANDconst [c] (MOVWZload ptr x))) => z +(MOVWZreg z:(AND y (MOVWZload ptr x))) => z + // Arithmetic constant ops (ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [c] x) @@ -788,6 +845,9 @@ (SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x) (ADDconst [c] (MOVDaddr [d] {sym} x)) && is32Bit(c+int64(d)) => (MOVDaddr [int32(c+int64(d))] {sym} x) +(ADDconst [c] x:(SP)) && is32Bit(c) => (MOVDaddr [int32(c)] x) // so it is rematerializeable + +(MULL(W|D) x (MOVDconst [c])) && is16Bit(c) => (MULL(W|D)const [int32(c)] x) // Subtract from (with carry, but ignored) constant. // Note, these clobber the carry bit. @@ -829,48 +889,48 @@ // is only one use. (MOVBstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVHstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVWstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 => - (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (FMOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVBZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVBZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVHZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 => - (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (MOVWZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 => - (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) => - (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) // Fold offsets for loads. (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOVSload [off1+int32(off2)] {sym} ptr mem) @@ -920,23 +980,23 @@ // Fold symbols into storezero (MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 => - (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) (MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) => - (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) (MOVHstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) => - (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) (MOVBstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) => - (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) // atomic intrinsics (AtomicLoad(8|32|64|Ptr) ptr mem) => (LoweredAtomicLoad(8|32|64|Ptr) [1] ptr mem) -(AtomicLoadAcq32 ptr mem) => (LoweredAtomicLoad32 [0] ptr mem) +(AtomicLoadAcq(32|64) ptr mem) => (LoweredAtomicLoad(32|64) [0] ptr mem) (AtomicStore(8|32|64) ptr val mem) => (LoweredAtomicStore(8|32|64) [1] ptr val mem) -(AtomicStoreRel32 ptr val mem) => (LoweredAtomicStore32 [0] ptr val mem) +(AtomicStoreRel(32|64) ptr val mem) => (LoweredAtomicStore(32|64) [0] ptr val mem) //(AtomicStorePtrNoWB ptr val mem) => (STLR ptr val mem) (AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...) @@ -946,25 +1006,10 @@ (AtomicCompareAndSwap(32|64) ptr old new_ mem) => (LoweredAtomicCas(32|64) [1] ptr old new_ mem) (AtomicCompareAndSwapRel32 ptr old new_ mem) => (LoweredAtomicCas32 [0] ptr old new_ mem) -(AtomicAnd8 ...) => (LoweredAtomicAnd8 ...) -(AtomicOr8 ...) => (LoweredAtomicOr8 ...) - -// Lowering extension -// Note: we always extend to 64 bits even though some ops don't need that many result bits. -(SignExt8to(16|32|64) ...) => (MOVBreg ...) -(SignExt16to(32|64) ...) => (MOVHreg ...) -(SignExt32to64 ...) => (MOVWreg ...) - -(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...) -(ZeroExt16to(32|64) ...) => (MOVHZreg ...) -(ZeroExt32to64 ...) => (MOVWZreg ...) - -(Trunc(16|32|64)to8 <t> x) && isSigned(t) => (MOVBreg x) -(Trunc(16|32|64)to8 x) => (MOVBZreg x) -(Trunc(32|64)to16 <t> x) && isSigned(t) => (MOVHreg x) -(Trunc(32|64)to16 x) => (MOVHZreg x) -(Trunc64to32 <t> x) && isSigned(t) => (MOVWreg x) -(Trunc64to32 x) => (MOVWZreg x) +(AtomicAnd8 ...) => (LoweredAtomicAnd8 ...) +(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...) +(AtomicOr8 ...) => (LoweredAtomicOr8 ...) +(AtomicOr32 ...) => (LoweredAtomicOr32 ...) (Slicemask <t> x) => (SRADconst (NEG <t> x) [63]) @@ -996,6 +1041,21 @@ (MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))]) (MOVWZreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))]) +// Implement clrsldi and clrslwi extended mnemonics as described in +// ISA 3.0 section C.8. AuxInt field contains values needed for +// the instructions, packed together since there is only one available. +(SLDconst [c] z:(MOVBZreg x)) && c < 8 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,56,63,64)] x) +(SLDconst [c] z:(MOVHZreg x)) && c < 16 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,48,63,64)] x) +(SLDconst [c] z:(MOVWZreg x)) && c < 32 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,32,63,64)] x) + +(SLDconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x) +(SLDconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x) +(SLWconst [c] z:(MOVBZreg x)) && z.Uses == 1 && c < 8 => (CLRLSLWI [newPPC64ShiftAuxInt(c,24,31,32)] x) +(SLWconst [c] z:(MOVHZreg x)) && z.Uses == 1 && c < 16 => (CLRLSLWI [newPPC64ShiftAuxInt(c,16,31,32)] x) +(SLWconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x) +(SLWconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x) +// special case for power9 +(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && objabi.GOPPC64 >= 9 => (EXTSWSLconst [c] x) // Lose widening ops fed to stores (MOVBstore [off] {sym} ptr (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstore [off] {sym} ptr x mem) diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go index 44f6a74c63..f7198b90c3 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go @@ -137,6 +137,7 @@ func init() { gp01 = regInfo{inputs: nil, outputs: []regMask{gp}} gp11 = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}} gp21 = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}} + gp21a0 = regInfo{inputs: []regMask{gp, gp | sp | sb}, outputs: []regMask{gp}} gp31 = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}} gp22 = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, gp}} gp32 = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, gp}} @@ -181,6 +182,8 @@ func init() { {name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true}, // arg0*arg1 (signed 64-bit) {name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true}, // arg0*arg1 (signed 32-bit) + {name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit) + {name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit) {name: "MADDLD", argLength: 3, reg: gp31, asm: "MADDLD", typ: "Int64"}, // (arg0*arg1)+arg2 (signed 64-bit) {name: "MULHD", argLength: 2, reg: gp21, asm: "MULHD", commutative: true}, // (arg0 * arg1) >> 64, signed @@ -206,6 +209,11 @@ func init() { {name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"}, // arg0 rotate left by arg1 mod 64 {name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32 + // The following are ops to implement the extended mnemonics for shifts as described in section C.8 of the ISA. + // The constant shift values are packed into the aux int32. + {name: "RLDICL", argLength: 1, reg: gp11, asm: "RLDICL", aux: "Int32"}, // arg0 extract bits identified by shift params" + {name: "CLRLSLWI", argLength: 1, reg: gp11, asm: "CLRLSLWI", aux: "Int32"}, // + {name: "CLRLSLDI", argLength: 1, reg: gp11, asm: "CLRLSLDI", aux: "Int32"}, // {name: "LoweredAdd64Carry", argLength: 3, reg: gp32, resultNotInArgs: true}, // arg0 + arg1 + carry, returns (sum, carry) @@ -218,6 +226,11 @@ func init() { {name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"}, // arg0 rotate left by auxInt bits {name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32(arg0) rotate left by auxInt bits + {name: "EXTSWSLconst", argLength: 1, reg: gp11, asm: "EXTSWSLI", aux: "Int64"}, + + {name: "RLWINM", argLength: 1, reg: gp11, asm: "RLWNM", aux: "Int64"}, // Rotate and mask by immediate "rlwinm". encodePPC64RotateMask describes aux + {name: "RLWNM", argLength: 2, reg: gp21, asm: "RLWNM", aux: "Int64"}, // Rotate and mask by "rlwnm". encodePPC64RotateMask describes aux + {name: "RLWMI", argLength: 2, reg: gp21a0, asm: "RLWMI", aux: "Int64", resultInArg0: true}, // "rlwimi" similar aux encoding as above {name: "CNTLZD", argLength: 1, reg: gp11, asm: "CNTLZD", clobberFlags: true}, // count leading zeros {name: "CNTLZW", argLength: 1, reg: gp11, asm: "CNTLZW", clobberFlags: true}, // count leading zeros (32 bit) @@ -414,9 +427,9 @@ func init() { {name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true}, {name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true}, - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // large or unaligned zeroing // arg0 = address of memory to zero (in R3, changed as side effect) @@ -594,25 +607,22 @@ func init() { {name: "LoweredAtomicLoadPtr", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true}, // atomic add32, 64 - // SYNC + // LWSYNC // LDAR (Rarg0), Rout // ADD Rarg1, Rout // STDCCC Rout, (Rarg0) // BNE -3(PC) - // ISYNC // return new sum - {name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, {name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, // atomic exchange32, 64 - // SYNC + // LWSYNC // LDAR (Rarg0), Rout // STDCCC Rarg1, (Rarg0) // BNE -2(PC) // ISYNC // return old val - {name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, {name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, @@ -635,15 +645,16 @@ func init() { {name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, {name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, - // atomic 8 and/or. + // atomic 8/32 and/or. // *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero. - // LBAR (Rarg0), Rtmp + // LBAR/LWAT (Rarg0), Rtmp // AND/OR Rarg1, Rtmp - // STBCCC Rtmp, (Rarg0), Rtmp + // STBCCC/STWCCC Rtmp, (Rarg0), Rtmp // BNE Rtmp, -3(PC) - {name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicAnd32", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true}, {name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicOr32", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true}, // LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier // It preserves R0 through R17 (except special registers R1, R2, R11, R12, R13), g, and its arguments R20 and R21, diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules index 9437c8e9d4..4380a5efef 100644 --- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules @@ -3,17 +3,12 @@ // license that can be found in the LICENSE file. // Optimizations TODO: -// * Somehow track when values are already zero/signed-extended, avoid re-extending. // * Use SLTI and SLTIU for comparisons to constants, instead of SLT/SLTU with constants in registers -// * Find a more efficient way to do zero/sign extension than left+right shift. -// There are many other options (store then load-extend, LUI+ANDI for zero extend, special case 32->64, ...), -// but left+right shift is simple and uniform, and we don't have real hardware to do perf testing on anyway. // * Use the zero register instead of moving 0 into a register. // * Add rules to avoid generating a temp bool value for (If (SLT[U] ...) ...). // * Optimize left and right shift by simplifying SLTIU, Neg, and ADD for constants. // * Arrange for non-trivial Zero and Move lowerings to use aligned loads and stores. // * Eliminate zero immediate shifts, adds, etc. -// * Use a Duff's device for some moves and zeros. // * Avoid using Neq32 for writeBarrier.enabled checks. // Lowering arithmetic @@ -66,8 +61,8 @@ (Mod32u ...) => (REMUW ...) (Mod16 x y [false]) => (REMW (SignExt16to32 x) (SignExt16to32 y)) (Mod16u x y) => (REMUW (ZeroExt16to32 x) (ZeroExt16to32 y)) -(Mod8 x y) => (REMW (SignExt8to32 x) (SignExt8to32 y)) -(Mod8u x y) => (REMUW (ZeroExt8to32 x) (ZeroExt8to32 y)) +(Mod8 x y) => (REMW (SignExt8to32 x) (SignExt8to32 y)) +(Mod8u x y) => (REMUW (ZeroExt8to32 x) (ZeroExt8to32 y)) (And64 ...) => (AND ...) (And32 ...) => (AND ...) @@ -98,25 +93,21 @@ (Sqrt ...) => (FSQRTD ...) -// Zero and sign extension -// Shift left until the bits we want are at the top of the register. -// Then logical/arithmetic shift right for zero/sign extend. -// We always extend to 64 bits; there's no reason not to, -// and optimization rules can then collapse some extensions. +// Sign and zero extension. -(SignExt8to16 <t> x) => (SRAI [56] (SLLI <t> [56] x)) -(SignExt8to32 <t> x) => (SRAI [56] (SLLI <t> [56] x)) -(SignExt8to64 <t> x) => (SRAI [56] (SLLI <t> [56] x)) -(SignExt16to32 <t> x) => (SRAI [48] (SLLI <t> [48] x)) -(SignExt16to64 <t> x) => (SRAI [48] (SLLI <t> [48] x)) -(SignExt32to64 <t> x) => (ADDIW [0] x) +(SignExt8to16 ...) => (MOVBreg ...) +(SignExt8to32 ...) => (MOVBreg ...) +(SignExt8to64 ...) => (MOVBreg ...) +(SignExt16to32 ...) => (MOVHreg ...) +(SignExt16to64 ...) => (MOVHreg ...) +(SignExt32to64 ...) => (MOVWreg ...) -(ZeroExt8to16 <t> x) => (SRLI [56] (SLLI <t> [56] x)) -(ZeroExt8to32 <t> x) => (SRLI [56] (SLLI <t> [56] x)) -(ZeroExt8to64 <t> x) => (SRLI [56] (SLLI <t> [56] x)) -(ZeroExt16to32 <t> x) => (SRLI [48] (SLLI <t> [48] x)) -(ZeroExt16to64 <t> x) => (SRLI [48] (SLLI <t> [48] x)) -(ZeroExt32to64 <t> x) => (SRLI [32] (SLLI <t> [32] x)) +(ZeroExt8to16 ...) => (MOVBUreg ...) +(ZeroExt8to32 ...) => (MOVBUreg ...) +(ZeroExt8to64 ...) => (MOVBUreg ...) +(ZeroExt16to32 ...) => (MOVHUreg ...) +(ZeroExt16to64 ...) => (MOVHUreg ...) +(ZeroExt32to64 ...) => (MOVWUreg ...) (Cvt32to32F ...) => (FCVTSW ...) (Cvt32to64F ...) => (FCVTDW ...) @@ -261,16 +252,16 @@ (EqPtr x y) => (SEQZ (SUB <x.Type> x y)) (Eq64 x y) => (SEQZ (SUB <x.Type> x y)) (Eq32 x y) => (SEQZ (SUBW <x.Type> x y)) -(Eq16 x y) => (SEQZ (ZeroExt16to64 (SUB <x.Type> x y))) -(Eq8 x y) => (SEQZ (ZeroExt8to64 (SUB <x.Type> x y))) +(Eq16 x y) => (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y))) +(Eq8 x y) => (SEQZ (SUB <x.Type> (ZeroExt8to64 x) (ZeroExt8to64 y))) (Eq64F ...) => (FEQD ...) (Eq32F ...) => (FEQS ...) (NeqPtr x y) => (SNEZ (SUB <x.Type> x y)) (Neq64 x y) => (SNEZ (SUB <x.Type> x y)) (Neq32 x y) => (SNEZ (SUBW <x.Type> x y)) -(Neq16 x y) => (SNEZ (ZeroExt16to64 (SUB <x.Type> x y))) -(Neq8 x y) => (SNEZ (ZeroExt8to64 (SUB <x.Type> x y))) +(Neq16 x y) => (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y))) +(Neq8 x y) => (SNEZ (SUB <x.Type> (ZeroExt8to64 x) (ZeroExt8to64 y))) (Neq64F ...) => (FNED ...) (Neq32F ...) => (FNES ...) @@ -291,42 +282,42 @@ (Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem) (Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem) (Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem) -(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVWstore ptr val mem) -(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVWstore ptr val mem) +(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem) // We need to fold MOVaddr into the LD/MOVDstore ops so that the live variable analysis // knows what variables are being read/written by the ops. (MOVBUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVBload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVHUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVHload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVWUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVWUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVWload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVDload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVBstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVHstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVWstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVDstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVBstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => - (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} base mem) @@ -360,13 +351,66 @@ // with OffPtr -> ADDI. (ADDI [c] (MOVaddr [d] {s} x)) && is32Bit(c+int64(d)) => (MOVaddr [int32(c)+d] {s} x) -// Zeroing -// TODO: more optimized zeroing, including attempting to use aligned accesses. -(Zero [0] _ mem) => mem -(Zero [1] ptr mem) => (MOVBstore ptr (MOVBconst) mem) -(Zero [2] ptr mem) => (MOVHstore ptr (MOVHconst) mem) -(Zero [4] ptr mem) => (MOVWstore ptr (MOVWconst) mem) -(Zero [8] ptr mem) => (MOVDstore ptr (MOVDconst) mem) +// Small zeroing +(Zero [0] _ mem) => mem +(Zero [1] ptr mem) => (MOVBstore ptr (MOVBconst [0]) mem) +(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 => + (MOVHstore ptr (MOVHconst [0]) mem) +(Zero [2] ptr mem) => + (MOVBstore [1] ptr (MOVBconst [0]) + (MOVBstore ptr (MOVBconst [0]) mem)) +(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 => + (MOVWstore ptr (MOVWconst [0]) mem) +(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 => + (MOVHstore [2] ptr (MOVHconst [0]) + (MOVHstore ptr (MOVHconst [0]) mem)) +(Zero [4] ptr mem) => + (MOVBstore [3] ptr (MOVBconst [0]) + (MOVBstore [2] ptr (MOVBconst [0]) + (MOVBstore [1] ptr (MOVBconst [0]) + (MOVBstore ptr (MOVBconst [0]) mem)))) +(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 => + (MOVDstore ptr (MOVDconst [0]) mem) +(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 => + (MOVWstore [4] ptr (MOVWconst [0]) + (MOVWstore ptr (MOVWconst [0]) mem)) +(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 => + (MOVHstore [6] ptr (MOVHconst [0]) + (MOVHstore [4] ptr (MOVHconst [0]) + (MOVHstore [2] ptr (MOVHconst [0]) + (MOVHstore ptr (MOVHconst [0]) mem)))) + +(Zero [3] ptr mem) => + (MOVBstore [2] ptr (MOVBconst [0]) + (MOVBstore [1] ptr (MOVBconst [0]) + (MOVBstore ptr (MOVBconst [0]) mem))) +(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 => + (MOVHstore [4] ptr (MOVHconst [0]) + (MOVHstore [2] ptr (MOVHconst [0]) + (MOVHstore ptr (MOVHconst [0]) mem))) +(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 => + (MOVWstore [8] ptr (MOVWconst [0]) + (MOVWstore [4] ptr (MOVWconst [0]) + (MOVWstore ptr (MOVWconst [0]) mem))) +(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 => + (MOVDstore [8] ptr (MOVDconst [0]) + (MOVDstore ptr (MOVDconst [0]) mem)) +(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 => + (MOVDstore [16] ptr (MOVDconst [0]) + (MOVDstore [8] ptr (MOVDconst [0]) + (MOVDstore ptr (MOVDconst [0]) mem))) +(Zero [32] {t} ptr mem) && t.Alignment()%8 == 0 => + (MOVDstore [24] ptr (MOVDconst [0]) + (MOVDstore [16] ptr (MOVDconst [0]) + (MOVDstore [8] ptr (MOVDconst [0]) + (MOVDstore ptr (MOVDconst [0]) mem)))) + +// Medium 8-aligned zeroing uses a Duff's device +// 8 and 128 are magic constants, see runtime/mkduff.go +(Zero [s] {t} ptr mem) + && s%8 == 0 && s <= 8*128 + && t.Alignment()%8 == 0 && !config.noDuffDevice => + (DUFFZERO [8 * (128 - s/8)] ptr mem) // Generic zeroing uses a loop (Zero [s] {t} ptr mem) => @@ -378,7 +422,7 @@ (Convert ...) => (MOVconvert ...) // Checks -(IsNonNil p) => (NeqPtr (MOVDconst) p) +(IsNonNil p) => (NeqPtr (MOVDconst [0]) p) (IsInBounds ...) => (Less64U ...) (IsSliceInBounds ...) => (Leq64U ...) @@ -395,13 +439,66 @@ (PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem) (PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem) -// Moves -// TODO: more optimized moves, including attempting to use aligned accesses. -(Move [0] _ _ mem) => mem +// Small moves +(Move [0] _ _ mem) => mem (Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem) -(Move [2] dst src mem) => (MOVHstore dst (MOVHload src mem) mem) -(Move [4] dst src mem) => (MOVWstore dst (MOVWload src mem) mem) -(Move [8] dst src mem) => (MOVDstore dst (MOVDload src mem) mem) +(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 => + (MOVHstore dst (MOVHload src mem) mem) +(Move [2] dst src mem) => + (MOVBstore [1] dst (MOVBload [1] src mem) + (MOVBstore dst (MOVBload src mem) mem)) +(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 => + (MOVWstore dst (MOVWload src mem) mem) +(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 => + (MOVHstore [2] dst (MOVHload [2] src mem) + (MOVHstore dst (MOVHload src mem) mem)) +(Move [4] dst src mem) => + (MOVBstore [3] dst (MOVBload [3] src mem) + (MOVBstore [2] dst (MOVBload [2] src mem) + (MOVBstore [1] dst (MOVBload [1] src mem) + (MOVBstore dst (MOVBload src mem) mem)))) +(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 => + (MOVDstore dst (MOVDload src mem) mem) +(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 => + (MOVWstore [4] dst (MOVWload [4] src mem) + (MOVWstore dst (MOVWload src mem) mem)) +(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 => + (MOVHstore [6] dst (MOVHload [6] src mem) + (MOVHstore [4] dst (MOVHload [4] src mem) + (MOVHstore [2] dst (MOVHload [2] src mem) + (MOVHstore dst (MOVHload src mem) mem)))) + +(Move [3] dst src mem) => + (MOVBstore [2] dst (MOVBload [2] src mem) + (MOVBstore [1] dst (MOVBload [1] src mem) + (MOVBstore dst (MOVBload src mem) mem))) +(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 => + (MOVHstore [4] dst (MOVHload [4] src mem) + (MOVHstore [2] dst (MOVHload [2] src mem) + (MOVHstore dst (MOVHload src mem) mem))) +(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 => + (MOVWstore [8] dst (MOVWload [8] src mem) + (MOVWstore [4] dst (MOVWload [4] src mem) + (MOVWstore dst (MOVWload src mem) mem))) +(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 => + (MOVDstore [8] dst (MOVDload [8] src mem) + (MOVDstore dst (MOVDload src mem) mem)) +(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 => + (MOVDstore [16] dst (MOVDload [16] src mem) + (MOVDstore [8] dst (MOVDload [8] src mem) + (MOVDstore dst (MOVDload src mem) mem))) +(Move [32] {t} dst src mem) && t.Alignment()%8 == 0 => + (MOVDstore [24] dst (MOVDload [24] src mem) + (MOVDstore [16] dst (MOVDload [16] src mem) + (MOVDstore [8] dst (MOVDload [8] src mem) + (MOVDstore dst (MOVDload src mem) mem)))) + +// Medium 8-aligned move uses a Duff's device +// 16 and 128 are magic constants, see runtime/mkduff.go +(Move [s] {t} dst src mem) + && s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0 + && !config.noDuffDevice && logLargeCopy(v, s) => + (DUFFCOPY [16 * (128 - s/8)] dst src mem) // Generic move uses a loop (Move [s] {t} dst src mem) && (s <= 16 || logLargeCopy(v, s)) => @@ -424,6 +521,8 @@ (OffPtr [off] ptr) && is32Bit(off) => (ADDI [off] ptr) (OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr) +// TODO(jsing): Check if we actually need MOV{B,H,W}const as most platforms +// use a single MOVDconst op. (Const8 ...) => (MOVBconst ...) (Const16 ...) => (MOVHconst ...) (Const32 ...) => (MOVWconst ...) @@ -501,6 +600,79 @@ (MOVWstore [off] {sym} ptr (MOVWconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem) (MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem) +// Avoid sign/zero extension for consts. +(MOVBreg (MOVBconst [c])) => (MOVDconst [int64(c)]) +(MOVHreg (MOVBconst [c])) => (MOVDconst [int64(c)]) +(MOVHreg (MOVHconst [c])) => (MOVDconst [int64(c)]) +(MOVWreg (MOVBconst [c])) => (MOVDconst [int64(c)]) +(MOVWreg (MOVHconst [c])) => (MOVDconst [int64(c)]) +(MOVWreg (MOVWconst [c])) => (MOVDconst [int64(c)]) +(MOVBUreg (MOVBconst [c])) => (MOVDconst [int64(uint8(c))]) +(MOVHUreg (MOVBconst [c])) => (MOVDconst [int64(uint16(c))]) +(MOVHUreg (MOVHconst [c])) => (MOVDconst [int64(uint16(c))]) +(MOVWUreg (MOVBconst [c])) => (MOVDconst [int64(uint32(c))]) +(MOVWUreg (MOVHconst [c])) => (MOVDconst [int64(uint32(c))]) +(MOVWUreg (MOVWconst [c])) => (MOVDconst [int64(uint32(c))]) + +// Avoid sign/zero extension after properly typed load. +(MOVBreg x:(MOVBload _ _)) => (MOVDreg x) +(MOVHreg x:(MOVBload _ _)) => (MOVDreg x) +(MOVHreg x:(MOVBUload _ _)) => (MOVDreg x) +(MOVHreg x:(MOVHload _ _)) => (MOVDreg x) +(MOVWreg x:(MOVBload _ _)) => (MOVDreg x) +(MOVWreg x:(MOVBUload _ _)) => (MOVDreg x) +(MOVWreg x:(MOVHload _ _)) => (MOVDreg x) +(MOVWreg x:(MOVHUload _ _)) => (MOVDreg x) +(MOVWreg x:(MOVWload _ _)) => (MOVDreg x) +(MOVBUreg x:(MOVBUload _ _)) => (MOVDreg x) +(MOVHUreg x:(MOVBUload _ _)) => (MOVDreg x) +(MOVHUreg x:(MOVHUload _ _)) => (MOVDreg x) +(MOVWUreg x:(MOVBUload _ _)) => (MOVDreg x) +(MOVWUreg x:(MOVHUload _ _)) => (MOVDreg x) +(MOVWUreg x:(MOVWUload _ _)) => (MOVDreg x) + +// Fold double extensions. +(MOVBreg x:(MOVBreg _)) => (MOVDreg x) +(MOVHreg x:(MOVBreg _)) => (MOVDreg x) +(MOVHreg x:(MOVBUreg _)) => (MOVDreg x) +(MOVHreg x:(MOVHreg _)) => (MOVDreg x) +(MOVWreg x:(MOVBreg _)) => (MOVDreg x) +(MOVWreg x:(MOVBUreg _)) => (MOVDreg x) +(MOVWreg x:(MOVHreg _)) => (MOVDreg x) +(MOVWreg x:(MOVWreg _)) => (MOVDreg x) +(MOVBUreg x:(MOVBUreg _)) => (MOVDreg x) +(MOVHUreg x:(MOVBUreg _)) => (MOVDreg x) +(MOVHUreg x:(MOVHUreg _)) => (MOVDreg x) +(MOVWUreg x:(MOVBUreg _)) => (MOVDreg x) +(MOVWUreg x:(MOVHUreg _)) => (MOVDreg x) +(MOVWUreg x:(MOVWUreg _)) => (MOVDreg x) + +// Do not extend before store. +(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem) +(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem) +(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem) +(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem) + +// Replace extend after load with alternate load where possible. +(MOVBreg <t> x:(MOVBUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <t> [off] {sym} ptr mem) +(MOVHreg <t> x:(MOVHUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHload <t> [off] {sym} ptr mem) +(MOVWreg <t> x:(MOVWUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <t> [off] {sym} ptr mem) +(MOVBUreg <t> x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBUload <t> [off] {sym} ptr mem) +(MOVHUreg <t> x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHUload <t> [off] {sym} ptr mem) +(MOVWUreg <t> x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWUload <t> [off] {sym} ptr mem) + +// If a register move has only 1 use, just use the same register without emitting instruction +// MOVnop does not emit an instruction, only for ensuring the type. +(MOVDreg x) && x.Uses == 1 => (MOVDnop x) + // Fold constant into immediate instructions where possible. (ADD (MOVBconst [val]) x) => (ADDI [int64(val)] x) (ADD (MOVHconst [val]) x) => (ADDI [int64(val)] x) diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go index 8ab4abe04a..f64319230b 100644 --- a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go @@ -24,10 +24,11 @@ import ( // L = 64 bit int, used when the opcode starts with F const ( - riscv64REG_G = 4 + riscv64REG_G = 27 riscv64REG_CTXT = 20 riscv64REG_LR = 1 riscv64REG_SP = 2 + riscv64REG_TP = 4 riscv64REG_TMP = 31 riscv64REG_ZERO = 0 ) @@ -78,8 +79,8 @@ func init() { // Add general purpose registers to gpMask. switch r { - // ZERO, and TMP are not in any gp mask. - case riscv64REG_ZERO, riscv64REG_TMP: + // ZERO, TP and TMP are not in any gp mask. + case riscv64REG_ZERO, riscv64REG_TP, riscv64REG_TMP: case riscv64REG_G: gpgMask |= mask gpspsbgMask |= mask @@ -192,6 +193,17 @@ func init() { {name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 32 bits {name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 64 bits + // Conversions + {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"}, // move from arg0, sign-extended from byte + {name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"}, // move from arg0, sign-extended from half + {name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"}, // move from arg0, sign-extended from word + {name: "MOVDreg", argLength: 1, reg: gp11, asm: "MOV"}, // move from arg0 + {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte + {name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half + {name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word + + {name: "MOVDnop", argLength: 1, reg: regInfo{inputs: []regMask{gpMask}, outputs: []regMask{gpMask}}, resultInArg0: true}, // nop, return arg0 in same register + // Shift ops {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << (aux1 & 63) {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> (aux1 & 63), signed @@ -224,9 +236,47 @@ func init() { {name: "MOVconvert", argLength: 2, reg: gp11, asm: "MOV"}, // arg0, but converted to int/ptr as appropriate; arg1=mem // Calls - {name: "CALLstatic", argLength: 1, reg: call, aux: "SymOff", call: true, symEffect: "None"}, // call static function aux.(*gc.Sym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: callClosure, aux: "Int64", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: callInter, aux: "Int64", call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: call, aux: "CallOff", call: true}, // call static function aux.(*gc.Sym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: callClosure, aux: "CallOff", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: callInter, aux: "CallOff", call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + + // duffzero + // arg0 = address of memory to zero (in X10, changed as side effect) + // arg1 = mem + // auxint = offset into duffzero code to start executing + // X1 (link register) changed because of function call + // returns mem + { + name: "DUFFZERO", + aux: "Int64", + argLength: 2, + reg: regInfo{ + inputs: []regMask{regNamed["X10"]}, + clobbers: regNamed["X1"] | regNamed["X10"], + }, + typ: "Mem", + faultOnNilArg0: true, + }, + + // duffcopy + // arg0 = address of dst memory (in X11, changed as side effect) + // arg1 = address of src memory (in X10, changed as side effect) + // arg2 = mem + // auxint = offset into duffcopy code to start executing + // X1 (link register) changed because of function call + // returns mem + { + name: "DUFFCOPY", + aux: "Int64", + argLength: 3, + reg: regInfo{ + inputs: []regMask{regNamed["X11"], regNamed["X10"]}, + clobbers: regNamed["X1"] | regNamed["X10"] | regNamed["X11"], + }, + typ: "Mem", + faultOnNilArg0: true, + faultOnNilArg1: true, + }, // Generic moves and zeros diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules index e564f638d3..39949edbc2 100644 --- a/src/cmd/compile/internal/ssa/gen/S390X.rules +++ b/src/cmd/compile/internal/ssa/gen/S390X.rules @@ -198,6 +198,9 @@ (RXSBG <typ.UInt32> {s390x.NewRotateParams(59, 60, 3)} (MOVDconst [3<<3]) ptr)) mem) +(AtomicAnd32 ...) => (LAN ...) +(AtomicOr32 ...) => (LAO ...) + // Lowering extension // Note: we always extend to 64 bits even though some ops don't need that many result bits. (SignExt8to(16|32|64) ...) => (MOVBreg ...) @@ -640,8 +643,18 @@ // equivalent to the leftmost 32 bits being set. // TODO(mundaym): modify the assembler to accept 64-bit values // and use isU32Bit(^c). -(AND x (MOVDconst [c])) && is32Bit(c) && c < 0 => (ANDconst [c] x) -(AND x (MOVDconst [c])) && is32Bit(c) && c >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x)) +(AND x (MOVDconst [c])) + && s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c)) != nil + => (RISBGZ x {*s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c))}) +(AND x (MOVDconst [c])) + && is32Bit(c) + && c < 0 + => (ANDconst [c] x) +(AND x (MOVDconst [c])) + && is32Bit(c) + && c >= 0 + => (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x)) + (ANDW x (MOVDconst [c])) => (ANDWconst [int32(c)] x) ((AND|ANDW)const [c] ((AND|ANDW)const [d] x)) => ((AND|ANDW)const [c&d] x) @@ -650,14 +663,20 @@ ((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x) // Constant shifts. -(S(LD|RD|RAD|LW|RW|RAW) x (MOVDconst [c])) - => (S(LD|RD|RAD|LW|RW|RAW)const x [int8(c&63)]) +(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [int8(c&63)]) +(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [int8(c&31)]) +(S(LW|RW) _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0]) +(SRAW x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31]) // Shifts only use the rightmost 6 bits of the shift value. +(S(LD|RD|RAD|LW|RW|RAW) x (RISBGZ y {r})) + && r.Amount == 0 + && r.OutMask()&63 == 63 + => (S(LD|RD|RAD|LW|RW|RAW) x y) (S(LD|RD|RAD|LW|RW|RAW) x (AND (MOVDconst [c]) y)) - => (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [int32(c&63)] y)) + => (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [int32(c&63)] y)) (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c] y)) && c&63 == 63 - => (S(LD|RD|RAD|LW|RW|RAW) x y) + => (S(LD|RD|RAD|LW|RW|RAW) x y) (SLD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLD x y) (SRD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRD x y) (SRAD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAD x y) @@ -665,17 +684,13 @@ (SRW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRW x y) (SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y) -// Constant rotate generation -(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)]) -(RLLG x (MOVDconst [c])) => (RLLGconst x [int8(c&63)]) +// Match rotate by constant. +(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))}) +(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)]) -(ADD (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (RLLGconst [c] x) -( OR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (RLLGconst [c] x) -(XOR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (RLLGconst [c] x) - -(ADDW (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (RLLconst [c] x) -( ORW (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (RLLconst [c] x) -(XORW (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (RLLconst [c] x) +// Match rotate by constant pattern. +((ADD|OR|XOR) (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)}) +((ADD|OR|XOR)W (SLWconst x [c]) (SRWconst x [32-c])) => (RLLconst x [c]) // Signed 64-bit comparison with immediate. (CMP x (MOVDconst [c])) && is32Bit(c) => (CMPconst x [int32(c)]) @@ -689,15 +704,97 @@ (CMP(W|WU) x (MOVDconst [c])) => (CMP(W|WU)const x [int32(c)]) (CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)])) +// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'. +(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)}) + +// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'. +(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)}) + +// Absorb input zero extension into 'rotate then insert selected bits [into zero]'. +(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)}) +(RISBGZ (MOVHZreg x) {r}) && r.InMerge(0x0000ffff) != nil => (RISBGZ x {*r.InMerge(0x0000ffff)}) +(RISBGZ (MOVBZreg x) {r}) && r.InMerge(0x000000ff) != nil => (RISBGZ x {*r.InMerge(0x000000ff)}) + +// Absorb 'rotate then insert selected bits [into zero]' into zero extension. +(MOVWZreg (RISBGZ x {r})) && r.OutMerge(0xffffffff) != nil => (RISBGZ x {*r.OutMerge(0xffffffff)}) +(MOVHZreg (RISBGZ x {r})) && r.OutMerge(0x0000ffff) != nil => (RISBGZ x {*r.OutMerge(0x0000ffff)}) +(MOVBZreg (RISBGZ x {r})) && r.OutMerge(0x000000ff) != nil => (RISBGZ x {*r.OutMerge(0x000000ff)}) + +// Absorb shift into 'rotate then insert selected bits [into zero]'. +// +// Any unsigned shift can be represented as a rotate and mask operation: +// +// x << c => RotateLeft64(x, c) & (^uint64(0) << c) +// x >> c => RotateLeft64(x, -c) & (^uint64(0) >> c) +// +// Therefore when a shift is used as the input to a rotate then insert +// selected bits instruction we can merge the two together. We just have +// to be careful that the resultant mask is representable (non-zero and +// contiguous). For example, assuming that x is variable and c, y and m +// are constants, a shift followed by a rotate then insert selected bits +// could be represented as: +// +// RotateLeft64(RotateLeft64(x, c) & (^uint64(0) << c), y) & m +// +// We can split the rotation by y into two, one rotate for x and one for +// the mask: +// +// RotateLeft64(RotateLeft64(x, c), y) & (RotateLeft64(^uint64(0) << c, y)) & m +// +// The rotations of x by c followed by y can then be combined: +// +// RotateLeft64(x, c+y) & (RotateLeft64(^uint64(0) << c, y)) & m +// ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// rotate mask +// +// To perform this optimization we therefore just need to check that it +// is valid to merge the shift mask (^(uint64(0)<<c)) into the selected +// bits mask (i.e. that the resultant mask is non-zero and contiguous). +// +(RISBGZ (SLDconst x [c]) {r}) && r.InMerge(^uint64(0)<<c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)<<c)).RotateLeft(c)}) +(RISBGZ (SRDconst x [c]) {r}) && r.InMerge(^uint64(0)>>c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)>>c)).RotateLeft(-c)}) + +// Absorb 'rotate then insert selected bits [into zero]' into left shift. +(SLDconst (RISBGZ x {r}) [c]) + && s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil + => (RISBGZ x {(*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)}) + +// Absorb 'rotate then insert selected bits [into zero]' into right shift. +(SRDconst (RISBGZ x {r}) [c]) + && s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil + => (RISBGZ x {(*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)}) + +// Merge 'rotate then insert selected bits [into zero]' instructions together. +(RISBGZ (RISBGZ x {y}) {z}) + && z.InMerge(y.OutMask()) != nil + => (RISBGZ x {(*z.InMerge(y.OutMask())).RotateLeft(y.Amount)}) + +// Convert RISBGZ into 64-bit shift (helps CSE). +(RISBGZ x {r}) && r.End == 63 && r.Start == -r.Amount&63 => (SRDconst x [-r.Amount&63]) +(RISBGZ x {r}) && r.Start == 0 && r.End == 63-r.Amount => (SLDconst x [r.Amount]) + +// Optimize single bit isolation when it is known to be equivalent to +// the most significant bit due to mask produced by arithmetic shift. +// Simply isolate the most significant bit itself and place it in the +// correct position. +// +// Example: (int64(x) >> 63) & 0x8 -> RISBGZ $60, $60, $4, Rsrc, Rdst +(RISBGZ (SRADconst x [c]) {r}) + && r.Start == r.End // single bit selected + && (r.Start+r.Amount)&63 <= c // equivalent to most significant bit of x + => (RISBGZ x {s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)}) + // Canonicalize the order of arguments to comparisons - helps with CSE. ((CMP|CMPW|CMPU|CMPWU) x y) && x.ID > y.ID => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x)) -// Using MOV{W,H,B}Zreg instead of AND is cheaper. -(AND x (MOVDconst [0xFF])) => (MOVBZreg x) -(AND x (MOVDconst [0xFFFF])) => (MOVHZreg x) -(AND x (MOVDconst [0xFFFFFFFF])) => (MOVWZreg x) -(ANDWconst [0xFF] x) => (MOVBZreg x) -(ANDWconst [0xFFFF] x) => (MOVHZreg x) +// Use sign/zero extend instead of RISBGZ. +(RISBGZ x {r}) && r == s390x.NewRotateParams(56, 63, 0) => (MOVBZreg x) +(RISBGZ x {r}) && r == s390x.NewRotateParams(48, 63, 0) => (MOVHZreg x) +(RISBGZ x {r}) && r == s390x.NewRotateParams(32, 63, 0) => (MOVWZreg x) + +// Use sign/zero extend instead of ANDW. +(ANDWconst [0x00ff] x) => (MOVBZreg x) +(ANDWconst [0xffff] x) => (MOVHZreg x) // Strength reduce multiplication to the sum (or difference) of two powers of two. // @@ -770,21 +867,22 @@ // detect attempts to set/clear the sign bit // may need to be reworked when NIHH/OIHH are added -(SRDconst [1] (SLDconst [1] (LGDR <t> x))) => (LGDR <t> (LPDFR <x.Type> x)) -(LDGR <t> (SRDconst [1] (SLDconst [1] x))) => (LPDFR (LDGR <t> x)) -(AND (MOVDconst [^(-1<<63)]) (LGDR <t> x)) => (LGDR <t> (LPDFR <x.Type> x)) -(LDGR <t> (AND (MOVDconst [^(-1<<63)]) x)) => (LPDFR (LDGR <t> x)) -(OR (MOVDconst [-1<<63]) (LGDR <t> x)) => (LGDR <t> (LNDFR <x.Type> x)) -(LDGR <t> (OR (MOVDconst [-1<<63]) x)) => (LNDFR (LDGR <t> x)) +(RISBGZ (LGDR <t> x) {r}) && r == s390x.NewRotateParams(1, 63, 0) => (LGDR <t> (LPDFR <x.Type> x)) +(LDGR <t> (RISBGZ x {r})) && r == s390x.NewRotateParams(1, 63, 0) => (LPDFR (LDGR <t> x)) +(OR (MOVDconst [-1<<63]) (LGDR <t> x)) => (LGDR <t> (LNDFR <x.Type> x)) +(LDGR <t> (OR (MOVDconst [-1<<63]) x)) => (LNDFR (LDGR <t> x)) // detect attempts to set the sign bit with load (LDGR <t> x:(ORload <t1> [off] {sym} (MOVDconst [-1<<63]) ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (LNDFR <t> (LDGR <t> (MOVDload <t1> [off] {sym} ptr mem))) // detect copysign -(OR (SLDconst [63] (SRDconst [63] (LGDR x))) (LGDR (LPDFR <t> y))) => (LGDR (CPSDR <t> y x)) -(OR (SLDconst [63] (SRDconst [63] (LGDR x))) (MOVDconst [c])) && c & -1<<63 == 0 => (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x)) -(OR (AND (MOVDconst [-1<<63]) (LGDR x)) (LGDR (LPDFR <t> y))) => (LGDR (CPSDR <t> y x)) -(OR (AND (MOVDconst [-1<<63]) (LGDR x)) (MOVDconst [c])) && c & -1<<63 == 0 => (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x)) +(OR (RISBGZ (LGDR x) {r}) (LGDR (LPDFR <t> y))) + && r == s390x.NewRotateParams(0, 0, 0) + => (LGDR (CPSDR <t> y x)) +(OR (RISBGZ (LGDR x) {r}) (MOVDconst [c])) + && c >= 0 + && r == s390x.NewRotateParams(0, 0, 0) + => (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x)) (CPSDR y (FMOVDconst [c])) && !math.Signbit(c) => (LPDFR y) (CPSDR y (FMOVDconst [c])) && math.Signbit(c) => (LNDFR y) @@ -871,67 +969,67 @@ // loads/stores using PC-relative addressing directly must be aligned to the // size of the target. (MOVDload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) => - (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVWZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) => - (MOVWZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVHZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) => - (MOVHZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} base mem) (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem) (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVWload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) => - (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVHload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) => - (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) (MOVDstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) => - (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVWstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) => - (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVHstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) => - (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => - (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) -(ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(ADDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(SUBload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(SUBWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) +(ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(ADDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(SUBload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(SUBWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) -(ANDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(ANDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(ORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(ORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(XORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) -(XORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) +(ANDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(ANDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(ORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(ORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(XORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORload [o1+o2] {mergeSym(s1, s2)} x ptr mem) +(XORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) // Cannot store constant to SB directly (no 'move relative long immediate' instructions). (MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) => - (MOVDstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + (MOVDstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) (MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) => - (MOVWstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + (MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) (MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) => - (MOVHstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + (MOVHstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) (MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) => - (MOVBstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + (MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) // MOVDaddr into MOVDaddridx (MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB => - (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y) (MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB => - (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y) // Absorb InvertFlags into branches. (BRC {c} (InvertFlags cmp) yes no) => (BRC {c.ReverseComparison()} cmp yes no) @@ -963,6 +1061,9 @@ (CMPWconst (ANDWconst _ [m]) [n]) && int32(m) >= 0 && int32(m) < int32(n) => (FlagLT) (CMPWUconst (ANDWconst _ [m]) [n]) && uint32(m) < uint32(n) => (FlagLT) +(CMPconst (RISBGZ x {r}) [c]) && c > 0 && r.OutMask() < uint64(c) => (FlagLT) +(CMPUconst (RISBGZ x {r}) [c]) && r.OutMask() < uint64(uint32(c)) => (FlagLT) + // Constant compare-and-branch with immediate. (CGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal != 0 && int64(x) == int64(y) => (First yes no) (CGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less != 0 && int64(x) < int64(y) => (First yes no) diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go index 710beaddbb..f0cf2f2f6e 100644 --- a/src/cmd/compile/internal/ssa/gen/S390XOps.go +++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go @@ -331,25 +331,26 @@ func init() { {name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32 {name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64 - {name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 32 + {name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64 {name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int8"}, // arg0 << auxint, shift amount 0-63 {name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31 {name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64 - {name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 32 + {name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64 {name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-63 {name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31 // Arithmetic shifts clobber flags. {name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64 - {name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 32 + {name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64 {name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63 {name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31 - {name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63 - {name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31 - {name: "RLLGconst", argLength: 1, reg: gp11, asm: "RLLG", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-63 - {name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-31 + // Rotate instructions. + // Note: no RLLGconst - use RISBGZ instead. + {name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63 + {name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31 + {name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-31 // Rotate then (and|or|xor|insert) selected bits instructions. // @@ -371,6 +372,7 @@ func init() { // +-------------+-------+-----+--------+-----------------------+-----------------------+-----------------------+ // {name: "RXSBG", argLength: 2, reg: gp21, asm: "RXSBG", resultInArg0: true, aux: "S390XRotateParams", clobberFlags: true}, // rotate then xor selected bits + {name: "RISBGZ", argLength: 1, reg: gp11, asm: "RISBGZ", aux: "S390XRotateParams", clobberFlags: true}, // rotate then insert selected bits [into zero] // unary ops {name: "NEG", argLength: 1, reg: gp11, asm: "NEG", clobberFlags: true}, // -arg0 @@ -475,9 +477,9 @@ func init() { {name: "CLEAR", argLength: 2, reg: regInfo{inputs: []regMask{ptr, 0}}, asm: "CLEAR", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"}, - {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{ptrsp, buildReg("R12"), 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{ptr}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{ptrsp, buildReg("R12"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{ptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem // (InvertFlags (CMP a b)) == (CMP b a) // InvertFlags is a pseudo-op which can't appear in assembly output. @@ -547,8 +549,10 @@ func init() { // Atomic bitwise operations. // Note: 'floor' operations round the pointer down to the nearest word boundary // which reflects how they are used in the runtime. - {name: "LAOfloor", argLength: 3, reg: gpstorelab, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) |= arg1. arg2 = mem. + {name: "LAN", argLength: 3, reg: gpstore, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *arg0 &= arg1. arg2 = mem. {name: "LANfloor", argLength: 3, reg: gpstorelab, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) &= arg1. arg2 = mem. + {name: "LAO", argLength: 3, reg: gpstore, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *arg0 |= arg1. arg2 = mem. + {name: "LAOfloor", argLength: 3, reg: gpstorelab, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) |= arg1. arg2 = mem. // Compare and swap. // arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. diff --git a/src/cmd/compile/internal/ssa/gen/Wasm.rules b/src/cmd/compile/internal/ssa/gen/Wasm.rules index ea12c5d617..fc45cd3ed5 100644 --- a/src/cmd/compile/internal/ssa/gen/Wasm.rules +++ b/src/cmd/compile/internal/ssa/gen/Wasm.rules @@ -399,6 +399,7 @@ // folding offset into address (I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) => (LoweredAddr {sym} [int32(off)+off2] base) +(I64AddConst [off] x:(SP)) && isU32Bit(off) => (LoweredAddr [int32(off)] x) // so it is rematerializeable // transforming readonly globals into constants (I64Load [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read64(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))]) diff --git a/src/cmd/compile/internal/ssa/gen/WasmOps.go b/src/cmd/compile/internal/ssa/gen/WasmOps.go index e43eae17e9..36c53bc78c 100644 --- a/src/cmd/compile/internal/ssa/gen/WasmOps.go +++ b/src/cmd/compile/internal/ssa/gen/WasmOps.go @@ -122,9 +122,9 @@ func init() { ) var WasmOps = []opData{ - {name: "LoweredStaticCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem - {name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "Int64", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem - {name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem + {name: "LoweredStaticCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem + {name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "CallOff", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem + {name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem {name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // returns base+aux+auxint, arg0=base {name: "LoweredMove", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Int64"}, // large move. arg0=dst, arg1=src, arg2=mem, auxint=len/8, returns mem @@ -137,7 +137,7 @@ func init() { {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Sym", symEffect: "None"}, // invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier // LoweredConvert converts between pointers and integers. - // We have a special op for this so as to not confuse GC + // We have a special op for this so as to not confuse GCCallOff // (particularly stack maps). It takes a memory arg so it // gets correctly ordered with respect to GC safepoints. // arg0=ptr/int arg1=mem, output=int/ptr diff --git a/src/cmd/compile/internal/ssa/gen/dec64.rules b/src/cmd/compile/internal/ssa/gen/dec64.rules index 4f9e863f90..9297ed8d2e 100644 --- a/src/cmd/compile/internal/ssa/gen/dec64.rules +++ b/src/cmd/compile/internal/ssa/gen/dec64.rules @@ -9,7 +9,6 @@ (Int64Hi (Int64Make hi _)) => hi (Int64Lo (Int64Make _ lo)) => lo - (Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && t.IsSigned() => (Int64Make (Load <typ.Int32> (OffPtr <typ.Int32Ptr> [4] ptr) mem) @@ -42,20 +41,21 @@ lo (Store {hi.Type} dst hi mem)) -(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() => +// These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat +(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") => (Int64Make (Arg <typ.Int32> {n} [off+4]) (Arg <typ.UInt32> {n} [off])) -(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() => +(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") => (Int64Make (Arg <typ.UInt32> {n} [off+4]) (Arg <typ.UInt32> {n} [off])) -(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() => +(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") => (Int64Make (Arg <typ.Int32> {n} [off]) (Arg <typ.UInt32> {n} [off+4])) -(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() => +(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") => (Int64Make (Arg <typ.UInt32> {n} [off]) (Arg <typ.UInt32> {n} [off+4])) @@ -143,6 +143,10 @@ (Trunc64to32 (Int64Make _ lo)) => lo (Trunc64to16 (Int64Make _ lo)) => (Trunc32to16 lo) (Trunc64to8 (Int64Make _ lo)) => (Trunc32to8 lo) +// Most general +(Trunc64to32 x) => (Int64Lo x) +(Trunc64to16 x) => (Trunc32to16 (Int64Lo x)) +(Trunc64to8 x) => (Trunc32to8 (Int64Lo x)) (Lsh32x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0]) (Rsh32x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask x) @@ -175,156 +179,174 @@ // turn x64 non-constant shifts to x32 shifts // if high 32-bit of the shift is nonzero, make a huge shift (Lsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh64Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Lsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh32Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Lsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh16Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Lsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) (Rsh8Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 => - (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo)) + +// Most general +(Lsh64x64 x y) => (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh64x64 x y) => (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh64Ux64 x y) => (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Lsh32x64 x y) => (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh32x64 x y) => (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh32Ux64 x y) => (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Lsh16x64 x y) => (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh16x64 x y) => (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh16Ux64 x y) => (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Lsh8x64 x y) => (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh8x64 x y) => (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) +(Rsh8Ux64 x y) => (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + +// Clean up constants a little +(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c == 0 => y +(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c != 0 => (Const32 <typ.UInt32> [-1]) // 64x left shift // result.hi = hi<<s | lo>>(32-s) | lo<<(s-32) // >> is unsigned, large shifts result 0 // result.lo = lo<<s -(Lsh64x32 (Int64Make hi lo) s) => +(Lsh64x32 x s) => (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Lsh32x32 <typ.UInt32> hi s) + (Lsh32x32 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux32 <typ.UInt32> - lo + (Int64Lo x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Lsh32x32 <typ.UInt32> - lo + (Int64Lo x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))) - (Lsh32x32 <typ.UInt32> lo s)) -(Lsh64x16 (Int64Make hi lo) s) => + (Lsh32x32 <typ.UInt32> (Int64Lo x) s)) +(Lsh64x16 x s) => (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Lsh32x16 <typ.UInt32> hi s) + (Lsh32x16 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux16 <typ.UInt32> - lo + (Int64Lo x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Lsh32x16 <typ.UInt32> - lo + (Int64Lo x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))) - (Lsh32x16 <typ.UInt32> lo s)) -(Lsh64x8 (Int64Make hi lo) s) => + (Lsh32x16 <typ.UInt32> (Int64Lo x) s)) +(Lsh64x8 x s) => (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Lsh32x8 <typ.UInt32> hi s) + (Lsh32x8 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux8 <typ.UInt32> - lo + (Int64Lo x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Lsh32x8 <typ.UInt32> - lo + (Int64Lo x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))) - (Lsh32x8 <typ.UInt32> lo s)) + (Lsh32x8 <typ.UInt32> (Int64Lo x) s)) // 64x unsigned right shift // result.hi = hi>>s // result.lo = lo>>s | hi<<(32-s) | hi>>(s-32) // >> is unsigned, large shifts result 0 -(Rsh64Ux32 (Int64Make hi lo) s) => +(Rsh64Ux32 x s) => (Int64Make - (Rsh32Ux32 <typ.UInt32> hi s) + (Rsh32Ux32 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux32 <typ.UInt32> lo s) + (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s) (Lsh32x32 <typ.UInt32> - hi + (Int64Hi x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Rsh32Ux32 <typ.UInt32> - hi + (Int64Hi x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))) -(Rsh64Ux16 (Int64Make hi lo) s) => +(Rsh64Ux16 x s) => (Int64Make - (Rsh32Ux16 <typ.UInt32> hi s) + (Rsh32Ux16 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux16 <typ.UInt32> lo s) + (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s) (Lsh32x16 <typ.UInt32> - hi + (Int64Hi x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Rsh32Ux16 <typ.UInt32> - hi + (Int64Hi x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))) -(Rsh64Ux8 (Int64Make hi lo) s) => +(Rsh64Ux8 x s) => (Int64Make - (Rsh32Ux8 <typ.UInt32> hi s) + (Rsh32Ux8 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux8 <typ.UInt32> lo s) + (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s) (Lsh32x8 <typ.UInt32> - hi + (Int64Hi x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Rsh32Ux8 <typ.UInt32> - hi + (Int64Hi x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))) // 64x signed right shift // result.hi = hi>>s // result.lo = lo>>s | hi<<(32-s) | (hi>>(s-32))&zeromask(s>>5) // hi>>(s-32) is signed, large shifts result 0/-1 -(Rsh64x32 (Int64Make hi lo) s) => +(Rsh64x32 x s) => (Int64Make - (Rsh32x32 <typ.UInt32> hi s) + (Rsh32x32 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux32 <typ.UInt32> lo s) + (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s) (Lsh32x32 <typ.UInt32> - hi + (Int64Hi x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (And32 <typ.UInt32> (Rsh32x32 <typ.UInt32> - hi + (Int64Hi x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))) (Zeromask (Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5])))))) -(Rsh64x16 (Int64Make hi lo) s) => +(Rsh64x16 x s) => (Int64Make - (Rsh32x16 <typ.UInt32> hi s) + (Rsh32x16 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux16 <typ.UInt32> lo s) + (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s) (Lsh32x16 <typ.UInt32> - hi + (Int64Hi x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (And32 <typ.UInt32> (Rsh32x16 <typ.UInt32> - hi + (Int64Hi x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))) (Zeromask (ZeroExt16to32 (Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5]))))))) -(Rsh64x8 (Int64Make hi lo) s) => +(Rsh64x8 x s) => (Int64Make - (Rsh32x8 <typ.UInt32> hi s) + (Rsh32x8 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> - (Rsh32Ux8 <typ.UInt32> lo s) + (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s) (Lsh32x8 <typ.UInt32> - hi + (Int64Hi x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (And32 <typ.UInt32> (Rsh32x8 <typ.UInt32> - hi + (Int64Hi x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))) (Zeromask (ZeroExt8to32 diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index f7e6bbebac..81568b7b7a 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -1040,6 +1040,46 @@ (ZeroExt32to64 x))) (Const64 <typ.UInt64> [32+umagic32(c).s-1]))) +// For unsigned 64-bit divides on 32-bit machines, +// if the constant fits in 16 bits (so that the last term +// fits in 32 bits), convert to three 32-bit divides by a constant. +// +// If 1<<32 = Q * c + R +// and x = hi << 32 + lo +// +// Then x = (hi/c*c + hi%c) << 32 + lo +// = hi/c*c<<32 + hi%c<<32 + lo +// = hi/c*c<<32 + (hi%c)*(Q*c+R) + lo/c*c + lo%c +// = hi/c*c<<32 + (hi%c)*Q*c + lo/c*c + (hi%c*R+lo%c) +// and x / c = (hi/c)<<32 + (hi%c)*Q + lo/c + (hi%c*R+lo%c)/c +(Div64u x (Const64 [c])) && c > 0 && c <= 0xFFFF && umagicOK32(int32(c)) && config.RegSize == 4 && config.useHmul => + (Add64 + (Add64 <typ.UInt64> + (Add64 <typ.UInt64> + (Lsh64x64 <typ.UInt64> + (ZeroExt32to64 + (Div32u <typ.UInt32> + (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) + (Const32 <typ.UInt32> [int32(c)]))) + (Const64 <typ.UInt64> [32])) + (ZeroExt32to64 (Div32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)])))) + (Mul64 <typ.UInt64> + (ZeroExt32to64 <typ.UInt64> + (Mod32u <typ.UInt32> + (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) + (Const32 <typ.UInt32> [int32(c)]))) + (Const64 <typ.UInt64> [int64((1<<32)/c)]))) + (ZeroExt32to64 + (Div32u <typ.UInt32> + (Add32 <typ.UInt32> + (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)])) + (Mul32 <typ.UInt32> + (Mod32u <typ.UInt32> + (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) + (Const32 <typ.UInt32> [int32(c)])) + (Const32 <typ.UInt32> [int32((1<<32)%c)]))) + (Const32 <typ.UInt32> [int32(c)])))) + // For 64-bit divides on 64-bit machines // (64-bit divides on 32-bit machines are lowered to a runtime call by the walk pass.) (Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && umagic64(c).m&1 == 0 && config.useHmul => @@ -1933,34 +1973,71 @@ // recognize runtime.newobject and don't Zero/Nilcheck it (Zero (Load (OffPtr [c] (SP)) mem) mem) && mem.Op == OpStaticCall - && isSameSym(mem.Aux, "runtime.newobject") + && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value => mem (Store (Load (OffPtr [c] (SP)) mem) x mem) && isConstZero(x) && mem.Op == OpStaticCall - && isSameSym(mem.Aux, "runtime.newobject") + && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value => mem (Store (OffPtr (Load (OffPtr [c] (SP)) mem)) x mem) && isConstZero(x) && mem.Op == OpStaticCall - && isSameSym(mem.Aux, "runtime.newobject") + && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value => mem // nil checks just need to rewrite to something useless. // they will be deadcode eliminated soon afterwards. (NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _) - && symNamed(sym, "runtime.newobject") + && isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value && warnRule(fe.Debug_checknil(), v, "removed nil check") => (Invalid) (NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _) - && symNamed(sym, "runtime.newobject") + && isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value && warnRule(fe.Debug_checknil(), v, "removed nil check") => (Invalid) +// for rewriting results of some late-expanded rewrites (below) +(SelectN [0] (MakeResult a ___)) => a +(SelectN [1] (MakeResult a b ___)) => b +(SelectN [2] (MakeResult a b c ___)) => c + +// for late-expanded calls, recognize newobject and remove zeroing and nilchecks +(Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call)) + && isSameCall(call.Aux, "runtime.newobject") + => mem + +(Store (SelectN [0] call:(StaticLECall _ _)) x mem:(SelectN [1] call)) + && isConstZero(x) + && isSameCall(call.Aux, "runtime.newobject") + => mem + +(Store (OffPtr (SelectN [0] call:(StaticLECall _ _))) x mem:(SelectN [1] call)) + && isConstZero(x) + && isSameCall(call.Aux, "runtime.newobject") + => mem + +(NilCheck (SelectN [0] call:(StaticLECall _ _)) (SelectN [1] call)) + && isSameCall(call.Aux, "runtime.newobject") + && warnRule(fe.Debug_checknil(), v, "removed nil check") + => (Invalid) + +(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) (SelectN [1] call)) + && isSameCall(call.Aux, "runtime.newobject") + && warnRule(fe.Debug_checknil(), v, "removed nil check") + => (Invalid) + +// for late-expanded calls, recognize memequal applied to a single constant byte +// TODO figure out breakeven number of bytes for this optimization. +(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [1]) mem) + && isSameCall(callAux, "runtime.memequal") + && symIsRO(scon) + => (MakeResult (Eq8 (Load <typ.Int8> sptr mem) (Const8 <typ.Int8> [int8(read8(scon,0))])) mem) + // Evaluate constant address comparisons. (EqPtr x x) => (ConstBool [true]) (NeqPtr x x) => (ConstBool [false]) @@ -2010,19 +2087,37 @@ // See the comment in op Move in genericOps.go for discussion of the type. (StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))) && sz >= 0 - && symNamed(sym, "runtime.memmove") + && isSameCall(sym, "runtime.memmove") && t.IsPtr() // avoids TUINTPTR, see issue 30061 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3) => (Move {t.Elem()} [int64(sz)] dst src mem) +// Inline small or disjoint runtime.memmove calls with constant length. +// See the comment in op Move in genericOps.go for discussion of the type. +(SelectN [0] call:(StaticLECall {sym} dst src (Const(64|32) [sz]) mem)) + && sz >= 0 + && call.Uses == 1 // this will exclude all calls with results + && isSameCall(sym, "runtime.memmove") + && dst.Type.IsPtr() // avoids TUINTPTR, see issue 30061 + && isInlinableMemmove(dst, src, int64(sz), config) + && clobber(call) + => (Move {dst.Type.Elem()} [int64(sz)] dst src mem) + // De-virtualize interface calls into static calls. // Note that (ITab (IMake)) doesn't get // rewritten until after the first opt pass, // so this rule should trigger reliably. -(InterCall [argsize] (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) && devirt(v, itab, off) != nil => - (StaticCall [int32(argsize)] {devirt(v, itab, off)} mem) +(InterCall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) && devirt(v, auxCall, itab, off) != nil => + (StaticCall [int32(argsize)] {devirt(v, auxCall, itab, off)} mem) + +// De-virtualize late-expanded interface calls into late-expanded static calls. +// Note that (ITab (IMake)) doesn't get rewritten until after the first opt pass, +// so this rule should trigger reliably. +// devirtLECall removes the first argument, adds the devirtualized symbol to the AuxCall, and changes the opcode +(InterLECall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) ___) && devirtLESym(v, auxCall, itab, off) != + nil => devirtLECall(v, devirtLESym(v, auxCall, itab, off)) // Move and Zero optimizations. // Move source and destination may overlap. @@ -2404,6 +2499,7 @@ (Store {t5} (OffPtr <tt5> [o5] dst) d4 (Zero {t1} [n] dst mem))))) +// TODO this does not fire before call expansion; is that acceptable? (StaticCall {sym} x) && needRaceCleanup(sym, v) => x // Collapse moving A -> B -> C into just A -> C. diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go index 5df0a164bf..8cfda35c22 100644 --- a/src/cmd/compile/internal/ssa/gen/genericOps.go +++ b/src/cmd/compile/internal/ssa/gen/genericOps.go @@ -346,6 +346,7 @@ var genericOps = []opData{ // Memory operations {name: "Load", argLength: 2}, // Load from arg0. arg1=memory + {name: "Dereference", argLength: 2}, // Load from arg0. arg1=memory. Helper op for arg/result passing, result is an otherwise not-SSA-able "value". {name: "Store", argLength: 3, typ: "Mem", aux: "Typ"}, // Store arg1 to arg0. arg2=memory, aux=type. Returns memory. // The source and destination of Move may overlap in some cases. See e.g. // memmove inlining in generic.rules. When inlineablememmovesize (in ../rewrite.go) @@ -387,9 +388,13 @@ var genericOps = []opData{ // as a phantom first argument. // TODO(josharian): ClosureCall and InterCall should have Int32 aux // to match StaticCall's 32 bit arg size limit. - {name: "ClosureCall", argLength: 3, aux: "Int64", call: true}, // arg0=code pointer, arg1=context ptr, arg2=memory. auxint=arg size. Returns memory. - {name: "StaticCall", argLength: 1, aux: "SymOff", call: true, symEffect: "None"}, // call function aux.(*obj.LSym), arg0=memory. auxint=arg size. Returns memory. - {name: "InterCall", argLength: 2, aux: "Int64", call: true}, // interface call. arg0=code pointer, arg1=memory, auxint=arg size. Returns memory. + // TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff? + {name: "ClosureCall", argLength: 3, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2=memory. auxint=arg size. Returns memory. + {name: "StaticCall", argLength: 1, aux: "CallOff", call: true}, // call function aux.(*obj.LSym), arg0=memory. auxint=arg size. Returns memory. + {name: "InterCall", argLength: 2, aux: "CallOff", call: true}, // interface call. arg0=code pointer, arg1=memory, auxint=arg size. Returns memory. + {name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr, arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem. + {name: "StaticLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem. + {name: "InterLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded interface call. arg0=code pointer, arg1..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem. // Conversions: signed extensions, zero (unsigned) extensions, truncations {name: "SignExt8to16", argLength: 1, typ: "Int16"}, @@ -531,23 +536,28 @@ var genericOps = []opData{ {name: "Cvt64Fto64U", argLength: 1}, // float64 -> uint64, only used on archs that has the instruction // pseudo-ops for breaking Tuple - {name: "Select0", argLength: 1, zeroWidth: true}, // the first component of a tuple - {name: "Select1", argLength: 1, zeroWidth: true}, // the second component of a tuple + {name: "Select0", argLength: 1, zeroWidth: true}, // the first component of a tuple + {name: "Select1", argLength: 1, zeroWidth: true}, // the second component of a tuple + {name: "SelectN", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index. Returns the auxint'th member. + {name: "SelectNAddr", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index. Returns the address of auxint'th member. Used for un-SSA-able result types. + {name: "MakeResult", argLength: -1}, // arg0 .. are components of a "Result" (like the result from a Call). The last arg should be memory (like the result from a call). - // Atomic operations used for semantically inlining runtime/internal/atomic. - // Atomic loads return a new memory so that the loads are properly ordered - // with respect to other loads and stores. - // TODO: use for sync/atomic at some point. + // Atomic operations used for semantically inlining sync/atomic and + // runtime/internal/atomic. Atomic loads return a new memory so that + // the loads are properly ordered with respect to other loads and + // stores. {name: "AtomicLoad8", argLength: 2, typ: "(UInt8,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory. {name: "AtomicLoad32", argLength: 2, typ: "(UInt32,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory. {name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory. {name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory. {name: "AtomicLoadAcq32", argLength: 2, typ: "(UInt32,Mem)"}, // Load from arg0. arg1=memory. Lock acquisition, returns loaded value and new memory. + {name: "AtomicLoadAcq64", argLength: 2, typ: "(UInt64,Mem)"}, // Load from arg0. arg1=memory. Lock acquisition, returns loaded value and new memory. {name: "AtomicStore8", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory. {name: "AtomicStore32", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory. {name: "AtomicStore64", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory. {name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory. {name: "AtomicStoreRel32", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Lock release, returns memory. + {name: "AtomicStoreRel64", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Lock release, returns memory. {name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory. {name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory. {name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory. @@ -556,14 +566,24 @@ var genericOps = []opData{ {name: "AtomicCompareAndSwap64", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Returns true if store happens and new memory. {name: "AtomicCompareAndSwapRel32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Lock release, reports whether store happens and new memory. {name: "AtomicAnd8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory. + {name: "AtomicAnd32", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory. {name: "AtomicOr8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory. + {name: "AtomicOr32", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory. // Atomic operation variants // These variants have the same semantics as above atomic operations. // But they are used for generating more efficient code on certain modern machines, with run-time CPU feature detection. // Currently, they are used on ARM64 only. - {name: "AtomicAdd32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory. - {name: "AtomicAdd64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory. + {name: "AtomicAdd32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory. + {name: "AtomicAdd64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory. + {name: "AtomicExchange32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory. + {name: "AtomicExchange64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory. + {name: "AtomicCompareAndSwap32Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Returns true if store happens and new memory. + {name: "AtomicCompareAndSwap64Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Returns true if store happens and new memory. + {name: "AtomicAnd8Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory. + {name: "AtomicAnd32Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory. + {name: "AtomicOr8Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory. + {name: "AtomicOr32Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory. // Clobber experiment op {name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go index 9e2e112cd7..120ccbbdb3 100644 --- a/src/cmd/compile/internal/ssa/gen/rulegen.go +++ b/src/cmd/compile/internal/ssa/gen/rulegen.go @@ -35,8 +35,7 @@ import ( ) // rule syntax: -// sexpr [&& extra conditions] -> [@block] sexpr (untyped) -// sexpr [&& extra conditions] => [@block] sexpr (typed) +// sexpr [&& extra conditions] => [@block] sexpr // // sexpr are s-expressions (lisp-like parenthesized groupings) // sexpr ::= [variable:](opcode sexpr*) @@ -50,8 +49,12 @@ import ( // variable ::= some token // opcode ::= one of the opcodes from the *Ops.go files +// special rules: trailing ellipsis "..." (in the outermost sexpr?) must match on both sides of a rule. +// trailing three underscore "___" in the outermost match sexpr indicate the presence of +// extra ignored args that need not appear in the replacement + // extra conditions is just a chunk of Go that evaluates to a boolean. It may use -// variables declared in the matching sexpr. The variable "v" is predefined to be +// variables declared in the matching tsexpr. The variable "v" is predefined to be // the value matched by the entire rule. // If multiple rules match, the first one in file order is selected. @@ -75,14 +78,8 @@ func normalizeSpaces(s string) string { } // parse returns the matching part of the rule, additional conditions, and the result. -// parse also reports whether the generated code should use strongly typed aux and auxint fields. -func (r Rule) parse() (match, cond, result string, typed bool) { - arrow := "->" - if strings.Contains(r.Rule, "=>") { - arrow = "=>" - typed = true - } - s := strings.Split(r.Rule, arrow) +func (r Rule) parse() (match, cond, result string) { + s := strings.Split(r.Rule, "=>") match = normalizeSpaces(s[0]) result = normalizeSpaces(s[1]) cond = "" @@ -90,7 +87,7 @@ func (r Rule) parse() (match, cond, result string, typed bool) { cond = normalizeSpaces(match[i+2:]) match = normalizeSpaces(match[:i]) } - return match, cond, result, typed + return match, cond, result } func genRules(arch arch) { genRulesSuffix(arch, "") } @@ -116,7 +113,7 @@ func genRulesSuffix(arch arch, suff string) { scanner := bufio.NewScanner(text) rule := "" var lineno int - var ruleLineno int // line number of "->" or "=>" + var ruleLineno int // line number of "=>" for scanner.Scan() { lineno++ line := scanner.Text() @@ -130,13 +127,13 @@ func genRulesSuffix(arch arch, suff string) { if rule == "" { continue } - if !strings.Contains(rule, "->") && !strings.Contains(rule, "=>") { + if !strings.Contains(rule, "=>") { continue } if ruleLineno == 0 { ruleLineno = lineno } - if strings.HasSuffix(rule, "->") || strings.HasSuffix(rule, "=>") { + if strings.HasSuffix(rule, "=>") { continue // continue on the next line } if n := balance(rule); n > 0 { @@ -153,7 +150,7 @@ func genRulesSuffix(arch arch, suff string) { continue } // Do fancier value op matching. - match, _, _, _ := r.parse() + match, _, _ := r.parse() op, oparch, _, _, _, _ := parseValue(match, arch, loc) opname := fmt.Sprintf("Op%s%s", oparch, op.name) oprules[opname] = append(oprules[opname], r) @@ -227,7 +224,7 @@ func genRulesSuffix(arch arch, suff string) { log.Fatalf("unconditional rule %s is followed by other rules", rr.Match) } rr = &RuleRewrite{Loc: rule.Loc} - rr.Match, rr.Cond, rr.Result, rr.Typed = rule.parse() + rr.Match, rr.Cond, rr.Result = rule.parse() pos, _ := genMatch(rr, arch, rr.Match, fn.ArgLen >= 0) if pos == "" { pos = "v.Pos" @@ -786,7 +783,6 @@ type ( Alloc int // for unique var names Loc string // file name & line number of the original rule CommuteDepth int // used to track depth of commute loops - Typed bool // aux and auxint fields should be strongly typed } Declare struct { Name string @@ -840,7 +836,7 @@ func breakf(format string, a ...interface{}) *CondBreak { func genBlockRewrite(rule Rule, arch arch, data blockData) *RuleRewrite { rr := &RuleRewrite{Loc: rule.Loc} - rr.Match, rr.Cond, rr.Result, rr.Typed = rule.parse() + rr.Match, rr.Cond, rr.Result = rule.parse() _, _, auxint, aux, s := extract(rr.Match) // remove parens, then split // check match of control values @@ -884,15 +880,6 @@ func genBlockRewrite(rule Rule, arch arch, data blockData) *RuleRewrite { if e.name == "" { continue } - if !rr.Typed { - if !token.IsIdentifier(e.name) || rr.declared(e.name) { - // code or variable - rr.add(breakf("b.%s != %s", e.field, e.name)) - } else { - rr.add(declf(e.name, "b.%s", e.field)) - } - continue - } if e.dclType == "" { log.Fatalf("op %s has no declared type for %s", data.name, e.field) @@ -961,20 +948,12 @@ func genBlockRewrite(rule Rule, arch arch, data blockData) *RuleRewrite { } if auxint != "" { - if rr.Typed { - // Make sure auxint value has the right type. - rr.add(stmtf("b.AuxInt = %sToAuxInt(%s)", unTitle(outdata.auxIntType()), auxint)) - } else { - rr.add(stmtf("b.AuxInt = %s", auxint)) - } + // Make sure auxint value has the right type. + rr.add(stmtf("b.AuxInt = %sToAuxInt(%s)", unTitle(outdata.auxIntType()), auxint)) } if aux != "" { - if rr.Typed { - // Make sure aux value has the right type. - rr.add(stmtf("b.Aux = %sToAux(%s)", unTitle(outdata.auxType()), aux)) - } else { - rr.add(stmtf("b.Aux = %s", aux)) - } + // Make sure aux value has the right type. + rr.add(stmtf("b.Aux = %sToAux(%s)", unTitle(outdata.auxType()), aux)) } succChanged := false @@ -1019,6 +998,19 @@ func genMatch0(rr *RuleRewrite, arch arch, match, v string, cnt map[string]int, pos = v + ".Pos" } + // If the last argument is ___, it means "don't care about trailing arguments, really" + // The likely/intended use is for rewrites that are too tricky to express in the existing pattern language + // Do a length check early because long patterns fed short (ultimately not-matching) inputs will + // do an indexing error in pattern-matching. + if op.argLength == -1 { + l := len(args) + if l == 0 || args[l-1] != "___" { + rr.add(breakf("len(%s.Args) != %d", v, l)) + } else if l > 1 && args[l-1] == "___" { + rr.add(breakf("len(%s.Args) < %d", v, l-1)) + } + } + for _, e := range []struct { name, field, dclType string }{ @@ -1029,15 +1021,6 @@ func genMatch0(rr *RuleRewrite, arch arch, match, v string, cnt map[string]int, if e.name == "" { continue } - if !rr.Typed { - if !token.IsIdentifier(e.name) || rr.declared(e.name) { - // code or variable - rr.add(breakf("%s.%s != %s", v, e.field, e.name)) - } else { - rr.add(declf(e.name, "%s.%s", v, e.field)) - } - continue - } if e.dclType == "" { log.Fatalf("op %s has no declared type for %s", op.name, e.field) @@ -1159,9 +1142,6 @@ func genMatch0(rr *RuleRewrite, arch arch, match, v string, cnt map[string]int, } } - if op.argLength == -1 { - rr.add(breakf("len(%s.Args) != %d", v, len(args))) - } return pos, checkOp } @@ -1230,20 +1210,12 @@ func genResult0(rr *RuleRewrite, arch arch, result string, top, move bool, pos s } if auxint != "" { - if rr.Typed { - // Make sure auxint value has the right type. - rr.add(stmtf("%s.AuxInt = %sToAuxInt(%s)", v, unTitle(op.auxIntType()), auxint)) - } else { - rr.add(stmtf("%s.AuxInt = %s", v, auxint)) - } + // Make sure auxint value has the right type. + rr.add(stmtf("%s.AuxInt = %sToAuxInt(%s)", v, unTitle(op.auxIntType()), auxint)) } if aux != "" { - if rr.Typed { - // Make sure aux value has the right type. - rr.add(stmtf("%s.Aux = %sToAux(%s)", v, unTitle(op.auxType()), aux)) - } else { - rr.add(stmtf("%s.Aux = %s", v, aux)) - } + // Make sure aux value has the right type. + rr.add(stmtf("%s.Aux = %sToAux(%s)", v, unTitle(op.auxType()), aux)) } all := new(strings.Builder) for i, arg := range args { @@ -1424,7 +1396,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi func opHasAuxInt(op opData) bool { switch op.aux { case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", - "SymOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop": + "SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop": return true } return false @@ -1432,7 +1404,7 @@ func opHasAuxInt(op opData) bool { func opHasAux(op opData) bool { switch op.aux { - case "String", "Sym", "SymOff", "SymValAndOff", "Typ", "TypSize", + case "String", "Sym", "SymOff", "Call", "CallOff", "SymValAndOff", "Typ", "TypSize", "S390XCCMask", "S390XRotateParams": return true } @@ -1524,7 +1496,7 @@ func excludeFromExpansion(s string, idx []int) bool { return true } right := s[idx[1]:] - if strings.Contains(left, "&&") && (strings.Contains(right, "->") || strings.Contains(right, "=>")) { + if strings.Contains(left, "&&") && strings.Contains(right, "=>") { // Inside && conditions. return true } @@ -1626,7 +1598,6 @@ func normalizeWhitespace(x string) string { x = strings.Replace(x, " )", ")", -1) x = strings.Replace(x, "[ ", "[", -1) x = strings.Replace(x, " ]", "]", -1) - x = strings.Replace(x, ")->", ") ->", -1) x = strings.Replace(x, ")=>", ") =>", -1) return x } @@ -1683,7 +1654,7 @@ func parseEllipsisRules(rules []Rule, arch arch) (newop string, ok bool) { return "", false } rule := rules[0] - match, cond, result, _ := rule.parse() + match, cond, result := rule.parse() if cond != "" || !isEllipsisValue(match) || !isEllipsisValue(result) { if strings.Contains(rule.Rule, "...") { log.Fatalf("%s: found ellipsis in non-ellipsis rule", rule.Loc) @@ -1708,7 +1679,7 @@ func isEllipsisValue(s string) bool { } func checkEllipsisRuleCandidate(rule Rule, arch arch) { - match, cond, result, _ := rule.parse() + match, cond, result := rule.parse() if cond != "" { return } @@ -1718,7 +1689,7 @@ func checkEllipsisRuleCandidate(rule Rule, arch arch) { var usingCopy string var eop opData if result[0] != '(' { - // Check for (Foo x) -> x, which can be converted to (Foo ...) -> (Copy ...). + // Check for (Foo x) => x, which can be converted to (Foo ...) => (Copy ...). args2 = []string{result} usingCopy = " using Copy" } else { @@ -1775,6 +1746,10 @@ func (op opData) auxType() string { return "Sym" case "SymOff": return "Sym" + case "Call": + return "Call" + case "CallOff": + return "Call" case "SymValAndOff": return "Sym" case "Typ": @@ -1809,6 +1784,8 @@ func (op opData) auxIntType() string { return "float32" case "Float64": return "float64" + case "CallOff": + return "int32" case "SymOff": return "int32" case "SymValAndOff": diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go index ba37a80412..a9d52fa4ee 100644 --- a/src/cmd/compile/internal/ssa/html.go +++ b/src/cmd/compile/internal/ssa/html.go @@ -28,18 +28,23 @@ type HTMLWriter struct { } func NewHTMLWriter(path string, f *Func, cfgMask string) *HTMLWriter { + path = strings.Replace(path, "/", string(filepath.Separator), -1) out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { f.Fatalf("%v", err) } - pwd, err := os.Getwd() - if err != nil { - f.Fatalf("%v", err) + reportPath := path + if !filepath.IsAbs(reportPath) { + pwd, err := os.Getwd() + if err != nil { + f.Fatalf("%v", err) + } + reportPath = filepath.Join(pwd, path) } html := HTMLWriter{ w: out, Func: f, - path: filepath.Join(pwd, path), + path: reportPath, dot: newDotWriter(cfgMask), } html.start() @@ -119,7 +124,8 @@ td.collapsed { } td.collapsed div { - /* TODO: Flip the direction of the phase's title 90 degrees on a collapsed column. */ + text-align: right; + transform: rotate(180deg); writing-mode: vertical-lr; white-space: pre; } @@ -357,6 +363,21 @@ body.darkmode ellipse.outline-black { outline: gray solid 2px; } </style> <script type="text/javascript"> + +// Contains phase names which are expanded by default. Other columns are collapsed. +let expandedDefault = [ + "start", + "deadcode", + "opt", + "lower", + "late-deadcode", + "regalloc", + "genssa", +]; +if (history.state === null) { + history.pushState({expandedDefault}, "", location.href); +} + // ordered list of all available highlight colors var highlights = [ "highlight-aquamarine", @@ -401,6 +422,9 @@ for (var i = 0; i < outlines.length; i++) { } window.onload = function() { + if (history.state !== null) { + expandedDefault = history.state.expandedDefault; + } if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { toggleDarkMode(); document.getElementById("dark-mode-button").checked = true; @@ -409,9 +433,6 @@ window.onload = function() { var ssaElemClicked = function(elem, event, selections, selected) { event.stopPropagation(); - // TODO: pushState with updated state and read it on page load, - // so that state can survive across reloads - // find all values with the same name var c = elem.classList.item(0); var x = document.getElementsByClassName(c); @@ -489,21 +510,18 @@ window.onload = function() { lines[i].addEventListener('click', ssaValueClicked); } - // Contains phase names which are expanded by default. Other columns are collapsed. - var expandedDefault = [ - "start", - "deadcode", - "opt", - "lower", - "late-deadcode", - "regalloc", - "genssa", - ]; function toggler(phase) { return function() { toggle_cell(phase+'-col'); toggle_cell(phase+'-exp'); + const i = expandedDefault.indexOf(phase); + if (i !== -1) { + expandedDefault.splice(i, 1); + } else { + expandedDefault.push(phase); + } + history.pushState({expandedDefault}, "", location.href); }; } @@ -531,9 +549,13 @@ window.onload = function() { const len = combined.length; if (len > 1) { for (let i = 0; i < len; i++) { - if (expandedDefault.indexOf(combined[i]) !== -1) { - show = true; - break; + const num = expandedDefault.indexOf(combined[i]); + if (num !== -1) { + expandedDefault.splice(num, 1); + if (expandedDefault.indexOf(phase) === -1) { + expandedDefault.push(phase); + show = true; + } } } } diff --git a/src/cmd/compile/internal/ssa/lca.go b/src/cmd/compile/internal/ssa/lca.go index b9731fa7c2..5cb73911df 100644 --- a/src/cmd/compile/internal/ssa/lca.go +++ b/src/cmd/compile/internal/ssa/lca.go @@ -113,7 +113,7 @@ func (lca *lcaRange) find(a, b *Block) *Block { // on the tour from p1 to p2. We've precomputed minimum // depth blocks for powers-of-two subsequences of the tour. // Combine the right two precomputed values to get the answer. - logS := uint(log2(int64(p2 - p1))) + logS := uint(log64(int64(p2 - p1))) bid1 := lca.rangeMin[logS][p1] bid2 := lca.rangeMin[logS][p2-1<<logS+1] if lca.blocks[bid1].depth < lca.blocks[bid2].depth { diff --git a/src/cmd/compile/internal/ssa/loopreschedchecks.go b/src/cmd/compile/internal/ssa/loopreschedchecks.go index 1932f9d23a..9c73bcff26 100644 --- a/src/cmd/compile/internal/ssa/loopreschedchecks.go +++ b/src/cmd/compile/internal/ssa/loopreschedchecks.go @@ -246,7 +246,7 @@ func insertLoopReschedChecks(f *Func) { // mem1 := call resched (mem0) // goto header resched := f.fe.Syslook("goschedguarded") - mem1 := sched.NewValue1A(bb.Pos, OpStaticCall, types.TypeMem, resched, mem0) + mem1 := sched.NewValue1A(bb.Pos, OpStaticCall, types.TypeMem, StaticAuxCall(resched, nil, nil), mem0) sched.AddEdgeTo(h) headerMemPhi.AddArg(mem1) diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go index 063998c6a1..6f029a421e 100644 --- a/src/cmd/compile/internal/ssa/op.go +++ b/src/cmd/compile/internal/ssa/op.go @@ -5,6 +5,7 @@ package ssa import ( + "cmd/compile/internal/types" "cmd/internal/obj" "fmt" ) @@ -67,6 +68,135 @@ type regInfo struct { type auxType int8 +type Param struct { + Type *types.Type + Offset int32 // TODO someday this will be a register +} + +type AuxCall struct { + Fn *obj.LSym + args []Param // Includes receiver for method calls. Does NOT include hidden closure pointer. + results []Param +} + +// ResultForOffset returns the index of the result at a particular offset among the results +// This does not include the mem result for the call opcode. +func (a *AuxCall) ResultForOffset(offset int64) int64 { + which := int64(-1) + for i := int64(0); i < a.NResults(); i++ { // note aux NResults does not include mem result. + if a.OffsetOfResult(i) == offset { + which = i + break + } + } + return which +} + +// OffsetOfResult returns the SP offset of result which (indexed 0, 1, etc). +func (a *AuxCall) OffsetOfResult(which int64) int64 { + return int64(a.results[which].Offset) +} + +// OffsetOfArg returns the SP offset of argument which (indexed 0, 1, etc). +func (a *AuxCall) OffsetOfArg(which int64) int64 { + return int64(a.args[which].Offset) +} + +// TypeOfResult returns the type of result which (indexed 0, 1, etc). +func (a *AuxCall) TypeOfResult(which int64) *types.Type { + return a.results[which].Type +} + +// TypeOfArg returns the type of argument which (indexed 0, 1, etc). +func (a *AuxCall) TypeOfArg(which int64) *types.Type { + return a.args[which].Type +} + +// SizeOfResult returns the size of result which (indexed 0, 1, etc). +func (a *AuxCall) SizeOfResult(which int64) int64 { + return a.TypeOfResult(which).Width +} + +// SizeOfArg returns the size of argument which (indexed 0, 1, etc). +func (a *AuxCall) SizeOfArg(which int64) int64 { + return a.TypeOfArg(which).Width +} + +// NResults returns the number of results +func (a *AuxCall) NResults() int64 { + return int64(len(a.results)) +} + +// LateExpansionResultType returns the result type (including trailing mem) +// for a call that will be expanded later in the SSA phase. +func (a *AuxCall) LateExpansionResultType() *types.Type { + var tys []*types.Type + for i := int64(0); i < a.NResults(); i++ { + tys = append(tys, a.TypeOfResult(i)) + } + tys = append(tys, types.TypeMem) + return types.NewResults(tys) +} + +// NArgs returns the number of arguments +func (a *AuxCall) NArgs() int64 { + return int64(len(a.args)) +} + +// String returns +// "AuxCall{<fn>(<args>)}" if len(results) == 0; +// "AuxCall{<fn>(<args>)<results[0]>}" if len(results) == 1; +// "AuxCall{<fn>(<args>)(<results>)}" otherwise. +func (a *AuxCall) String() string { + var fn string + if a.Fn == nil { + fn = "AuxCall{nil" // could be interface/closure etc. + } else { + fn = fmt.Sprintf("AuxCall{%v", a.Fn) + } + + if len(a.args) == 0 { + fn += "()" + } else { + s := "(" + for _, arg := range a.args { + fn += fmt.Sprintf("%s[%v,%v]", s, arg.Type, arg.Offset) + s = "," + } + fn += ")" + } + + if len(a.results) > 0 { // usual is zero or one; only some RT calls have more than one. + if len(a.results) == 1 { + fn += fmt.Sprintf("[%v,%v]", a.results[0].Type, a.results[0].Offset) + } else { + s := "(" + for _, result := range a.results { + fn += fmt.Sprintf("%s[%v,%v]", s, result.Type, result.Offset) + s = "," + } + fn += ")" + } + } + + return fn + "}" +} + +// StaticAuxCall returns an AuxCall for a static call. +func StaticAuxCall(sym *obj.LSym, args []Param, results []Param) *AuxCall { + return &AuxCall{Fn: sym, args: args, results: results} +} + +// InterfaceAuxCall returns an AuxCall for an interface call. +func InterfaceAuxCall(args []Param, results []Param) *AuxCall { + return &AuxCall{Fn: nil, args: args, results: results} +} + +// ClosureAuxCall returns an AuxCall for a closure call. +func ClosureAuxCall(args []Param, results []Param) *AuxCall { + return &AuxCall{Fn: nil, args: args, results: results} +} + const ( auxNone auxType = iota auxBool // auxInt is 0/1 for false/true @@ -85,6 +215,8 @@ const ( auxTyp // aux is a type auxTypSize // aux is a type, auxInt is a size, must have Aux.(Type).Size() == AuxInt auxCCop // aux is a ssa.Op that represents a flags-to-bool conversion (e.g. LessThan) + auxCall // aux is a *ssa.AuxCall + auxCallOff // aux is a *ssa.AuxCall, AuxInt is int64 param (in+out) size // architecture specific aux types auxARM64BitField // aux is an arm64 bitfield lsb and width packed into auxInt @@ -134,9 +266,6 @@ func (x ValAndOff) Val8() int8 { return int8(int64(x) >> 32) } func (x ValAndOff) Off() int64 { return int64(int32(x)) } func (x ValAndOff) Off32() int32 { return int32(x) } -func (x ValAndOff) Int64() int64 { - return int64(x) -} func (x ValAndOff) String() string { return fmt.Sprintf("val=%d,off=%d", x.Val(), x.Off()) } @@ -165,46 +294,36 @@ func validValAndOff(val, off int64) bool { return true } -// makeValAndOff encodes a ValAndOff into an int64 suitable for storing in an AuxInt field. -func makeValAndOff(val, off int64) int64 { - if !validValAndOff(val, off) { - panic("invalid makeValAndOff") - } - return ValAndOff(val<<32 + int64(uint32(off))).Int64() -} func makeValAndOff32(val, off int32) ValAndOff { return ValAndOff(int64(val)<<32 + int64(uint32(off))) } - -func (x ValAndOff) canAdd(off int64) bool { - newoff := x.Off() + off - return newoff == int64(int32(newoff)) +func makeValAndOff64(val, off int64) ValAndOff { + if !validValAndOff(val, off) { + panic("invalid makeValAndOff64") + } + return ValAndOff(val<<32 + int64(uint32(off))) } func (x ValAndOff) canAdd32(off int32) bool { newoff := x.Off() + int64(off) return newoff == int64(int32(newoff)) } - -func (x ValAndOff) add(off int64) int64 { - if !x.canAdd(off) { - panic("invalid ValAndOff.add") - } - return makeValAndOff(x.Val(), x.Off()+off) +func (x ValAndOff) canAdd64(off int64) bool { + newoff := x.Off() + off + return newoff == int64(int32(newoff)) } func (x ValAndOff) addOffset32(off int32) ValAndOff { if !x.canAdd32(off) { - panic("invalid ValAndOff.add") + panic("invalid ValAndOff.addOffset32") } - return ValAndOff(makeValAndOff(x.Val(), x.Off()+int64(off))) + return makeValAndOff64(x.Val(), x.Off()+int64(off)) } - func (x ValAndOff) addOffset64(off int64) ValAndOff { - if !x.canAdd(off) { - panic("invalid ValAndOff.add") + if !x.canAdd64(off) { + panic("invalid ValAndOff.addOffset64") } - return ValAndOff(makeValAndOff(x.Val(), x.Off()+off)) + return makeValAndOff64(x.Val(), x.Off()+off) } // int128 is a type that stores a 128-bit constant. diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 45401898c8..eceef1d91a 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -536,7 +536,6 @@ const ( Op386FlagLT_UGT Op386FlagGT_UGT Op386FlagGT_ULT - Op386FCHS Op386MOVSSconst1 Op386MOVSDconst1 Op386MOVSSconst2 @@ -1035,7 +1034,9 @@ const ( OpAMD64CMPXCHGLlock OpAMD64CMPXCHGQlock OpAMD64ANDBlock + OpAMD64ANDLlock OpAMD64ORBlock + OpAMD64ORLlock OpARMADD OpARMADDconst @@ -1580,14 +1581,24 @@ const ( OpARM64STLRW OpARM64LoweredAtomicExchange64 OpARM64LoweredAtomicExchange32 + OpARM64LoweredAtomicExchange64Variant + OpARM64LoweredAtomicExchange32Variant OpARM64LoweredAtomicAdd64 OpARM64LoweredAtomicAdd32 OpARM64LoweredAtomicAdd64Variant OpARM64LoweredAtomicAdd32Variant OpARM64LoweredAtomicCas64 OpARM64LoweredAtomicCas32 + OpARM64LoweredAtomicCas64Variant + OpARM64LoweredAtomicCas32Variant OpARM64LoweredAtomicAnd8 + OpARM64LoweredAtomicAnd32 OpARM64LoweredAtomicOr8 + OpARM64LoweredAtomicOr32 + OpARM64LoweredAtomicAnd8Variant + OpARM64LoweredAtomicAnd32Variant + OpARM64LoweredAtomicOr8Variant + OpARM64LoweredAtomicOr32Variant OpARM64LoweredWB OpARM64LoweredPanicBoundsA OpARM64LoweredPanicBoundsB @@ -1833,6 +1844,8 @@ const ( OpPPC64FSUBS OpPPC64MULLD OpPPC64MULLW + OpPPC64MULLDconst + OpPPC64MULLWconst OpPPC64MADDLD OpPPC64MULHD OpPPC64MULHW @@ -1853,6 +1866,9 @@ const ( OpPPC64SLW OpPPC64ROTL OpPPC64ROTLW + OpPPC64RLDICL + OpPPC64CLRLSLWI + OpPPC64CLRLSLDI OpPPC64LoweredAdd64Carry OpPPC64SRADconst OpPPC64SRAWconst @@ -1862,6 +1878,10 @@ const ( OpPPC64SLWconst OpPPC64ROTLconst OpPPC64ROTLWconst + OpPPC64EXTSWSLconst + OpPPC64RLWINM + OpPPC64RLWNM + OpPPC64RLWMI OpPPC64CNTLZD OpPPC64CNTLZW OpPPC64CNTTZD @@ -2017,7 +2037,9 @@ const ( OpPPC64LoweredAtomicCas64 OpPPC64LoweredAtomicCas32 OpPPC64LoweredAtomicAnd8 + OpPPC64LoweredAtomicAnd32 OpPPC64LoweredAtomicOr8 + OpPPC64LoweredAtomicOr32 OpPPC64LoweredWB OpPPC64LoweredPanicBoundsA OpPPC64LoweredPanicBoundsB @@ -2066,6 +2088,14 @@ const ( OpRISCV64MOVHstorezero OpRISCV64MOVWstorezero OpRISCV64MOVDstorezero + OpRISCV64MOVBreg + OpRISCV64MOVHreg + OpRISCV64MOVWreg + OpRISCV64MOVDreg + OpRISCV64MOVBUreg + OpRISCV64MOVHUreg + OpRISCV64MOVWUreg + OpRISCV64MOVDnop OpRISCV64SLL OpRISCV64SRA OpRISCV64SRL @@ -2089,6 +2119,8 @@ const ( OpRISCV64CALLstatic OpRISCV64CALLclosure OpRISCV64CALLinter + OpRISCV64DUFFZERO + OpRISCV64DUFFCOPY OpRISCV64LoweredZero OpRISCV64LoweredMove OpRISCV64LoweredAtomicLoad8 @@ -2253,9 +2285,9 @@ const ( OpS390XSRAWconst OpS390XRLLG OpS390XRLL - OpS390XRLLGconst OpS390XRLLconst OpS390XRXSBG + OpS390XRISBGZ OpS390XNEG OpS390XNEGW OpS390XNOT @@ -2363,8 +2395,10 @@ const ( OpS390XLAAG OpS390XAddTupleFirst32 OpS390XAddTupleFirst64 - OpS390XLAOfloor + OpS390XLAN OpS390XLANfloor + OpS390XLAO + OpS390XLAOfloor OpS390XLoweredAtomicCas32 OpS390XLoweredAtomicCas64 OpS390XLoweredAtomicExchange32 @@ -2714,6 +2748,7 @@ const ( OpSP OpSB OpLoad + OpDereference OpStore OpMove OpZero @@ -2727,6 +2762,9 @@ const ( OpClosureCall OpStaticCall OpInterCall + OpClosureLECall + OpStaticLECall + OpInterLECall OpSignExt8to16 OpSignExt8to32 OpSignExt8to64 @@ -2823,16 +2861,21 @@ const ( OpCvt64Fto64U OpSelect0 OpSelect1 + OpSelectN + OpSelectNAddr + OpMakeResult OpAtomicLoad8 OpAtomicLoad32 OpAtomicLoad64 OpAtomicLoadPtr OpAtomicLoadAcq32 + OpAtomicLoadAcq64 OpAtomicStore8 OpAtomicStore32 OpAtomicStore64 OpAtomicStorePtrNoWB OpAtomicStoreRel32 + OpAtomicStoreRel64 OpAtomicExchange32 OpAtomicExchange64 OpAtomicAdd32 @@ -2841,9 +2884,19 @@ const ( OpAtomicCompareAndSwap64 OpAtomicCompareAndSwapRel32 OpAtomicAnd8 + OpAtomicAnd32 OpAtomicOr8 + OpAtomicOr32 OpAtomicAdd32Variant OpAtomicAdd64Variant + OpAtomicExchange32Variant + OpAtomicExchange64Variant + OpAtomicCompareAndSwap32Variant + OpAtomicCompareAndSwap64Variant + OpAtomicAnd8Variant + OpAtomicAnd32Variant + OpAtomicOr8Variant + OpAtomicOr32Variant OpClobber ) @@ -5816,18 +5869,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 65519, // AX CX DX BX BP SI DI X0 X1 X2 X3 X4 X5 X6 X7 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -5841,7 +5893,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -6052,18 +6104,6 @@ var opcodeTable = [...]opInfo{ reg: regInfo{}, }, { - name: "FCHS", - argLen: 1, - reg: regInfo{ - inputs: []inputInfo{ - {0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7 - }, - outputs: []outputInfo{ - {0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7 - }, - }, - }, - { name: "MOVSSconst1", auxType: auxFloat32, argLen: 0, @@ -13152,18 +13192,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 4294967279, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -13177,7 +13216,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -13577,6 +13616,22 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "ANDLlock", + auxType: auxSymOff, + argLen: 3, + clobberFlags: true, + faultOnNilArg0: true, + hasSideEffects: true, + symEffect: SymRdWr, + asm: x86.AANDL, + reg: regInfo{ + inputs: []inputInfo{ + {1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 + {0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB + }, + }, + }, + { name: "ORBlock", auxType: auxSymOff, argLen: 3, @@ -13592,6 +13647,22 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "ORLlock", + auxType: auxSymOff, + argLen: 3, + clobberFlags: true, + faultOnNilArg0: true, + hasSideEffects: true, + symEffect: SymRdWr, + asm: x86.AORL, + reg: regInfo{ + inputs: []inputInfo{ + {1, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 + {0, 4295032831}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 SB + }, + }, + }, { name: "ADD", @@ -16922,18 +16993,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 4294924287, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -16947,7 +17017,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -20556,18 +20626,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 9223372035512336383, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -20581,7 +20650,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -20942,6 +21011,38 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicExchange64Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicExchange32Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { name: "LoweredAtomicAdd64", argLen: 3, resultNotInArgs: true, @@ -21046,6 +21147,44 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicCas64Variant", + argLen: 4, + resultNotInArgs: true, + clobberFlags: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {2, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicCas32Variant", + argLen: 4, + resultNotInArgs: true, + clobberFlags: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {2, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { name: "LoweredAtomicAnd8", argLen: 3, resultNotInArgs: true, @@ -21064,6 +21203,24 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicAnd32", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + asm: arm64.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { name: "LoweredAtomicOr8", argLen: 3, resultNotInArgs: true, @@ -21082,6 +21239,90 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicOr32", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + asm: arm64.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicAnd8Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicAnd32Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicOr8Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { + name: "LoweredAtomicOr32Variant", + argLen: 3, + resultNotInArgs: true, + faultOnNilArg0: true, + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ + {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 + {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB + }, + outputs: []outputInfo{ + {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30 + }, + }, + }, + { name: "LoweredWB", auxType: auxSym, argLen: 3, @@ -22257,18 +22498,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 140737421246462, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31 F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30 HI LO }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -22282,7 +22522,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -23804,18 +24044,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 4611686018393833470, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 HI LO }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -23829,7 +24068,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -24387,6 +24626,34 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "MULLDconst", + auxType: auxInt32, + argLen: 1, + asm: ppc64.AMULLD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "MULLWconst", + auxType: auxInt32, + argLen: 1, + asm: ppc64.AMULLW, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { name: "MADDLD", argLen: 3, asm: ppc64.AMADDLD, @@ -24679,6 +24946,48 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "RLDICL", + auxType: auxInt32, + argLen: 1, + asm: ppc64.ARLDICL, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "CLRLSLWI", + auxType: auxInt32, + argLen: 1, + asm: ppc64.ACLRLSLWI, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "CLRLSLDI", + auxType: auxInt32, + argLen: 1, + asm: ppc64.ACLRLSLDI, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { name: "LoweredAdd64Carry", argLen: 3, resultNotInArgs: true, @@ -24807,6 +25116,65 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "EXTSWSLconst", + auxType: auxInt64, + argLen: 1, + asm: ppc64.AEXTSWSLI, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "RLWINM", + auxType: auxInt64, + argLen: 1, + asm: ppc64.ARLWNM, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "RLWNM", + auxType: auxInt64, + argLen: 2, + asm: ppc64.ARLWNM, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + {1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { + name: "RLWMI", + auxType: auxInt64, + argLen: 2, + resultInArg0: true, + asm: ppc64.ARLWMI, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + {1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { name: "CNTLZD", argLen: 1, clobberFlags: true, @@ -26504,18 +26872,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -26529,7 +26896,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -26871,6 +27238,19 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicAnd32", + argLen: 3, + faultOnNilArg0: true, + hasSideEffects: true, + asm: ppc64.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + {1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { name: "LoweredAtomicOr8", argLen: 3, faultOnNilArg0: true, @@ -26884,6 +27264,19 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredAtomicOr32", + argLen: 3, + faultOnNilArg0: true, + hasSideEffects: true, + asm: ppc64.AOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + {1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, + { name: "LoweredWB", auxType: auxSym, argLen: 3, @@ -26961,11 +27354,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AADD, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -26976,10 +27369,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AADDI, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -26990,10 +27383,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AADDIW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27003,10 +27396,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ANEG, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27016,10 +27409,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ANEGW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27029,11 +27422,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASUB, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27043,11 +27436,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASUBW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27058,11 +27451,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMUL, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27073,11 +27466,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMULW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27088,11 +27481,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMULH, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27103,11 +27496,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMULHU, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27117,11 +27510,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ADIV, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27131,11 +27524,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ADIVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27145,11 +27538,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ADIVW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27159,11 +27552,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ADIVUW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27173,11 +27566,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AREM, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27187,11 +27580,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AREMU, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27201,11 +27594,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AREMW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27215,11 +27608,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AREMUW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27232,10 +27625,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27247,7 +27640,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27259,7 +27652,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27271,7 +27664,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27283,7 +27676,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27296,10 +27689,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27312,10 +27705,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27328,10 +27721,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27344,10 +27737,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27360,10 +27753,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVBU, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27376,10 +27769,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVHU, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27392,10 +27785,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVWU, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27408,8 +27801,8 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27422,8 +27815,8 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27436,8 +27829,8 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27450,8 +27843,8 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27464,7 +27857,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVB, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27477,7 +27870,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVH, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27490,7 +27883,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVW, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27503,7 +27896,111 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB + }, + }, + }, + { + name: "MOVBreg", + argLen: 1, + asm: riscv.AMOVB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVHreg", + argLen: 1, + asm: riscv.AMOVH, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVWreg", + argLen: 1, + asm: riscv.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVDreg", + argLen: 1, + asm: riscv.AMOV, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVBUreg", + argLen: 1, + asm: riscv.AMOVBU, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVHUreg", + argLen: 1, + asm: riscv.AMOVHU, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVWUreg", + argLen: 1, + asm: riscv.AMOVWU, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + }, + }, + { + name: "MOVDnop", + argLen: 1, + resultInArg0: true, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + outputs: []outputInfo{ + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27513,11 +28010,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLL, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27527,11 +28024,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASRA, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27541,11 +28038,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASRL, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27556,10 +28053,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLLI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27570,10 +28067,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASRAI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27584,10 +28081,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASRLI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27598,11 +28095,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AXOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27613,10 +28110,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AXORI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27627,11 +28124,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AOR, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27642,10 +28139,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AORI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27656,11 +28153,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.AAND, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27671,10 +28168,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.AANDI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27684,10 +28181,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ANOT, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27697,10 +28194,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASEQZ, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27710,10 +28207,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASNEZ, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27723,11 +28220,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLT, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27738,10 +28235,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLTI, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27751,11 +28248,11 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLTU, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27766,10 +28263,10 @@ var opcodeTable = [...]opInfo{ asm: riscv.ASLTIU, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27779,46 +28276,71 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOV, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, { - name: "CALLstatic", - auxType: auxSymOff, - argLen: 1, - call: true, - symEffect: SymNone, + name: "CALLstatic", + auxType: auxCallOff, + argLen: 1, + call: true, reg: regInfo{ - clobbers: 9223372035781033980, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 9223372035781033972, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, call: true, reg: regInfo{ inputs: []inputInfo{ {1, 524288}, // X20 - {0, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, - clobbers: 9223372035781033980, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 9223372035781033972, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, call: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + }, + clobbers: 9223372035781033972, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, + { + name: "DUFFZERO", + auxType: auxInt64, + argLen: 2, + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ + {0, 512}, // X10 + }, + clobbers: 512, // X10 + }, + }, + { + name: "DUFFCOPY", + auxType: auxInt64, + argLen: 3, + faultOnNilArg0: true, + faultOnNilArg1: true, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1024}, // X11 + {1, 512}, // X10 }, - clobbers: 9223372035781033980, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + clobbers: 1536, // X10 X11 }, }, { @@ -27829,7 +28351,7 @@ var opcodeTable = [...]opInfo{ reg: regInfo{ inputs: []inputInfo{ {0, 16}, // X5 - {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, clobbers: 16, // X5 }, @@ -27844,7 +28366,7 @@ var opcodeTable = [...]opInfo{ inputs: []inputInfo{ {0, 16}, // X5 {1, 32}, // X6 - {2, 1073741748}, // X3 X5 X6 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {2, 1006632884}, // X3 X5 X6 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, clobbers: 112, // X5 X6 X7 }, @@ -27855,10 +28377,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27868,10 +28390,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27881,10 +28403,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27895,8 +28417,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27907,8 +28429,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27919,8 +28441,8 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, }, }, @@ -27932,11 +28454,11 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27948,11 +28470,11 @@ var opcodeTable = [...]opInfo{ hasSideEffects: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27965,11 +28487,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27982,11 +28504,11 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -27999,12 +28521,12 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {2, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {2, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28017,12 +28539,12 @@ var opcodeTable = [...]opInfo{ unsafePoint: true, reg: regInfo{ inputs: []inputInfo{ - {1, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {2, 1073741820}, // X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 - {0, 9223372037928517630}, // SP X3 g X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {1, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {2, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 + {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 g X28 X29 X30 SB }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28033,7 +28555,7 @@ var opcodeTable = [...]opInfo{ faultOnNilArg0: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741814}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632950}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28052,7 +28574,7 @@ var opcodeTable = [...]opInfo{ rematerializeable: true, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28062,7 +28584,7 @@ var opcodeTable = [...]opInfo{ rematerializeable: true, reg: regInfo{ outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28206,7 +28728,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFMVSX, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28219,7 +28741,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFCVTSW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28232,7 +28754,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFCVTSL, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28248,7 +28770,7 @@ var opcodeTable = [...]opInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28261,7 +28783,7 @@ var opcodeTable = [...]opInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28274,7 +28796,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVF, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28290,7 +28812,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVF, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, @@ -28306,7 +28828,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28321,7 +28843,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28335,7 +28857,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28349,7 +28871,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28443,7 +28965,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFMVDX, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28456,7 +28978,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFCVTDW, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28469,7 +28991,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AFCVTDL, reg: regInfo{ inputs: []inputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28485,7 +29007,7 @@ var opcodeTable = [...]opInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28498,7 +29020,7 @@ var opcodeTable = [...]opInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28537,7 +29059,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVD, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB }, outputs: []outputInfo{ {0, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 @@ -28553,7 +29075,7 @@ var opcodeTable = [...]opInfo{ asm: riscv.AMOVD, reg: regInfo{ inputs: []inputInfo{ - {0, 9223372037928517622}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 SB + {0, 9223372037861408758}, // SP X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 SB {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, }, @@ -28569,7 +29091,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28584,7 +29106,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28598,7 +29120,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -28612,7 +29134,7 @@ var opcodeTable = [...]opInfo{ {1, 9223372034707292160}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 }, outputs: []outputInfo{ - {0, 1073741812}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 + {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30 }, }, }, @@ -30218,10 +30740,10 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "RLLGconst", + name: "RLLconst", auxType: auxInt8, argLen: 1, - asm: s390x.ARLLG, + asm: s390x.ARLL, reg: regInfo{ inputs: []inputInfo{ {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 @@ -30232,13 +30754,16 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "RLLconst", - auxType: auxInt8, - argLen: 1, - asm: s390x.ARLL, + name: "RXSBG", + auxType: auxS390XRotateParams, + argLen: 2, + resultInArg0: true, + clobberFlags: true, + asm: s390x.ARXSBG, reg: regInfo{ inputs: []inputInfo{ {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 + {1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 }, outputs: []outputInfo{ {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 @@ -30246,16 +30771,14 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "RXSBG", + name: "RISBGZ", auxType: auxS390XRotateParams, - argLen: 2, - resultInArg0: true, + argLen: 1, clobberFlags: true, - asm: s390x.ARXSBG, + asm: s390x.ARISBGZ, reg: regInfo{ inputs: []inputInfo{ {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 - {1, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 }, outputs: []outputInfo{ {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 @@ -31386,18 +31909,17 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLstatic", - auxType: auxSymOff, + auxType: auxCallOff, argLen: 1, clobberFlags: true, call: true, - symEffect: SymNone, reg: regInfo{ clobbers: 4294933503, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 g R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 }, }, { name: "CALLclosure", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, clobberFlags: true, call: true, @@ -31411,7 +31933,7 @@ var opcodeTable = [...]opInfo{ }, { name: "CALLinter", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, clobberFlags: true, call: true, @@ -31727,11 +32249,24 @@ var opcodeTable = [...]opInfo{ reg: regInfo{}, }, { - name: "LAOfloor", + name: "LAN", argLen: 3, clobberFlags: true, hasSideEffects: true, - asm: s390x.ALAO, + asm: s390x.ALAN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 4295023614}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP SB + {1, 56319}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP + }, + }, + }, + { + name: "LANfloor", + argLen: 3, + clobberFlags: true, + hasSideEffects: true, + asm: s390x.ALAN, reg: regInfo{ inputs: []inputInfo{ {0, 2}, // R1 @@ -31741,11 +32276,24 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "LANfloor", + name: "LAO", argLen: 3, clobberFlags: true, hasSideEffects: true, - asm: s390x.ALAN, + asm: s390x.ALAO, + reg: regInfo{ + inputs: []inputInfo{ + {0, 4295023614}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP SB + {1, 56319}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14 SP + }, + }, + }, + { + name: "LAOfloor", + argLen: 3, + clobberFlags: true, + hasSideEffects: true, + asm: s390x.ALAO, reg: regInfo{ inputs: []inputInfo{ {0, 2}, // R1 @@ -32031,18 +32579,17 @@ var opcodeTable = [...]opInfo{ }, { - name: "LoweredStaticCall", - auxType: auxSymOff, - argLen: 1, - call: true, - symEffect: SymNone, + name: "LoweredStaticCall", + auxType: auxCallOff, + argLen: 1, + call: true, reg: regInfo{ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g }, }, { name: "LoweredClosureCall", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, call: true, reg: regInfo{ @@ -32055,7 +32602,7 @@ var opcodeTable = [...]opInfo{ }, { name: "LoweredInterCall", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, call: true, reg: regInfo{ @@ -34708,6 +35255,11 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "Dereference", + argLen: 2, + generic: true, + }, + { name: "Store", auxType: auxTyp, argLen: 3, @@ -34773,27 +35325,47 @@ var opcodeTable = [...]opInfo{ }, { name: "ClosureCall", - auxType: auxInt64, + auxType: auxCallOff, argLen: 3, call: true, generic: true, }, { - name: "StaticCall", - auxType: auxSymOff, - argLen: 1, - call: true, - symEffect: SymNone, - generic: true, + name: "StaticCall", + auxType: auxCallOff, + argLen: 1, + call: true, + generic: true, }, { name: "InterCall", - auxType: auxInt64, + auxType: auxCallOff, argLen: 2, call: true, generic: true, }, { + name: "ClosureLECall", + auxType: auxCallOff, + argLen: -1, + call: true, + generic: true, + }, + { + name: "StaticLECall", + auxType: auxCallOff, + argLen: -1, + call: true, + generic: true, + }, + { + name: "InterLECall", + auxType: auxCallOff, + argLen: -1, + call: true, + generic: true, + }, + { name: "SignExt8to16", argLen: 1, generic: true, @@ -35295,6 +35867,23 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "SelectN", + auxType: auxInt64, + argLen: 1, + generic: true, + }, + { + name: "SelectNAddr", + auxType: auxInt64, + argLen: 1, + generic: true, + }, + { + name: "MakeResult", + argLen: -1, + generic: true, + }, + { name: "AtomicLoad8", argLen: 2, generic: true, @@ -35320,6 +35909,11 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "AtomicLoadAcq64", + argLen: 2, + generic: true, + }, + { name: "AtomicStore8", argLen: 3, hasSideEffects: true, @@ -35350,6 +35944,12 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "AtomicStoreRel64", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { name: "AtomicExchange32", argLen: 3, hasSideEffects: true, @@ -35398,12 +35998,24 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "AtomicAnd32", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { name: "AtomicOr8", argLen: 3, hasSideEffects: true, generic: true, }, { + name: "AtomicOr32", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { name: "AtomicAdd32Variant", argLen: 3, hasSideEffects: true, @@ -35416,6 +36028,54 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "AtomicExchange32Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicExchange64Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicCompareAndSwap32Variant", + argLen: 4, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicCompareAndSwap64Variant", + argLen: 4, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicAnd8Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicAnd32Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicOr8Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { + name: "AtomicOr32Variant", + argLen: 3, + hasSideEffects: true, + generic: true, + }, + { name: "Clobber", auxType: auxSymOff, argLen: 0, @@ -35808,7 +36468,7 @@ var registersRISCV64 = [...]Register{ {0, riscv.REG_X0, -1, "X0"}, {1, riscv.REGSP, -1, "SP"}, {2, riscv.REG_X3, 0, "X3"}, - {3, riscv.REGG, -1, "g"}, + {3, riscv.REG_X4, -1, "X4"}, {4, riscv.REG_X5, 1, "X5"}, {5, riscv.REG_X6, 2, "X6"}, {6, riscv.REG_X7, 3, "X7"}, @@ -35831,10 +36491,10 @@ var registersRISCV64 = [...]Register{ {23, riscv.REG_X24, 20, "X24"}, {24, riscv.REG_X25, 21, "X25"}, {25, riscv.REG_X26, 22, "X26"}, - {26, riscv.REG_X27, 23, "X27"}, - {27, riscv.REG_X28, 24, "X28"}, - {28, riscv.REG_X29, 25, "X29"}, - {29, riscv.REG_X30, 26, "X30"}, + {26, riscv.REGG, -1, "g"}, + {27, riscv.REG_X28, 23, "X28"}, + {28, riscv.REG_X29, 24, "X29"}, + {29, riscv.REG_X30, 25, "X30"}, {30, riscv.REG_X31, -1, "X31"}, {31, riscv.REG_F0, -1, "F0"}, {32, riscv.REG_F1, -1, "F1"}, @@ -35870,7 +36530,7 @@ var registersRISCV64 = [...]Register{ {62, riscv.REG_F31, -1, "F31"}, {63, 0, -1, "SB"}, } -var gpRegMaskRISCV64 = regMask(1073741812) +var gpRegMaskRISCV64 = regMask(1006632948) var fpRegMaskRISCV64 = regMask(9223372034707292160) var specialRegMaskRISCV64 = regMask(0) var framepointerRegRISCV64 = int8(-1) diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go index ce7d689f93..8a2e7c09bc 100644 --- a/src/cmd/compile/internal/ssa/prove.go +++ b/src/cmd/compile/internal/ssa/prove.go @@ -1082,7 +1082,7 @@ func addLocalInductiveFacts(ft *factsTable, b *Block) { return nil } pred, child := b.Preds[1].b, b - for ; pred != nil; pred = uniquePred(pred) { + for ; pred != nil; pred, child = uniquePred(pred), pred { if pred.Kind != BlockIf { continue } diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 64c6aed3e7..0339b073ae 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -625,9 +625,6 @@ func (s *regAllocState) init(f *Func) { s.f.fe.Fatalf(src.NoXPos, "arch %s not implemented", s.f.Config.arch) } } - if s.f.Config.use387 { - s.allocatable &^= 1 << 15 // X7 disallowed (one 387 register is used as scratch space during SSE->387 generation in ../x86/387.go) - } // Linear scan register allocation can be influenced by the order in which blocks appear. // Decouple the register allocation order from the generated block order. @@ -1015,8 +1012,8 @@ func (s *regAllocState) regalloc(f *Func) { // Copy phi ops into new schedule. b.Values = append(b.Values, phis...) - // Third pass - pick registers for phis whose inputs - // were not in a register. + // Third pass - pick registers for phis whose input + // was not in a register in the primary predecessor. for i, v := range phis { if !s.values[v.ID].needReg { continue @@ -1024,10 +1021,25 @@ func (s *regAllocState) regalloc(f *Func) { if phiRegs[i] != noRegister { continue } - if s.f.Config.use387 && v.Type.IsFloat() { - continue // 387 can't handle floats in registers between blocks - } m := s.compatRegs(v.Type) &^ phiUsed &^ s.used + // If one of the other inputs of v is in a register, and the register is available, + // select this register, which can save some unnecessary copies. + for i, pe := range b.Preds { + if int32(i) == idx { + continue + } + ri := noRegister + for _, er := range s.endRegs[pe.b.ID] { + if er.v == s.orig[v.Args[i].ID] { + ri = er.r + break + } + } + if ri != noRegister && m>>ri&1 != 0 { + m = regMask(1) << ri + break + } + } if m != 0 { r := pickReg(m) phiRegs[i] = r @@ -1125,7 +1137,19 @@ func (s *regAllocState) regalloc(f *Func) { } rp, ok := s.f.getHome(v.ID).(*Register) if !ok { - continue + // If v is not assigned a register, pick a register assigned to one of v's inputs. + // Hopefully v will get assigned that register later. + // If the inputs have allocated register information, add it to desired, + // which may reduce spill or copy operations when the register is available. + for _, a := range v.Args { + rp, ok = s.f.getHome(a.ID).(*Register) + if ok { + break + } + } + if !ok { + continue + } } desired.add(v.Args[pidx].ID, register(rp.num)) } @@ -1528,11 +1552,6 @@ func (s *regAllocState) regalloc(f *Func) { s.freeUseRecords = u } - // Spill any values that can't live across basic block boundaries. - if s.f.Config.use387 { - s.freeRegs(s.f.Config.fpRegMask) - } - // If we are approaching a merge point and we are the primary // predecessor of it, find live values that we use soon after // the merge point and promote them to registers now. @@ -1562,10 +1581,20 @@ func (s *regAllocState) regalloc(f *Func) { continue } v := s.orig[vid] - if s.f.Config.use387 && v.Type.IsFloat() { - continue // 387 can't handle floats in registers between blocks - } m := s.compatRegs(v.Type) &^ s.used + // Used desired register if available. + outerloop: + for _, e := range desired.entries { + if e.ID != v.ID { + continue + } + for _, r := range e.regs { + if r != noRegister && m>>r&1 != 0 { + m = regMask(1) << r + break outerloop + } + } + } if m&^desired.avoid != 0 { m &^= desired.avoid } @@ -1627,7 +1656,9 @@ func (s *regAllocState) regalloc(f *Func) { // we'll rematerialize during the merge. continue } - //fmt.Printf("live-at-end spill for %s at %s\n", s.orig[e.ID], b) + if s.f.pass.debug > regDebug { + fmt.Printf("live-at-end spill for %s at %s\n", s.orig[e.ID], b) + } spill := s.makeSpill(s.orig[e.ID], b) s.spillLive[b.ID] = append(s.spillLive[b.ID], spill.ID) } @@ -2498,7 +2529,7 @@ func (s *regAllocState) computeLive() { for _, b := range f.Blocks { fmt.Printf(" %s:", b) for _, x := range s.live[b.ID] { - fmt.Printf(" v%d", x.ID) + fmt.Printf(" v%d(%d)", x.ID, x.dist) for _, e := range s.desired[b.ID].entries { if e.ID != x.ID { continue diff --git a/src/cmd/compile/internal/ssa/regalloc_test.go b/src/cmd/compile/internal/ssa/regalloc_test.go index bb8be5e7ac..d990cac47b 100644 --- a/src/cmd/compile/internal/ssa/regalloc_test.go +++ b/src/cmd/compile/internal/ssa/regalloc_test.go @@ -68,7 +68,7 @@ func TestNoGetgLoadReg(t *testing.T) { Exit("v16"), ), Bloc("b2", - Valu("v12", OpARM64CALLstatic, types.TypeMem, 0, nil, "v1"), + Valu("v12", OpARM64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "v1"), Goto("b3"), ), ) @@ -99,7 +99,7 @@ func TestSpillWithLoop(t *testing.T) { ), Bloc("loop", Valu("memphi", OpPhi, types.TypeMem, 0, nil, "mem", "call"), - Valu("call", OpAMD64CALLstatic, types.TypeMem, 0, nil, "memphi"), + Valu("call", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "memphi"), Valu("test", OpAMD64CMPBconst, types.TypeFlags, 0, nil, "cond"), Eq("test", "next", "exit"), ), @@ -140,12 +140,12 @@ func TestSpillMove1(t *testing.T) { Bloc("exit1", // store before call, y is available in a register Valu("mem2", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem"), - Valu("mem3", OpAMD64CALLstatic, types.TypeMem, 0, nil, "mem2"), + Valu("mem3", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem2"), Exit("mem3"), ), Bloc("exit2", // store after call, y must be loaded from a spill location - Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, nil, "mem"), + Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"), Valu("mem5", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem4"), Exit("mem5"), ), @@ -188,13 +188,13 @@ func TestSpillMove2(t *testing.T) { ), Bloc("exit1", // store after call, y must be loaded from a spill location - Valu("mem2", OpAMD64CALLstatic, types.TypeMem, 0, nil, "mem"), + Valu("mem2", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"), Valu("mem3", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem2"), Exit("mem3"), ), Bloc("exit2", // store after call, y must be loaded from a spill location - Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, nil, "mem"), + Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"), Valu("mem5", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem4"), Exit("mem5"), ), diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 09f94ef53e..24efd38fb7 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -212,30 +212,20 @@ func isSigned(t *types.Type) bool { // mergeSym merges two symbolic offsets. There is no real merging of // offsets, we just pick the non-nil one. -func mergeSym(x, y interface{}) interface{} { +func mergeSym(x, y Sym) Sym { if x == nil { return y } if y == nil { return x } - panic(fmt.Sprintf("mergeSym with two non-nil syms %s %s", x, y)) + panic(fmt.Sprintf("mergeSym with two non-nil syms %v %v", x, y)) } -func canMergeSym(x, y interface{}) bool { +func canMergeSym(x, y Sym) bool { return x == nil || y == nil } -func mergeSymTyped(x, y Sym) Sym { - if x == nil { - return y - } - if y == nil { - return x - } - panic(fmt.Sprintf("mergeSym with two non-nil syms %v %v", x, y)) -} - // canMergeLoadClobber reports whether the load can be merged into target without // invalidating the schedule. // It also checks that the other non-load argument x is something we @@ -393,15 +383,10 @@ func canMergeLoad(target, load *Value) bool { return true } -// symNamed reports whether sym's name is name. -func symNamed(sym Sym, name string) bool { - return sym.String() == name -} - -// isSameSym reports whether sym is the same as the given named symbol -func isSameSym(sym interface{}, name string) bool { - s, ok := sym.(fmt.Stringer) - return ok && s.String() == name +// isSameCall reports whether sym is the same as the given named symbol +func isSameCall(sym interface{}, name string) bool { + fn := sym.(*AuxCall).Fn + return fn != nil && fn.String() == name } // nlz returns the number of leading zeros. @@ -427,12 +412,6 @@ func nto(x int64) int64 { return int64(ntz64(^x)) } -// log2 returns logarithm in base 2 of uint64(n), with log2(0) = -1. -// Rounds down. -func log2(n int64) int64 { - return int64(bits.Len64(uint64(n))) - 1 -} - // logX returns logarithm of n base 2. // n must be a positive power of 2 (isPowerOfTwoX returns true). func log8(n int8) int64 { @@ -454,10 +433,7 @@ func log2uint32(n int64) int64 { return int64(bits.Len32(uint32(n))) - 1 } -// isPowerOfTwo reports whether n is a power of 2. -func isPowerOfTwo(n int64) bool { - return n > 0 && n&(n-1) == 0 -} +// isPowerOfTwo functions report whether n is a power of 2. func isPowerOfTwo8(n int8) bool { return n > 0 && n&(n-1) == 0 } @@ -713,6 +689,9 @@ func auxToSym(i interface{}) Sym { func auxToType(i interface{}) *types.Type { return i.(*types.Type) } +func auxToCall(i interface{}) *AuxCall { + return i.(*AuxCall) +} func auxToS390xCCMask(i interface{}) s390x.CCMask { return i.(s390x.CCMask) } @@ -726,6 +705,9 @@ func stringToAux(s string) interface{} { func symToAux(s Sym) interface{} { return s } +func callToAux(s *AuxCall) interface{} { + return s +} func typeToAux(t *types.Type) interface{} { return t } @@ -743,7 +725,7 @@ func uaddOvf(a, b int64) bool { // de-virtualize an InterCall // 'sym' is the symbol for the itab -func devirt(v *Value, sym Sym, offset int64) *obj.LSym { +func devirt(v *Value, aux interface{}, sym Sym, offset int64) *AuxCall { f := v.Block.Func n, ok := sym.(*obj.LSym) if !ok { @@ -757,9 +739,43 @@ func devirt(v *Value, sym Sym, offset int64) *obj.LSym { f.Warnl(v.Pos, "couldn't de-virtualize call") } } + if lsym == nil { + return nil + } + va := aux.(*AuxCall) + return StaticAuxCall(lsym, va.args, va.results) +} + +// de-virtualize an InterLECall +// 'sym' is the symbol for the itab +func devirtLESym(v *Value, aux interface{}, sym Sym, offset int64) *obj.LSym { + n, ok := sym.(*obj.LSym) + if !ok { + return nil + } + + f := v.Block.Func + lsym := f.fe.DerefItab(n, offset) + if f.pass.debug > 0 { + if lsym != nil { + f.Warnl(v.Pos, "de-virtualizing call") + } else { + f.Warnl(v.Pos, "couldn't de-virtualize call") + } + } + if lsym == nil { + return nil + } return lsym } +func devirtLECall(v *Value, sym *obj.LSym) *Value { + v.Op = OpStaticLECall + v.Aux.(*AuxCall).Fn = sym + v.RemoveArg(0) + return v +} + // isSamePtr reports whether p1 and p2 point to the same address. func isSamePtr(p1, p2 *Value) bool { if p1 == p2 { @@ -1321,6 +1337,182 @@ func hasSmallRotate(c *Config) bool { } } +func newPPC64ShiftAuxInt(sh, mb, me, sz int64) int32 { + if sh < 0 || sh >= sz { + panic("PPC64 shift arg sh out of range") + } + if mb < 0 || mb >= sz { + panic("PPC64 shift arg mb out of range") + } + if me < 0 || me >= sz { + panic("PPC64 shift arg me out of range") + } + return int32(sh<<16 | mb<<8 | me) +} + +func GetPPC64Shiftsh(auxint int64) int64 { + return int64(int8(auxint >> 16)) +} + +func GetPPC64Shiftmb(auxint int64) int64 { + return int64(int8(auxint >> 8)) +} + +func GetPPC64Shiftme(auxint int64) int64 { + return int64(int8(auxint)) +} + +// Test if this value can encoded as a mask for a rlwinm like +// operation. Masks can also extend from the msb and wrap to +// the lsb too. That is, the valid masks are 32 bit strings +// of the form: 0..01..10..0 or 1..10..01..1 or 1...1 +func isPPC64WordRotateMask(v64 int64) bool { + // Isolate rightmost 1 (if none 0) and add. + v := uint32(v64) + vp := (v & -v) + v + // Likewise, for the wrapping case. + vn := ^v + vpn := (vn & -vn) + vn + return (v&vp == 0 || vn&vpn == 0) && v != 0 +} + +// Compress mask and and shift into single value of the form +// me | mb<<8 | rotate<<16 | nbits<<24 where me and mb can +// be used to regenerate the input mask. +func encodePPC64RotateMask(rotate, mask, nbits int64) int64 { + var mb, me, mbn, men int + + // Determine boundaries and then decode them + if mask == 0 || ^mask == 0 || rotate >= nbits { + panic("Invalid PPC64 rotate mask") + } else if nbits == 32 { + mb = bits.LeadingZeros32(uint32(mask)) + me = 32 - bits.TrailingZeros32(uint32(mask)) + mbn = bits.LeadingZeros32(^uint32(mask)) + men = 32 - bits.TrailingZeros32(^uint32(mask)) + } else { + mb = bits.LeadingZeros64(uint64(mask)) + me = 64 - bits.TrailingZeros64(uint64(mask)) + mbn = bits.LeadingZeros64(^uint64(mask)) + men = 64 - bits.TrailingZeros64(^uint64(mask)) + } + // Check for a wrapping mask (e.g bits at 0 and 63) + if mb == 0 && me == int(nbits) { + // swap the inverted values + mb, me = men, mbn + } + + return int64(me) | int64(mb<<8) | int64(rotate<<16) | int64(nbits<<24) +} + +// The inverse operation of encodePPC64RotateMask. The values returned as +// mb and me satisfy the POWER ISA definition of MASK(x,y) where MASK(mb,me) = mask. +func DecodePPC64RotateMask(sauxint int64) (rotate, mb, me int64, mask uint64) { + auxint := uint64(sauxint) + rotate = int64((auxint >> 16) & 0xFF) + mb = int64((auxint >> 8) & 0xFF) + me = int64((auxint >> 0) & 0xFF) + nbits := int64((auxint >> 24) & 0xFF) + mask = ((1 << uint(nbits-mb)) - 1) ^ ((1 << uint(nbits-me)) - 1) + if mb > me { + mask = ^mask + } + if nbits == 32 { + mask = uint64(uint32(mask)) + } + + // Fixup ME to match ISA definition. The second argument to MASK(..,me) + // is inclusive. + me = (me - 1) & (nbits - 1) + return +} + +// This verifies that the mask is a set of +// consecutive bits including the least +// significant bit. +func isPPC64ValidShiftMask(v int64) bool { + if (v != 0) && ((v+1)&v) == 0 { + return true + } + return false +} + +func getPPC64ShiftMaskLength(v int64) int64 { + return int64(bits.Len64(uint64(v))) +} + +// Decompose a shift right into an equivalent rotate/mask, +// and return mask & m. +func mergePPC64RShiftMask(m, s, nbits int64) int64 { + smask := uint64((1<<uint(nbits))-1) >> uint(s) + return m & int64(smask) +} + +// Combine (ANDconst [m] (SRWconst [s])) into (RLWINM [y]) or return 0 +func mergePPC64AndSrwi(m, s int64) int64 { + mask := mergePPC64RShiftMask(m, s, 32) + if !isPPC64WordRotateMask(mask) { + return 0 + } + return encodePPC64RotateMask(32-s, mask, 32) +} + +// Test if a shift right feeding into a CLRLSLDI can be merged into RLWINM. +// Return the encoded RLWINM constant, or 0 if they cannot be merged. +func mergePPC64ClrlsldiSrw(sld, srw int64) int64 { + mask_1 := uint64(0xFFFFFFFF >> uint(srw)) + // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left. + mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld))) + + // Rewrite mask to apply after the final left shift. + mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(sld)) + + r_1 := 32 - srw + r_2 := GetPPC64Shiftsh(sld) + r_3 := (r_1 + r_2) & 31 // This can wrap. + + if uint64(uint32(mask_3)) != mask_3 || mask_3 == 0 { + return 0 + } + return encodePPC64RotateMask(int64(r_3), int64(mask_3), 32) +} + +// Test if a RLWINM feeding into a CLRLSLDI can be merged into RLWINM. Return +// the encoded RLWINM constant, or 0 if they cannot be merged. +func mergePPC64ClrlsldiRlwinm(sld int32, rlw int64) int64 { + r_1, _, _, mask_1 := DecodePPC64RotateMask(rlw) + // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left. + mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld))) + + // combine the masks, and adjust for the final left shift. + mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(int64(sld))) + r_2 := GetPPC64Shiftsh(int64(sld)) + r_3 := (r_1 + r_2) & 31 // This can wrap. + + // Verify the result is still a valid bitmask of <= 32 bits. + if !isPPC64WordRotateMask(int64(mask_3)) || uint64(uint32(mask_3)) != mask_3 { + return 0 + } + return encodePPC64RotateMask(r_3, int64(mask_3), 32) +} + +// Compute the encoded RLWINM constant from combining (SLDconst [sld] (SRWconst [srw] x)), +// or return 0 if they cannot be combined. +func mergePPC64SldiSrw(sld, srw int64) int64 { + if sld > srw || srw >= 32 { + return 0 + } + mask_r := uint32(0xFFFFFFFF) >> uint(srw) + mask_l := uint32(0xFFFFFFFF) >> uint(sld) + mask := (mask_r & mask_l) << uint(sld) + return encodePPC64RotateMask((32-srw+sld)&31, int64(mask), 32) +} + +// Convenience function to rotate a 32 bit constant value by another constant. +func rotateLeft32(v, rotate int64) int64 { + return int64(bits.RotateLeft32(uint32(v), int(rotate))) +} + // encodes the lsb and width for arm(64) bitfield ops into the expected auxInt format. func armBFAuxInt(lsb, width int64) arm64BitField { if lsb < 0 || lsb > 63 { @@ -1345,7 +1537,7 @@ func (bfc arm64BitField) getARM64BFwidth() int64 { // checks if mask >> rshift applied at lsb is a valid arm64 bitfield op mask. func isARM64BFMask(lsb, mask, rshift int64) bool { shiftedMask := int64(uint64(mask) >> uint64(rshift)) - return shiftedMask != 0 && isPowerOfTwo(shiftedMask+1) && nto(shiftedMask)+lsb < 64 + return shiftedMask != 0 && isPowerOfTwo64(shiftedMask+1) && nto(shiftedMask)+lsb < 64 } // returns the bitfield width of mask >> rshift for arm64 bitfield ops @@ -1377,23 +1569,23 @@ func registerizable(b *Block, typ *types.Type) bool { } // needRaceCleanup reports whether this call to racefuncenter/exit isn't needed. -func needRaceCleanup(sym Sym, v *Value) bool { +func needRaceCleanup(sym *AuxCall, v *Value) bool { f := v.Block.Func if !f.Config.Race { return false } - if !symNamed(sym, "runtime.racefuncenter") && !symNamed(sym, "runtime.racefuncexit") { + if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncenterfp") && !isSameCall(sym, "runtime.racefuncexit") { return false } for _, b := range f.Blocks { for _, v := range b.Values { switch v.Op { case OpStaticCall: - // Check for racefuncenter will encounter racefuncexit and vice versa. + // Check for racefuncenter/racefuncenterfp will encounter racefuncexit and vice versa. // Allow calls to panic* - s := v.Aux.(fmt.Stringer).String() + s := v.Aux.(*AuxCall).Fn.String() switch s { - case "runtime.racefuncenter", "runtime.racefuncexit", + case "runtime.racefuncenter", "runtime.racefuncenterfp", "runtime.racefuncexit", "runtime.panicdivide", "runtime.panicwrap", "runtime.panicshift": continue @@ -1409,7 +1601,7 @@ func needRaceCleanup(sym Sym, v *Value) bool { } } } - if symNamed(sym, "runtime.racefuncenter") { + if isSameCall(sym, "runtime.racefuncenter") { // If we're removing racefuncenter, remove its argument as well. if v.Args[0].Op != OpStore { return false diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go index fc1e0541b2..2acdccd568 100644 --- a/src/cmd/compile/internal/ssa/rewrite386.go +++ b/src/cmd/compile/internal/ssa/rewrite386.go @@ -1027,6 +1027,19 @@ func rewriteValue386_Op386ADDLconst(v *Value) bool { v.AddArg(x) return true } + // match: (ADDLconst [c] x:(SP)) + // result: (LEAL [c] x) + for { + c := auxIntToInt32(v.AuxInt) + x := v_0 + if x.Op != OpSP { + break + } + v.reset(Op386LEAL) + v.AuxInt = int32ToAuxInt(c) + v.AddArg(x) + return true + } // match: (ADDLconst [c] (LEAL1 [d] {s} x y)) // cond: is32Bit(int64(c)+int64(d)) // result: (LEAL1 [c+d] {s} x y) @@ -1179,7 +1192,7 @@ func rewriteValue386_Op386ADDLconstmodify(v *Value) bool { } // match: (ADDLconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ADDLconstmodify [valoff1.addOffset32(off2)] {mergeSymTyped(sym1,sym2)} base mem) + // result: (ADDLconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { valoff1 := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1195,7 +1208,7 @@ func rewriteValue386_Op386ADDLconstmodify(v *Value) bool { } v.reset(Op386ADDLconstmodify) v.AuxInt = valAndOffToAuxInt(valoff1.addOffset32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -1231,7 +1244,7 @@ func rewriteValue386_Op386ADDLload(v *Value) bool { } // match: (ADDLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ADDLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (ADDLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1248,7 +1261,7 @@ func rewriteValue386_Op386ADDLload(v *Value) bool { } v.reset(Op386ADDLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -1284,7 +1297,7 @@ func rewriteValue386_Op386ADDLmodify(v *Value) bool { } // match: (ADDLmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ADDLmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (ADDLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1301,7 +1314,7 @@ func rewriteValue386_Op386ADDLmodify(v *Value) bool { } v.reset(Op386ADDLmodify) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -1310,10 +1323,8 @@ func rewriteValue386_Op386ADDLmodify(v *Value) bool { func rewriteValue386_Op386ADDSD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (ADDSD x l:(MOVSDload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (ADDSDload x [off] {sym} ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -1326,7 +1337,7 @@ func rewriteValue386_Op386ADDSD(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(Op386ADDSDload) @@ -1369,7 +1380,7 @@ func rewriteValue386_Op386ADDSDload(v *Value) bool { } // match: (ADDSDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ADDSDload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (ADDSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1386,7 +1397,7 @@ func rewriteValue386_Op386ADDSDload(v *Value) bool { } v.reset(Op386ADDSDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -1395,10 +1406,8 @@ func rewriteValue386_Op386ADDSDload(v *Value) bool { func rewriteValue386_Op386ADDSS(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (ADDSS x l:(MOVSSload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (ADDSSload x [off] {sym} ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -1411,7 +1420,7 @@ func rewriteValue386_Op386ADDSS(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(Op386ADDSSload) @@ -1454,7 +1463,7 @@ func rewriteValue386_Op386ADDSSload(v *Value) bool { } // match: (ADDSSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ADDSSload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (ADDSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1471,7 +1480,7 @@ func rewriteValue386_Op386ADDSSload(v *Value) bool { } v.reset(Op386ADDSSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -1615,7 +1624,7 @@ func rewriteValue386_Op386ANDLconstmodify(v *Value) bool { } // match: (ANDLconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ANDLconstmodify [valoff1.addOffset32(off2)] {mergeSymTyped(sym1,sym2)} base mem) + // result: (ANDLconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { valoff1 := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1631,7 +1640,7 @@ func rewriteValue386_Op386ANDLconstmodify(v *Value) bool { } v.reset(Op386ANDLconstmodify) v.AuxInt = valAndOffToAuxInt(valoff1.addOffset32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -1667,7 +1676,7 @@ func rewriteValue386_Op386ANDLload(v *Value) bool { } // match: (ANDLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ANDLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (ANDLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1684,7 +1693,7 @@ func rewriteValue386_Op386ANDLload(v *Value) bool { } v.reset(Op386ANDLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -1720,7 +1729,7 @@ func rewriteValue386_Op386ANDLmodify(v *Value) bool { } // match: (ANDLmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ANDLmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (ANDLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -1737,7 +1746,7 @@ func rewriteValue386_Op386ANDLmodify(v *Value) bool { } v.reset(Op386ANDLmodify) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2640,10 +2649,8 @@ func rewriteValue386_Op386CMPWload(v *Value) bool { func rewriteValue386_Op386DIVSD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (DIVSD x l:(MOVSDload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (DIVSDload x [off] {sym} ptr mem) for { x := v_0 @@ -2655,7 +2662,7 @@ func rewriteValue386_Op386DIVSD(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(Op386DIVSDload) @@ -2696,7 +2703,7 @@ func rewriteValue386_Op386DIVSDload(v *Value) bool { } // match: (DIVSDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (DIVSDload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (DIVSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2713,7 +2720,7 @@ func rewriteValue386_Op386DIVSDload(v *Value) bool { } v.reset(Op386DIVSDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -2722,10 +2729,8 @@ func rewriteValue386_Op386DIVSDload(v *Value) bool { func rewriteValue386_Op386DIVSS(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (DIVSS x l:(MOVSSload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (DIVSSload x [off] {sym} ptr mem) for { x := v_0 @@ -2737,7 +2742,7 @@ func rewriteValue386_Op386DIVSS(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(Op386DIVSSload) @@ -2778,7 +2783,7 @@ func rewriteValue386_Op386DIVSSload(v *Value) bool { } // match: (DIVSSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (DIVSSload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (DIVSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2795,7 +2800,7 @@ func rewriteValue386_Op386DIVSSload(v *Value) bool { } v.reset(Op386DIVSSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -2851,7 +2856,7 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } // match: (LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL [off1+off2] {mergeSymTyped(sym1,sym2)} x) + // result: (LEAL [off1+off2] {mergeSym(sym1,sym2)} x) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2866,13 +2871,13 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } v.reset(Op386LEAL) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg(x) return true } // match: (LEAL [off1] {sym1} (LEAL1 [off2] {sym2} x y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL1 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2888,13 +2893,13 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } v.reset(Op386LEAL1) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAL [off1] {sym1} (LEAL2 [off2] {sym2} x y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL2 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2910,13 +2915,13 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } v.reset(Op386LEAL2) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAL [off1] {sym1} (LEAL4 [off2] {sym2} x y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL4 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2932,13 +2937,13 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } v.reset(Op386LEAL4) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAL [off1] {sym1} (LEAL8 [off2] {sym2} x y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL8 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2954,7 +2959,7 @@ func rewriteValue386_Op386LEAL(v *Value) bool { } v.reset(Op386LEAL8) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3046,7 +3051,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } // match: (LEAL1 [off1] {sym1} (LEAL [off2] {sym2} x) y) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB - // result: (LEAL1 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3063,7 +3068,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } v.reset(Op386LEAL1) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3071,7 +3076,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } // match: (LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} y y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL2 [off1+off2] {mergeSymTyped(sym1, sym2)} x y) + // result: (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3088,7 +3093,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } v.reset(Op386LEAL2) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3096,7 +3101,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } // match: (LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} x y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (LEAL2 [off1+off2] {mergeSymTyped(sym1, sym2)} y x) + // result: (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} y x) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3120,7 +3125,7 @@ func rewriteValue386_Op386LEAL1(v *Value) bool { } v.reset(Op386LEAL2) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(y, x) return true } @@ -3220,7 +3225,7 @@ func rewriteValue386_Op386LEAL2(v *Value) bool { } // match: (LEAL2 [off1] {sym1} (LEAL [off2] {sym2} x) y) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB - // result: (LEAL2 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3236,7 +3241,7 @@ func rewriteValue386_Op386LEAL2(v *Value) bool { } v.reset(Op386LEAL2) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3329,7 +3334,7 @@ func rewriteValue386_Op386LEAL4(v *Value) bool { } // match: (LEAL4 [off1] {sym1} (LEAL [off2] {sym2} x) y) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB - // result: (LEAL4 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3345,7 +3350,7 @@ func rewriteValue386_Op386LEAL4(v *Value) bool { } v.reset(Op386LEAL4) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3422,7 +3427,7 @@ func rewriteValue386_Op386LEAL8(v *Value) bool { } // match: (LEAL8 [off1] {sym1} (LEAL [off2] {sym2} x) y) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB - // result: (LEAL8 [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3438,7 +3443,7 @@ func rewriteValue386_Op386LEAL8(v *Value) bool { } v.reset(Op386LEAL8) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -3517,7 +3522,7 @@ func rewriteValue386_Op386MOVBLSXload(v *Value) bool { } // match: (MOVBLSXload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBLSXload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBLSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3533,7 +3538,7 @@ func rewriteValue386_Op386MOVBLSXload(v *Value) bool { } v.reset(Op386MOVBLSXload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3629,7 +3634,7 @@ func rewriteValue386_Op386MOVBload(v *Value) bool { } // match: (MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3645,7 +3650,7 @@ func rewriteValue386_Op386MOVBload(v *Value) bool { } v.reset(Op386MOVBload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3749,7 +3754,7 @@ func rewriteValue386_Op386MOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3766,7 +3771,7 @@ func rewriteValue386_Op386MOVBstore(v *Value) bool { } v.reset(Op386MOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4060,7 +4065,7 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { } // match: (MOVBstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4076,13 +4081,13 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { } v.reset(Op386MOVBstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem)) // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) - // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p mem) + // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem) for { c := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -4100,14 +4105,14 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { break } v.reset(Op386MOVWstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem)) // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) - // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p mem) + // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p mem) for { a := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -4125,14 +4130,14 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { break } v.reset(Op386MOVWstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem)) // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x) - // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p0 mem) + // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem) for { c := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -4151,14 +4156,14 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { break } v.reset(Op386MOVWstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p0, mem) return true } // match: (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem)) // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 1) && clobber(x) - // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), int32(a.Off()))] {s} p0 mem) + // result: (MOVWstoreconst [makeValAndOff32(int32(a.Val()&0xff | c.Val()<<8), a.Off32())] {s} p0 mem) for { a := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -4177,7 +4182,7 @@ func rewriteValue386_Op386MOVBstoreconst(v *Value) bool { break } v.reset(Op386MOVWstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xff|c.Val()<<8), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p0, mem) return true @@ -4232,7 +4237,7 @@ func rewriteValue386_Op386MOVLload(v *Value) bool { } // match: (MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVLload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4248,7 +4253,7 @@ func rewriteValue386_Op386MOVLload(v *Value) bool { } v.reset(Op386MOVLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4318,7 +4323,7 @@ func rewriteValue386_Op386MOVLstore(v *Value) bool { } // match: (MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVLstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4335,7 +4340,7 @@ func rewriteValue386_Op386MOVLstore(v *Value) bool { } v.reset(Op386MOVLstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4727,7 +4732,7 @@ func rewriteValue386_Op386MOVLstoreconst(v *Value) bool { } // match: (MOVLstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVLstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVLstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4743,7 +4748,7 @@ func rewriteValue386_Op386MOVLstoreconst(v *Value) bool { } v.reset(Op386MOVLstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4797,7 +4802,7 @@ func rewriteValue386_Op386MOVSDload(v *Value) bool { } // match: (MOVSDload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVSDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVSDload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4813,7 +4818,7 @@ func rewriteValue386_Op386MOVSDload(v *Value) bool { } v.reset(Op386MOVSDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4849,7 +4854,7 @@ func rewriteValue386_Op386MOVSDstore(v *Value) bool { } // match: (MOVSDstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVSDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVSDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4866,7 +4871,7 @@ func rewriteValue386_Op386MOVSDstore(v *Value) bool { } v.reset(Op386MOVSDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4920,7 +4925,7 @@ func rewriteValue386_Op386MOVSSload(v *Value) bool { } // match: (MOVSSload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVSSload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVSSload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4936,7 +4941,7 @@ func rewriteValue386_Op386MOVSSload(v *Value) bool { } v.reset(Op386MOVSSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4972,7 +4977,7 @@ func rewriteValue386_Op386MOVSSstore(v *Value) bool { } // match: (MOVSSstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVSSstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVSSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4989,7 +4994,7 @@ func rewriteValue386_Op386MOVSSstore(v *Value) bool { } v.reset(Op386MOVSSstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -5068,7 +5073,7 @@ func rewriteValue386_Op386MOVWLSXload(v *Value) bool { } // match: (MOVWLSXload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWLSXload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWLSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5084,7 +5089,7 @@ func rewriteValue386_Op386MOVWLSXload(v *Value) bool { } v.reset(Op386MOVWLSXload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -5180,7 +5185,7 @@ func rewriteValue386_Op386MOVWload(v *Value) bool { } // match: (MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5196,7 +5201,7 @@ func rewriteValue386_Op386MOVWload(v *Value) bool { } v.reset(Op386MOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -5300,7 +5305,7 @@ func rewriteValue386_Op386MOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5317,7 +5322,7 @@ func rewriteValue386_Op386MOVWstore(v *Value) bool { } v.reset(Op386MOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -5460,7 +5465,7 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { } // match: (MOVWstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5476,13 +5481,13 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { } v.reset(Op386MOVWstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem)) // cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x) - // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p mem) + // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem) for { c := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -5500,14 +5505,14 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { break } v.reset(Op386MOVLstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem)) // cond: x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x) - // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p mem) + // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p mem) for { a := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -5525,14 +5530,14 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { break } v.reset(Op386MOVLstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem)) // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x) - // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p0 mem) + // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem) for { c := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -5551,14 +5556,14 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { break } v.reset(Op386MOVLstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p0, mem) return true } // match: (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem)) // cond: x.Uses == 1 && a.Off() == c.Off() && sequentialAddresses(p0, p1, 2) && clobber(x) - // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), int32(a.Off()))] {s} p0 mem) + // result: (MOVLstoreconst [makeValAndOff32(int32(a.Val()&0xffff | c.Val()<<16), a.Off32())] {s} p0 mem) for { a := auxIntToValAndOff(v.AuxInt) s := auxToSym(v.Aux) @@ -5577,7 +5582,7 @@ func rewriteValue386_Op386MOVWstoreconst(v *Value) bool { break } v.reset(Op386MOVLstoreconst) - v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), int32(a.Off()))) + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(a.Val()&0xffff|c.Val()<<16), a.Off32())) v.Aux = symToAux(s) v.AddArg2(p0, mem) return true @@ -6078,7 +6083,7 @@ func rewriteValue386_Op386MULLload(v *Value) bool { } // match: (MULLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MULLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (MULLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6095,7 +6100,7 @@ func rewriteValue386_Op386MULLload(v *Value) bool { } v.reset(Op386MULLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -6104,10 +6109,8 @@ func rewriteValue386_Op386MULLload(v *Value) bool { func rewriteValue386_Op386MULSD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (MULSD x l:(MOVSDload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (MULSDload x [off] {sym} ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -6120,7 +6123,7 @@ func rewriteValue386_Op386MULSD(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(Op386MULSDload) @@ -6163,7 +6166,7 @@ func rewriteValue386_Op386MULSDload(v *Value) bool { } // match: (MULSDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MULSDload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (MULSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6180,7 +6183,7 @@ func rewriteValue386_Op386MULSDload(v *Value) bool { } v.reset(Op386MULSDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -6189,10 +6192,8 @@ func rewriteValue386_Op386MULSDload(v *Value) bool { func rewriteValue386_Op386MULSS(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (MULSS x l:(MOVSSload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (MULSSload x [off] {sym} ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -6205,7 +6206,7 @@ func rewriteValue386_Op386MULSS(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(Op386MULSSload) @@ -6248,7 +6249,7 @@ func rewriteValue386_Op386MULSSload(v *Value) bool { } // match: (MULSSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MULSSload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (MULSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6265,7 +6266,7 @@ func rewriteValue386_Op386MULSSload(v *Value) bool { } v.reset(Op386MULSSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -6698,7 +6699,7 @@ func rewriteValue386_Op386ORLconstmodify(v *Value) bool { } // match: (ORLconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ORLconstmodify [valoff1.addOffset32(off2)] {mergeSymTyped(sym1,sym2)} base mem) + // result: (ORLconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { valoff1 := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6714,7 +6715,7 @@ func rewriteValue386_Op386ORLconstmodify(v *Value) bool { } v.reset(Op386ORLconstmodify) v.AuxInt = valAndOffToAuxInt(valoff1.addOffset32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -6750,7 +6751,7 @@ func rewriteValue386_Op386ORLload(v *Value) bool { } // match: (ORLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ORLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (ORLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6767,7 +6768,7 @@ func rewriteValue386_Op386ORLload(v *Value) bool { } v.reset(Op386ORLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -6803,7 +6804,7 @@ func rewriteValue386_Op386ORLmodify(v *Value) bool { } // match: (ORLmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (ORLmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (ORLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6820,7 +6821,7 @@ func rewriteValue386_Op386ORLmodify(v *Value) bool { } v.reset(Op386ORLmodify) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -8108,7 +8109,7 @@ func rewriteValue386_Op386SUBLload(v *Value) bool { } // match: (SUBLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (SUBLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (SUBLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8125,7 +8126,7 @@ func rewriteValue386_Op386SUBLload(v *Value) bool { } v.reset(Op386SUBLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -8161,7 +8162,7 @@ func rewriteValue386_Op386SUBLmodify(v *Value) bool { } // match: (SUBLmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (SUBLmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (SUBLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8178,7 +8179,7 @@ func rewriteValue386_Op386SUBLmodify(v *Value) bool { } v.reset(Op386SUBLmodify) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -8187,10 +8188,8 @@ func rewriteValue386_Op386SUBLmodify(v *Value) bool { func rewriteValue386_Op386SUBSD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (SUBSD x l:(MOVSDload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (SUBSDload x [off] {sym} ptr mem) for { x := v_0 @@ -8202,7 +8201,7 @@ func rewriteValue386_Op386SUBSD(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(Op386SUBSDload) @@ -8243,7 +8242,7 @@ func rewriteValue386_Op386SUBSDload(v *Value) bool { } // match: (SUBSDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (SUBSDload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (SUBSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8260,7 +8259,7 @@ func rewriteValue386_Op386SUBSDload(v *Value) bool { } v.reset(Op386SUBSDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -8269,10 +8268,8 @@ func rewriteValue386_Op386SUBSDload(v *Value) bool { func rewriteValue386_Op386SUBSS(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - config := b.Func.Config // match: (SUBSS x l:(MOVSSload [off] {sym} ptr mem)) - // cond: canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l) + // cond: canMergeLoadClobber(v, l, x) && clobber(l) // result: (SUBSSload x [off] {sym} ptr mem) for { x := v_0 @@ -8284,7 +8281,7 @@ func rewriteValue386_Op386SUBSS(v *Value) bool { sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] - if !(canMergeLoadClobber(v, l, x) && !config.use387 && clobber(l)) { + if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(Op386SUBSSload) @@ -8325,7 +8322,7 @@ func rewriteValue386_Op386SUBSSload(v *Value) bool { } // match: (SUBSSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (SUBSSload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (SUBSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8342,7 +8339,7 @@ func rewriteValue386_Op386SUBSSload(v *Value) bool { } v.reset(Op386SUBSSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -8549,7 +8546,7 @@ func rewriteValue386_Op386XORLconstmodify(v *Value) bool { } // match: (XORLconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (XORLconstmodify [valoff1.addOffset32(off2)] {mergeSymTyped(sym1,sym2)} base mem) + // result: (XORLconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { valoff1 := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8565,7 +8562,7 @@ func rewriteValue386_Op386XORLconstmodify(v *Value) bool { } v.reset(Op386XORLconstmodify) v.AuxInt = valAndOffToAuxInt(valoff1.addOffset32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -8601,7 +8598,7 @@ func rewriteValue386_Op386XORLload(v *Value) bool { } // match: (XORLload [off1] {sym1} val (LEAL [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (XORLload [off1+off2] {mergeSymTyped(sym1,sym2)} val base mem) + // result: (XORLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8618,7 +8615,7 @@ func rewriteValue386_Op386XORLload(v *Value) bool { } v.reset(Op386XORLload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -8654,7 +8651,7 @@ func rewriteValue386_Op386XORLmodify(v *Value) bool { } // match: (XORLmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) - // result: (XORLmodify [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (XORLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8671,7 +8668,7 @@ func rewriteValue386_Op386XORLmodify(v *Value) bool { } v.reset(Op386XORLmodify) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -8712,11 +8709,11 @@ func rewriteValue386_OpConst8(v *Value) bool { } func rewriteValue386_OpConstBool(v *Value) bool { // match: (ConstBool [c]) - // result: (MOVLconst [int32(b2i(c))]) + // result: (MOVLconst [b2i32(c)]) for { c := auxIntToBool(v.AuxInt) v.reset(Op386MOVLconst) - v.AuxInt = int32ToAuxInt(int32(b2i(c))) + v.AuxInt = int32ToAuxInt(b2i32(c)) return true } } @@ -10043,68 +10040,32 @@ func rewriteValue386_OpMove(v *Value) bool { func rewriteValue386_OpNeg32F(v *Value) bool { v_0 := v.Args[0] b := v.Block - config := b.Func.Config typ := &b.Func.Config.Types // match: (Neg32F x) - // cond: !config.use387 // result: (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))])) for { x := v_0 - if !(!config.use387) { - break - } v.reset(Op386PXOR) v0 := b.NewValue0(v.Pos, Op386MOVSSconst, typ.Float32) v0.AuxInt = float32ToAuxInt(float32(math.Copysign(0, -1))) v.AddArg2(x, v0) return true } - // match: (Neg32F x) - // cond: config.use387 - // result: (FCHS x) - for { - x := v_0 - if !(config.use387) { - break - } - v.reset(Op386FCHS) - v.AddArg(x) - return true - } - return false } func rewriteValue386_OpNeg64F(v *Value) bool { v_0 := v.Args[0] b := v.Block - config := b.Func.Config typ := &b.Func.Config.Types // match: (Neg64F x) - // cond: !config.use387 // result: (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)])) for { x := v_0 - if !(!config.use387) { - break - } v.reset(Op386PXOR) v0 := b.NewValue0(v.Pos, Op386MOVSDconst, typ.Float64) v0.AuxInt = float64ToAuxInt(math.Copysign(0, -1)) v.AddArg2(x, v0) return true } - // match: (Neg64F x) - // cond: config.use387 - // result: (FCHS x) - for { - x := v_0 - if !(config.use387) { - break - } - v.reset(Op386FCHS) - v.AddArg(x) - return true - } - return false } func rewriteValue386_OpNeq16(v *Value) bool { v_1 := v.Args[1] diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 89d64052fe..75d4ff7357 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -552,8 +552,7 @@ func rewriteValueAMD64(v *Value) bool { v.Op = OpAMD64ADDQ return true case OpAddr: - v.Op = OpAMD64LEAQ - return true + return rewriteValueAMD64_OpAddr(v) case OpAnd16: v.Op = OpAMD64ANDL return true @@ -573,34 +572,30 @@ func rewriteValueAMD64(v *Value) bool { return rewriteValueAMD64_OpAtomicAdd32(v) case OpAtomicAdd64: return rewriteValueAMD64_OpAtomicAdd64(v) + case OpAtomicAnd32: + return rewriteValueAMD64_OpAtomicAnd32(v) case OpAtomicAnd8: - v.Op = OpAMD64ANDBlock - return true + return rewriteValueAMD64_OpAtomicAnd8(v) case OpAtomicCompareAndSwap32: - v.Op = OpAMD64CMPXCHGLlock - return true + return rewriteValueAMD64_OpAtomicCompareAndSwap32(v) case OpAtomicCompareAndSwap64: - v.Op = OpAMD64CMPXCHGQlock - return true + return rewriteValueAMD64_OpAtomicCompareAndSwap64(v) case OpAtomicExchange32: return rewriteValueAMD64_OpAtomicExchange32(v) case OpAtomicExchange64: return rewriteValueAMD64_OpAtomicExchange64(v) case OpAtomicLoad32: - v.Op = OpAMD64MOVLatomicload - return true + return rewriteValueAMD64_OpAtomicLoad32(v) case OpAtomicLoad64: - v.Op = OpAMD64MOVQatomicload - return true + return rewriteValueAMD64_OpAtomicLoad64(v) case OpAtomicLoad8: - v.Op = OpAMD64MOVBatomicload - return true + return rewriteValueAMD64_OpAtomicLoad8(v) case OpAtomicLoadPtr: - v.Op = OpAMD64MOVQatomicload - return true + return rewriteValueAMD64_OpAtomicLoadPtr(v) + case OpAtomicOr32: + return rewriteValueAMD64_OpAtomicOr32(v) case OpAtomicOr8: - v.Op = OpAMD64ORBlock - return true + return rewriteValueAMD64_OpAtomicOr8(v) case OpAtomicStore32: return rewriteValueAMD64_OpAtomicStore32(v) case OpAtomicStore64: @@ -1478,16 +1473,16 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool { if l.Op != OpAMD64MOVLload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ADDLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -1629,53 +1624,53 @@ func rewriteValueAMD64_OpAMD64ADDLconst(v *Value) bool { return true } // match: (ADDLconst [c] x) - // cond: int32(c)==0 + // cond: c==0 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 - if !(int32(c) == 0) { + if !(c == 0) { break } v.copyOf(x) return true } // match: (ADDLconst [c] (MOVLconst [d])) - // result: (MOVLconst [int64(int32(c+d))]) + // result: (MOVLconst [c+d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) return true } // match: (ADDLconst [c] (ADDLconst [d] x)) - // result: (ADDLconst [int64(int32(c+d))] x) + // result: (ADDLconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64ADDLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpAMD64ADDLconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg(x) return true } // match: (ADDLconst [off] x:(SP)) // result: (LEAL [off] x) for { - off := v.AuxInt + off := auxIntToInt32(v.AuxInt) x := v_0 if x.Op != OpSP { break } v.reset(OpAMD64LEAL) - v.AuxInt = off + v.AuxInt = int32ToAuxInt(off) v.AddArg(x) return true } @@ -1706,24 +1701,24 @@ func rewriteValueAMD64_OpAMD64ADDLconstmodify(v *Value) bool { return true } // match: (ADDLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ADDLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ADDLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -1758,36 +1753,36 @@ func rewriteValueAMD64_OpAMD64ADDLload(v *Value) bool { return true } // match: (ADDLload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ADDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) // result: (ADDL x (MOVLf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSSstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSSstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -1829,25 +1824,25 @@ func rewriteValueAMD64_OpAMD64ADDLmodify(v *Value) bool { return true } // match: (ADDLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2067,16 +2062,16 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value) bool { if l.Op != OpAMD64MOVQload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ADDQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -2245,7 +2240,7 @@ func rewriteValueAMD64_OpAMD64ADDQconst(v *Value) bool { // match: (ADDQconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -2253,45 +2248,45 @@ func rewriteValueAMD64_OpAMD64ADDQconst(v *Value) bool { return true } // match: (ADDQconst [c] (MOVQconst [d])) - // result: (MOVQconst [c+d]) + // result: (MOVQconst [int64(c)+d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c + d + v.AuxInt = int64ToAuxInt(int64(c) + d) return true } // match: (ADDQconst [c] (ADDQconst [d] x)) - // cond: is32Bit(c+d) + // cond: is32Bit(int64(c)+int64(d)) // result: (ADDQconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64ADDQconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] - if !(is32Bit(c + d)) { + if !(is32Bit(int64(c) + int64(d))) { break } v.reset(OpAMD64ADDQconst) - v.AuxInt = c + d + v.AuxInt = int32ToAuxInt(c + d) v.AddArg(x) return true } // match: (ADDQconst [off] x:(SP)) // result: (LEAQ [off] x) for { - off := v.AuxInt + off := auxIntToInt32(v.AuxInt) x := v_0 if x.Op != OpSP { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + v.AuxInt = int32ToAuxInt(off) v.AddArg(x) return true } @@ -2322,24 +2317,24 @@ func rewriteValueAMD64_OpAMD64ADDQconstmodify(v *Value) bool { return true } // match: (ADDQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ADDQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ADDQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2374,36 +2369,36 @@ func rewriteValueAMD64_OpAMD64ADDQload(v *Value) bool { return true } // match: (ADDQload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDQload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ADDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) // result: (ADDQ x (MOVQf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSDstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSDstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -2445,25 +2440,25 @@ func rewriteValueAMD64_OpAMD64ADDQmodify(v *Value) bool { return true } // match: (ADDQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2482,16 +2477,16 @@ func rewriteValueAMD64_OpAMD64ADDSD(v *Value) bool { if l.Op != OpAMD64MOVSDload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ADDSDload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -2528,36 +2523,36 @@ func rewriteValueAMD64_OpAMD64ADDSDload(v *Value) bool { return true } // match: (ADDSDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDSDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ADDSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) // result: (ADDSD x (MOVQi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVQstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVQstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -2585,16 +2580,16 @@ func rewriteValueAMD64_OpAMD64ADDSS(v *Value) bool { if l.Op != OpAMD64MOVSSload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ADDSSload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -2631,36 +2626,36 @@ func rewriteValueAMD64_OpAMD64ADDSSload(v *Value) bool { return true } // match: (ADDSSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ADDSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ADDSSload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ADDSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) // result: (ADDSS x (MOVLi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVLstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVLstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -2757,16 +2752,16 @@ func rewriteValueAMD64_OpAMD64ANDL(v *Value) bool { if l.Op != OpAMD64MOVLload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ANDLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -2841,24 +2836,24 @@ func rewriteValueAMD64_OpAMD64ANDLconst(v *Value) bool { return true } // match: (ANDLconst [c] _) - // cond: int32(c)==0 + // cond: c==0 // result: (MOVLconst [0]) for { - c := v.AuxInt - if !(int32(c) == 0) { + c := auxIntToInt32(v.AuxInt) + if !(c == 0) { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (ANDLconst [c] x) - // cond: int32(c)==-1 + // cond: c==-1 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 - if !(int32(c) == -1) { + if !(c == -1) { break } v.copyOf(x) @@ -2867,13 +2862,13 @@ func rewriteValueAMD64_OpAMD64ANDLconst(v *Value) bool { // match: (ANDLconst [c] (MOVLconst [d])) // result: (MOVLconst [c&d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = c & d + v.AuxInt = int32ToAuxInt(c & d) return true } return false @@ -2903,24 +2898,24 @@ func rewriteValueAMD64_OpAMD64ANDLconstmodify(v *Value) bool { return true } // match: (ANDLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ANDLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ANDLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2955,36 +2950,36 @@ func rewriteValueAMD64_OpAMD64ANDLload(v *Value) bool { return true } // match: (ANDLload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ANDLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ANDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) // result: (ANDL x (MOVLf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSSstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSSstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -3026,25 +3021,25 @@ func rewriteValueAMD64_OpAMD64ANDLmodify(v *Value) bool { return true } // match: (ANDLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ANDLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -3078,7 +3073,7 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool { } // match: (ANDQ (MOVQconst [c]) x) // cond: isUint64PowerOfTwo(^c) && uint64(^c) >= 128 - // result: (BTRQconst [int8(log2(^c))] x) + // result: (BTRQconst [int8(log64(^c))] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVQconst { @@ -3090,7 +3085,7 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool { continue } v.reset(OpAMD64BTRQconst) - v.AuxInt = int8ToAuxInt(int8(log2(^c))) + v.AuxInt = int8ToAuxInt(int8(log64(^c))) v.AddArg(x) return true } @@ -3136,16 +3131,16 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool { if l.Op != OpAMD64MOVQload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ANDQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -3226,17 +3221,17 @@ func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool { // match: (ANDQconst [0] _) // result: (MOVQconst [0]) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (ANDQconst [-1] x) // result: x for { - if v.AuxInt != -1 { + if auxIntToInt32(v.AuxInt) != -1 { break } x := v_0 @@ -3244,15 +3239,15 @@ func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool { return true } // match: (ANDQconst [c] (MOVQconst [d])) - // result: (MOVQconst [c&d]) + // result: (MOVQconst [int64(c)&d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c & d + v.AuxInt = int64ToAuxInt(int64(c) & d) return true } return false @@ -3282,24 +3277,24 @@ func rewriteValueAMD64_OpAMD64ANDQconstmodify(v *Value) bool { return true } // match: (ANDQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ANDQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ANDQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3334,36 +3329,36 @@ func rewriteValueAMD64_OpAMD64ANDQload(v *Value) bool { return true } // match: (ANDQload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ANDQload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (ANDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) // result: (ANDQ x (MOVQf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSDstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSDstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -3405,25 +3400,25 @@ func rewriteValueAMD64_OpAMD64ANDQmodify(v *Value) bool { return true } // match: (ANDQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ANDQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ANDQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -3439,7 +3434,7 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool { break } t := v_0.Type - if v_0.AuxInt != 1<<8 { + if auxIntToInt32(v_0.AuxInt) != 1<<8 { break } v_0_0 := v_0.Args[0] @@ -3449,7 +3444,7 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool { x := v_0_0.Args[0] v.reset(OpAMD64BSFQ) v0 := b.NewValue0(v.Pos, OpAMD64ORQconst, t) - v0.AuxInt = 1 << 8 + v0.AuxInt = int32ToAuxInt(1 << 8) v0.AddArg(x) v.AddArg(v0) return true @@ -3461,7 +3456,7 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool { break } t := v_0.Type - if v_0.AuxInt != 1<<16 { + if auxIntToInt32(v_0.AuxInt) != 1<<16 { break } v_0_0 := v_0.Args[0] @@ -3471,7 +3466,7 @@ func rewriteValueAMD64_OpAMD64BSFQ(v *Value) bool { x := v_0_0.Args[0] v.reset(OpAMD64BSFQ) v0 := b.NewValue0(v.Pos, OpAMD64ORQconst, t) - v0.AuxInt = 1 << 16 + v0.AuxInt = int32ToAuxInt(1 << 16) v0.AddArg(x) v.AddArg(v0) return true @@ -3511,13 +3506,13 @@ func rewriteValueAMD64_OpAMD64BTCLconst(v *Value) bool { // match: (BTCLconst [c] (MOVLconst [d])) // result: (MOVLconst [d^(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = d ^ (1 << uint32(c)) + v.AuxInt = int32ToAuxInt(d ^ (1 << uint32(c))) return true } return false @@ -3547,24 +3542,24 @@ func rewriteValueAMD64_OpAMD64BTCLconstmodify(v *Value) bool { return true } // match: (BTCLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTCLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTCLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTCLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3597,25 +3592,25 @@ func rewriteValueAMD64_OpAMD64BTCLmodify(v *Value) bool { return true } // match: (BTCLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTCLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTCLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -3662,13 +3657,13 @@ func rewriteValueAMD64_OpAMD64BTCQconst(v *Value) bool { // match: (BTCQconst [c] (MOVQconst [d])) // result: (MOVQconst [d^(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = d ^ (1 << uint32(c)) + v.AuxInt = int64ToAuxInt(d ^ (1 << uint32(c))) return true } return false @@ -3698,24 +3693,24 @@ func rewriteValueAMD64_OpAMD64BTCQconstmodify(v *Value) bool { return true } // match: (BTCQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTCQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTCQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTCQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3748,25 +3743,25 @@ func rewriteValueAMD64_OpAMD64BTCQmodify(v *Value) bool { return true } // match: (BTCQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTCQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTCQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -3995,13 +3990,13 @@ func rewriteValueAMD64_OpAMD64BTRLconst(v *Value) bool { // match: (BTRLconst [c] (MOVLconst [d])) // result: (MOVLconst [d&^(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = d &^ (1 << uint32(c)) + v.AuxInt = int32ToAuxInt(d &^ (1 << uint32(c))) return true } return false @@ -4031,24 +4026,24 @@ func rewriteValueAMD64_OpAMD64BTRLconstmodify(v *Value) bool { return true } // match: (BTRLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTRLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTRLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTRLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4081,25 +4076,25 @@ func rewriteValueAMD64_OpAMD64BTRLmodify(v *Value) bool { return true } // match: (BTRLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTRLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTRLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4172,13 +4167,13 @@ func rewriteValueAMD64_OpAMD64BTRQconst(v *Value) bool { // match: (BTRQconst [c] (MOVQconst [d])) // result: (MOVQconst [d&^(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = d &^ (1 << uint32(c)) + v.AuxInt = int64ToAuxInt(d &^ (1 << uint32(c))) return true } return false @@ -4208,24 +4203,24 @@ func rewriteValueAMD64_OpAMD64BTRQconstmodify(v *Value) bool { return true } // match: (BTRQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTRQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTRQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTRQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4258,25 +4253,25 @@ func rewriteValueAMD64_OpAMD64BTRQmodify(v *Value) bool { return true } // match: (BTRQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTRQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTRQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4341,13 +4336,13 @@ func rewriteValueAMD64_OpAMD64BTSLconst(v *Value) bool { // match: (BTSLconst [c] (MOVLconst [d])) // result: (MOVLconst [d|(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = d | (1 << uint32(c)) + v.AuxInt = int32ToAuxInt(d | (1 << uint32(c))) return true } return false @@ -4377,24 +4372,24 @@ func rewriteValueAMD64_OpAMD64BTSLconstmodify(v *Value) bool { return true } // match: (BTSLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTSLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTSLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTSLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4427,25 +4422,25 @@ func rewriteValueAMD64_OpAMD64BTSLmodify(v *Value) bool { return true } // match: (BTSLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTSLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTSLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -4518,13 +4513,13 @@ func rewriteValueAMD64_OpAMD64BTSQconst(v *Value) bool { // match: (BTSQconst [c] (MOVQconst [d])) // result: (MOVQconst [d|(1<<uint32(c))]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = d | (1 << uint32(c)) + v.AuxInt = int64ToAuxInt(d | (1 << uint32(c))) return true } return false @@ -4554,24 +4549,24 @@ func rewriteValueAMD64_OpAMD64BTSQconstmodify(v *Value) bool { return true } // match: (BTSQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (BTSQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (BTSQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTSQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -4604,25 +4599,25 @@ func rewriteValueAMD64_OpAMD64BTSQmodify(v *Value) bool { return true } // match: (BTSQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (BTSQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64BTSQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -5539,7 +5534,7 @@ func rewriteValueAMD64_OpAMD64CMOVQEQ(v *Value) bool { if v_2_0_0.Op != OpAMD64ORQconst { break } - c := v_2_0_0.AuxInt + c := auxIntToInt32(v_2_0_0.AuxInt) if !(c != 0) { break } @@ -6776,8 +6771,8 @@ func rewriteValueAMD64_OpAMD64CMPB(v *Value) bool { if l.Op != OpAMD64MOVBload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] x := v_1 @@ -6785,8 +6780,8 @@ func rewriteValueAMD64_OpAMD64CMPB(v *Value) bool { break } v.reset(OpAMD64CMPBload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -6799,8 +6794,8 @@ func rewriteValueAMD64_OpAMD64CMPB(v *Value) bool { if l.Op != OpAMD64MOVBload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoad(v, l) && clobber(l)) { @@ -6808,8 +6803,8 @@ func rewriteValueAMD64_OpAMD64CMPB(v *Value) bool { } v.reset(OpAMD64InvertFlags) v0 := b.NewValue0(l.Pos, OpAMD64CMPBload, types.TypeFlags) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) v0.AddArg3(ptr, x, mem) v.AddArg(v0) return true @@ -6820,90 +6815,90 @@ func rewriteValueAMD64_OpAMD64CMPBconst(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (CMPBconst (MOVLconst [x]) [y]) - // cond: int8(x)==int8(y) + // cond: int8(x)==y // result: (FlagEQ) for { - y := v.AuxInt + y := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int8(x) == int8(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int8(x) == y) { break } v.reset(OpAMD64FlagEQ) return true } // match: (CMPBconst (MOVLconst [x]) [y]) - // cond: int8(x)<int8(y) && uint8(x)<uint8(y) + // cond: int8(x)<y && uint8(x)<uint8(y) // result: (FlagLT_ULT) for { - y := v.AuxInt + y := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int8(x) < int8(y) && uint8(x) < uint8(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int8(x) < y && uint8(x) < uint8(y)) { break } v.reset(OpAMD64FlagLT_ULT) return true } // match: (CMPBconst (MOVLconst [x]) [y]) - // cond: int8(x)<int8(y) && uint8(x)>uint8(y) + // cond: int8(x)<y && uint8(x)>uint8(y) // result: (FlagLT_UGT) for { - y := v.AuxInt + y := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int8(x) < int8(y) && uint8(x) > uint8(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int8(x) < y && uint8(x) > uint8(y)) { break } v.reset(OpAMD64FlagLT_UGT) return true } // match: (CMPBconst (MOVLconst [x]) [y]) - // cond: int8(x)>int8(y) && uint8(x)<uint8(y) + // cond: int8(x)>y && uint8(x)<uint8(y) // result: (FlagGT_ULT) for { - y := v.AuxInt + y := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int8(x) > int8(y) && uint8(x) < uint8(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int8(x) > y && uint8(x) < uint8(y)) { break } v.reset(OpAMD64FlagGT_ULT) return true } // match: (CMPBconst (MOVLconst [x]) [y]) - // cond: int8(x)>int8(y) && uint8(x)>uint8(y) + // cond: int8(x)>y && uint8(x)>uint8(y) // result: (FlagGT_UGT) for { - y := v.AuxInt + y := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int8(x) > int8(y) && uint8(x) > uint8(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int8(x) > y && uint8(x) > uint8(y)) { break } v.reset(OpAMD64FlagGT_UGT) return true } // match: (CMPBconst (ANDLconst _ [m]) [n]) - // cond: 0 <= int8(m) && int8(m) < int8(n) + // cond: 0 <= int8(m) && int8(m) < n // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64ANDLconst { break } - m := v_0.AuxInt - if !(0 <= int8(m) && int8(m) < int8(n)) { + m := auxIntToInt32(v_0.AuxInt) + if !(0 <= int8(m) && int8(m) < n) { break } v.reset(OpAMD64FlagLT_ULT) @@ -6913,7 +6908,7 @@ func rewriteValueAMD64_OpAMD64CMPBconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTB x y) for { - if v.AuxInt != 0 { + if auxIntToInt8(v.AuxInt) != 0 { break } a := v_0 @@ -6931,29 +6926,29 @@ func rewriteValueAMD64_OpAMD64CMPBconst(v *Value) bool { } // match: (CMPBconst a:(ANDLconst [c] x) [0]) // cond: a.Uses == 1 - // result: (TESTBconst [int64(int8(c))] x) + // result: (TESTBconst [int8(c)] x) for { - if v.AuxInt != 0 { + if auxIntToInt8(v.AuxInt) != 0 { break } a := v_0 if a.Op != OpAMD64ANDLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) x := a.Args[0] if !(a.Uses == 1) { break } v.reset(OpAMD64TESTBconst) - v.AuxInt = int64(int8(c)) + v.AuxInt = int8ToAuxInt(int8(c)) v.AddArg(x) return true } // match: (CMPBconst x [0]) // result: (TESTB x x) for { - if v.AuxInt != 0 { + if auxIntToInt8(v.AuxInt) != 0 { break } x := v_0 @@ -7012,24 +7007,24 @@ func rewriteValueAMD64_OpAMD64CMPBconstload(v *Value) bool { return true } // match: (CMPBconstload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (CMPBconstload [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (CMPBconstload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPBconstload) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -7062,46 +7057,46 @@ func rewriteValueAMD64_OpAMD64CMPBload(v *Value) bool { return true } // match: (CMPBload [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (CMPBload [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPBload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (CMPBload {sym} [off] ptr (MOVLconst [c]) mem) - // cond: validValAndOff(int64(int8(c)),off) - // result: (CMPBconstload {sym} [makeValAndOff(int64(int8(c)),off)] ptr mem) + // cond: validValAndOff(int64(int8(c)),int64(off)) + // result: (CMPBconstload {sym} [makeValAndOff32(int32(int8(c)),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 - if !(validValAndOff(int64(int8(c)), off)) { + if !(validValAndOff(int64(int8(c)), int64(off))) { break } v.reset(OpAMD64CMPBconstload) - v.AuxInt = makeValAndOff(int64(int8(c)), off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int8(c)), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -7162,8 +7157,8 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool { if l.Op != OpAMD64MOVLload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] x := v_1 @@ -7171,8 +7166,8 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool { break } v.reset(OpAMD64CMPLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -7185,8 +7180,8 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool { if l.Op != OpAMD64MOVLload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoad(v, l) && clobber(l)) { @@ -7194,8 +7189,8 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool { } v.reset(OpAMD64InvertFlags) v0 := b.NewValue0(l.Pos, OpAMD64CMPLload, types.TypeFlags) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) v0.AddArg3(ptr, x, mem) v.AddArg(v0) return true @@ -7206,75 +7201,75 @@ func rewriteValueAMD64_OpAMD64CMPLconst(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (CMPLconst (MOVLconst [x]) [y]) - // cond: int32(x)==int32(y) + // cond: x==y // result: (FlagEQ) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int32(x) == int32(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(x == y) { break } v.reset(OpAMD64FlagEQ) return true } // match: (CMPLconst (MOVLconst [x]) [y]) - // cond: int32(x)<int32(y) && uint32(x)<uint32(y) + // cond: x<y && uint32(x)<uint32(y) // result: (FlagLT_ULT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int32(x) < int32(y) && uint32(x) < uint32(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(x < y && uint32(x) < uint32(y)) { break } v.reset(OpAMD64FlagLT_ULT) return true } // match: (CMPLconst (MOVLconst [x]) [y]) - // cond: int32(x)<int32(y) && uint32(x)>uint32(y) + // cond: x<y && uint32(x)>uint32(y) // result: (FlagLT_UGT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int32(x) < int32(y) && uint32(x) > uint32(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(x < y && uint32(x) > uint32(y)) { break } v.reset(OpAMD64FlagLT_UGT) return true } // match: (CMPLconst (MOVLconst [x]) [y]) - // cond: int32(x)>int32(y) && uint32(x)<uint32(y) + // cond: x>y && uint32(x)<uint32(y) // result: (FlagGT_ULT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int32(x) > int32(y) && uint32(x) < uint32(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(x > y && uint32(x) < uint32(y)) { break } v.reset(OpAMD64FlagGT_ULT) return true } // match: (CMPLconst (MOVLconst [x]) [y]) - // cond: int32(x)>int32(y) && uint32(x)>uint32(y) + // cond: x>y && uint32(x)>uint32(y) // result: (FlagGT_UGT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int32(x) > int32(y) && uint32(x) > uint32(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(x > y && uint32(x) > uint32(y)) { break } v.reset(OpAMD64FlagGT_UGT) @@ -7284,11 +7279,11 @@ func rewriteValueAMD64_OpAMD64CMPLconst(v *Value) bool { // cond: 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64SHRLconst { break } - c := v_0.AuxInt + c := auxIntToInt8(v_0.AuxInt) if !(0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n)) { break } @@ -7296,15 +7291,15 @@ func rewriteValueAMD64_OpAMD64CMPLconst(v *Value) bool { return true } // match: (CMPLconst (ANDLconst _ [m]) [n]) - // cond: 0 <= int32(m) && int32(m) < int32(n) + // cond: 0 <= m && m < n // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64ANDLconst { break } - m := v_0.AuxInt - if !(0 <= int32(m) && int32(m) < int32(n)) { + m := auxIntToInt32(v_0.AuxInt) + if !(0 <= m && m < n) { break } v.reset(OpAMD64FlagLT_ULT) @@ -7314,7 +7309,7 @@ func rewriteValueAMD64_OpAMD64CMPLconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTL x y) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } a := v_0 @@ -7334,27 +7329,27 @@ func rewriteValueAMD64_OpAMD64CMPLconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTLconst [c] x) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } a := v_0 if a.Op != OpAMD64ANDLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) x := a.Args[0] if !(a.Uses == 1) { break } v.reset(OpAMD64TESTLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } // match: (CMPLconst x [0]) // result: (TESTL x x) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -7413,24 +7408,24 @@ func rewriteValueAMD64_OpAMD64CMPLconstload(v *Value) bool { return true } // match: (CMPLconstload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (CMPLconstload [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (CMPLconstload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPLconstload) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -7463,46 +7458,46 @@ func rewriteValueAMD64_OpAMD64CMPLload(v *Value) bool { return true } // match: (CMPLload [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (CMPLload [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (CMPLload {sym} [off] ptr (MOVLconst [c]) mem) - // cond: validValAndOff(c,off) - // result: (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem) + // cond: validValAndOff(int64(c),int64(off)) + // result: (CMPLconstload {sym} [makeValAndOff32(c,off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 - if !(validValAndOff(c, off)) { + if !(validValAndOff(int64(c), int64(off))) { break } v.reset(OpAMD64CMPLconstload) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c, off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -7570,11 +7565,11 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt + x := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { break } - y := v_1.AuxInt + y := auxIntToInt64(v_1.AuxInt) if !(x == y) { break } @@ -7588,11 +7583,11 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt + x := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { break } - y := v_1.AuxInt + y := auxIntToInt64(v_1.AuxInt) if !(x < y && uint64(x) < uint64(y)) { break } @@ -7606,11 +7601,11 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt + x := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { break } - y := v_1.AuxInt + y := auxIntToInt64(v_1.AuxInt) if !(x < y && uint64(x) > uint64(y)) { break } @@ -7624,11 +7619,11 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt + x := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { break } - y := v_1.AuxInt + y := auxIntToInt64(v_1.AuxInt) if !(x > y && uint64(x) < uint64(y)) { break } @@ -7642,11 +7637,11 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt + x := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { break } - y := v_1.AuxInt + y := auxIntToInt64(v_1.AuxInt) if !(x > y && uint64(x) > uint64(y)) { break } @@ -7661,8 +7656,8 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if l.Op != OpAMD64MOVQload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] x := v_1 @@ -7670,8 +7665,8 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { break } v.reset(OpAMD64CMPQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -7684,8 +7679,8 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { if l.Op != OpAMD64MOVQload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoad(v, l) && clobber(l)) { @@ -7693,8 +7688,8 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool { } v.reset(OpAMD64InvertFlags) v0 := b.NewValue0(l.Pos, OpAMD64CMPQload, types.TypeFlags) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) v0.AddArg3(ptr, x, mem) v.AddArg(v0) return true @@ -7739,75 +7734,75 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { return true } // match: (CMPQconst (MOVQconst [x]) [y]) - // cond: x==y + // cond: x==int64(y) // result: (FlagEQ) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt - if !(x == y) { + x := auxIntToInt64(v_0.AuxInt) + if !(x == int64(y)) { break } v.reset(OpAMD64FlagEQ) return true } // match: (CMPQconst (MOVQconst [x]) [y]) - // cond: x<y && uint64(x)<uint64(y) + // cond: x<int64(y) && uint64(x)<uint64(int64(y)) // result: (FlagLT_ULT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt - if !(x < y && uint64(x) < uint64(y)) { + x := auxIntToInt64(v_0.AuxInt) + if !(x < int64(y) && uint64(x) < uint64(int64(y))) { break } v.reset(OpAMD64FlagLT_ULT) return true } // match: (CMPQconst (MOVQconst [x]) [y]) - // cond: x<y && uint64(x)>uint64(y) + // cond: x<int64(y) && uint64(x)>uint64(int64(y)) // result: (FlagLT_UGT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt - if !(x < y && uint64(x) > uint64(y)) { + x := auxIntToInt64(v_0.AuxInt) + if !(x < int64(y) && uint64(x) > uint64(int64(y))) { break } v.reset(OpAMD64FlagLT_UGT) return true } // match: (CMPQconst (MOVQconst [x]) [y]) - // cond: x>y && uint64(x)<uint64(y) + // cond: x>int64(y) && uint64(x)<uint64(int64(y)) // result: (FlagGT_ULT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt - if !(x > y && uint64(x) < uint64(y)) { + x := auxIntToInt64(v_0.AuxInt) + if !(x > int64(y) && uint64(x) < uint64(int64(y))) { break } v.reset(OpAMD64FlagGT_ULT) return true } // match: (CMPQconst (MOVQconst [x]) [y]) - // cond: x>y && uint64(x)>uint64(y) + // cond: x>int64(y) && uint64(x)>uint64(int64(y)) // result: (FlagGT_UGT) for { - y := v.AuxInt + y := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - x := v_0.AuxInt - if !(x > y && uint64(x) > uint64(y)) { + x := auxIntToInt64(v_0.AuxInt) + if !(x > int64(y) && uint64(x) > uint64(int64(y))) { break } v.reset(OpAMD64FlagGT_UGT) @@ -7817,7 +7812,7 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: 0xFF < c // result: (FlagLT_ULT) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVBQZX || !(0xFF < c) { break } @@ -7828,33 +7823,22 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: 0xFFFF < c // result: (FlagLT_ULT) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVWQZX || !(0xFFFF < c) { break } v.reset(OpAMD64FlagLT_ULT) return true } - // match: (CMPQconst (MOVLQZX _) [c]) - // cond: 0xFFFFFFFF < c - // result: (FlagLT_ULT) - for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVLQZX || !(0xFFFFFFFF < c) { - break - } - v.reset(OpAMD64FlagLT_ULT) - return true - } // match: (CMPQconst (SHRQconst _ [c]) [n]) // cond: 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64SHRQconst { break } - c := v_0.AuxInt + c := auxIntToInt8(v_0.AuxInt) if !(0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n)) { break } @@ -7865,11 +7849,11 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: 0 <= m && m < n // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64ANDQconst { break } - m := v_0.AuxInt + m := auxIntToInt32(v_0.AuxInt) if !(0 <= m && m < n) { break } @@ -7880,11 +7864,11 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: 0 <= m && m < n // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64ANDLconst { break } - m := v_0.AuxInt + m := auxIntToInt32(v_0.AuxInt) if !(0 <= m && m < n) { break } @@ -7895,7 +7879,7 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTQ x y) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } a := v_0 @@ -7915,27 +7899,27 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTQconst [c] x) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } a := v_0 if a.Op != OpAMD64ANDQconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) x := a.Args[0] if !(a.Uses == 1) { break } v.reset(OpAMD64TESTQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } // match: (CMPQconst x [0]) // result: (TESTQ x x) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -7994,24 +7978,24 @@ func rewriteValueAMD64_OpAMD64CMPQconstload(v *Value) bool { return true } // match: (CMPQconstload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (CMPQconstload [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (CMPQconstload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPQconstload) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -8044,46 +8028,46 @@ func rewriteValueAMD64_OpAMD64CMPQload(v *Value) bool { return true } // match: (CMPQload [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (CMPQload [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (CMPQload {sym} [off] ptr (MOVQconst [c]) mem) - // cond: validValAndOff(c,off) - // result: (CMPQconstload {sym} [makeValAndOff(c,off)] ptr mem) + // cond: validValAndOff(c,int64(off)) + // result: (CMPQconstload {sym} [makeValAndOff64(c,int64(off))] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVQconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) mem := v_2 - if !(validValAndOff(c, off)) { + if !(validValAndOff(c, int64(off))) { break } v.reset(OpAMD64CMPQconstload) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff64(c, int64(off))) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -8144,8 +8128,8 @@ func rewriteValueAMD64_OpAMD64CMPW(v *Value) bool { if l.Op != OpAMD64MOVWload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] x := v_1 @@ -8153,8 +8137,8 @@ func rewriteValueAMD64_OpAMD64CMPW(v *Value) bool { break } v.reset(OpAMD64CMPWload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -8167,8 +8151,8 @@ func rewriteValueAMD64_OpAMD64CMPW(v *Value) bool { if l.Op != OpAMD64MOVWload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoad(v, l) && clobber(l)) { @@ -8176,8 +8160,8 @@ func rewriteValueAMD64_OpAMD64CMPW(v *Value) bool { } v.reset(OpAMD64InvertFlags) v0 := b.NewValue0(l.Pos, OpAMD64CMPWload, types.TypeFlags) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) v0.AddArg3(ptr, x, mem) v.AddArg(v0) return true @@ -8188,90 +8172,90 @@ func rewriteValueAMD64_OpAMD64CMPWconst(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (CMPWconst (MOVLconst [x]) [y]) - // cond: int16(x)==int16(y) + // cond: int16(x)==y // result: (FlagEQ) for { - y := v.AuxInt + y := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int16(x) == int16(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int16(x) == y) { break } v.reset(OpAMD64FlagEQ) return true } // match: (CMPWconst (MOVLconst [x]) [y]) - // cond: int16(x)<int16(y) && uint16(x)<uint16(y) + // cond: int16(x)<y && uint16(x)<uint16(y) // result: (FlagLT_ULT) for { - y := v.AuxInt + y := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int16(x) < int16(y) && uint16(x) < uint16(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int16(x) < y && uint16(x) < uint16(y)) { break } v.reset(OpAMD64FlagLT_ULT) return true } // match: (CMPWconst (MOVLconst [x]) [y]) - // cond: int16(x)<int16(y) && uint16(x)>uint16(y) + // cond: int16(x)<y && uint16(x)>uint16(y) // result: (FlagLT_UGT) for { - y := v.AuxInt + y := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int16(x) < int16(y) && uint16(x) > uint16(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int16(x) < y && uint16(x) > uint16(y)) { break } v.reset(OpAMD64FlagLT_UGT) return true } // match: (CMPWconst (MOVLconst [x]) [y]) - // cond: int16(x)>int16(y) && uint16(x)<uint16(y) + // cond: int16(x)>y && uint16(x)<uint16(y) // result: (FlagGT_ULT) for { - y := v.AuxInt + y := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int16(x) > int16(y) && uint16(x) < uint16(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int16(x) > y && uint16(x) < uint16(y)) { break } v.reset(OpAMD64FlagGT_ULT) return true } // match: (CMPWconst (MOVLconst [x]) [y]) - // cond: int16(x)>int16(y) && uint16(x)>uint16(y) + // cond: int16(x)>y && uint16(x)>uint16(y) // result: (FlagGT_UGT) for { - y := v.AuxInt + y := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - x := v_0.AuxInt - if !(int16(x) > int16(y) && uint16(x) > uint16(y)) { + x := auxIntToInt32(v_0.AuxInt) + if !(int16(x) > y && uint16(x) > uint16(y)) { break } v.reset(OpAMD64FlagGT_UGT) return true } // match: (CMPWconst (ANDLconst _ [m]) [n]) - // cond: 0 <= int16(m) && int16(m) < int16(n) + // cond: 0 <= int16(m) && int16(m) < n // result: (FlagLT_ULT) for { - n := v.AuxInt + n := auxIntToInt16(v.AuxInt) if v_0.Op != OpAMD64ANDLconst { break } - m := v_0.AuxInt - if !(0 <= int16(m) && int16(m) < int16(n)) { + m := auxIntToInt32(v_0.AuxInt) + if !(0 <= int16(m) && int16(m) < n) { break } v.reset(OpAMD64FlagLT_ULT) @@ -8281,7 +8265,7 @@ func rewriteValueAMD64_OpAMD64CMPWconst(v *Value) bool { // cond: a.Uses == 1 // result: (TESTW x y) for { - if v.AuxInt != 0 { + if auxIntToInt16(v.AuxInt) != 0 { break } a := v_0 @@ -8299,29 +8283,29 @@ func rewriteValueAMD64_OpAMD64CMPWconst(v *Value) bool { } // match: (CMPWconst a:(ANDLconst [c] x) [0]) // cond: a.Uses == 1 - // result: (TESTWconst [int64(int16(c))] x) + // result: (TESTWconst [int16(c)] x) for { - if v.AuxInt != 0 { + if auxIntToInt16(v.AuxInt) != 0 { break } a := v_0 if a.Op != OpAMD64ANDLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) x := a.Args[0] if !(a.Uses == 1) { break } v.reset(OpAMD64TESTWconst) - v.AuxInt = int64(int16(c)) + v.AuxInt = int16ToAuxInt(int16(c)) v.AddArg(x) return true } // match: (CMPWconst x [0]) // result: (TESTW x x) for { - if v.AuxInt != 0 { + if auxIntToInt16(v.AuxInt) != 0 { break } x := v_0 @@ -8380,24 +8364,24 @@ func rewriteValueAMD64_OpAMD64CMPWconstload(v *Value) bool { return true } // match: (CMPWconstload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (CMPWconstload [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (CMPWconstload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPWconstload) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -8430,46 +8414,46 @@ func rewriteValueAMD64_OpAMD64CMPWload(v *Value) bool { return true } // match: (CMPWload [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (CMPWload [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64CMPWload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (CMPWload {sym} [off] ptr (MOVLconst [c]) mem) - // cond: validValAndOff(int64(int16(c)),off) - // result: (CMPWconstload {sym} [makeValAndOff(int64(int16(c)),off)] ptr mem) + // cond: validValAndOff(int64(int16(c)),int64(off)) + // result: (CMPWconstload {sym} [makeValAndOff32(int32(int16(c)),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 - if !(validValAndOff(int64(int16(c)), off)) { + if !(validValAndOff(int64(int16(c)), int64(off))) { break } v.reset(OpAMD64CMPWconstload) - v.AuxInt = makeValAndOff(int64(int16(c)), off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(int16(c)), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -8481,25 +8465,25 @@ func rewriteValueAMD64_OpAMD64CMPXCHGLlock(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (CMPXCHGLlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (CMPXCHGLlock [off1+off2] {sym} ptr old new_ mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDQconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] old := v_1 new_ := v_2 mem := v_3 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64CMPXCHGLlock) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg4(ptr, old, new_, mem) return true } @@ -8511,25 +8495,25 @@ func rewriteValueAMD64_OpAMD64CMPXCHGQlock(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (CMPXCHGQlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (CMPXCHGQlock [off1+off2] {sym} ptr old new_ mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDQconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] old := v_1 new_ := v_2 mem := v_3 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64CMPXCHGQlock) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg4(ptr, old, new_, mem) return true } @@ -8547,16 +8531,16 @@ func rewriteValueAMD64_OpAMD64DIVSD(v *Value) bool { if l.Op != OpAMD64MOVSDload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64DIVSDload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -8589,25 +8573,25 @@ func rewriteValueAMD64_OpAMD64DIVSDload(v *Value) bool { return true } // match: (DIVSDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (DIVSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64DIVSDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -8625,16 +8609,16 @@ func rewriteValueAMD64_OpAMD64DIVSS(v *Value) bool { if l.Op != OpAMD64MOVSSload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64DIVSSload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -8667,25 +8651,25 @@ func rewriteValueAMD64_OpAMD64DIVSSload(v *Value) bool { return true } // match: (DIVSSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (DIVSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64DIVSSload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } @@ -9137,111 +9121,111 @@ func rewriteValueAMD64_OpAMD64LEAQ(v *Value) bool { break } // match: (LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ [off1+off2] {mergeSym(sym1,sym2)} x) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) x := v_0.Args[0] - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg(x) return true } // match: (LEAQ [off1] {sym1} (LEAQ1 [off2] {sym2} x y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ1 { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) y := v_0.Args[1] x := v_0.Args[0] - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64LEAQ1) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ [off1] {sym1} (LEAQ2 [off2] {sym2} x y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ2 { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) y := v_0.Args[1] x := v_0.Args[0] - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64LEAQ2) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ [off1] {sym1} (LEAQ4 [off2] {sym2} x y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ4 { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) y := v_0.Args[1] x := v_0.Args[0] - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64LEAQ4) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ8 { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) y := v_0.Args[1] x := v_0.Args[0] - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64LEAQ8) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -9332,68 +9316,68 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool { break } // match: (LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB // result: (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64LEAQ { continue } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) x := v_0.Args[0] y := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB) { continue } v.reset(OpAMD64LEAQ1) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } break } // match: (LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpAMD64LEAQ1 { continue } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) y := v_1.Args[1] - if y != v_1.Args[0] || !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if y != v_1.Args[0] || !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { continue } v.reset(OpAMD64LEAQ2) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } break } // match: (LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} x y)) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} y x) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpAMD64LEAQ1 { continue } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) _ = v_1.Args[1] v_1_0 := v_1.Args[0] v_1_1 := v_1.Args[1] @@ -9402,12 +9386,12 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool { continue } y := v_1_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { continue } v.reset(OpAMD64LEAQ2) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(y, x) return true } @@ -9418,7 +9402,7 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool { // cond: v.Aux == nil // result: (ADDQ x y) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -9510,86 +9494,86 @@ func rewriteValueAMD64_OpAMD64LEAQ2(v *Value) bool { return true } // match: (LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB // result: (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) x := v_0.Args[0] y := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB) { break } v.reset(OpAMD64LEAQ2) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ2 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) - // cond: is32Bit(off1+2*off2) && sym2 == nil + // cond: is32Bit(int64(off1)+2*int64(off2)) && sym2 == nil // result: (LEAQ4 [off1+2*off2] {sym1} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64LEAQ1 { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) y := v_1.Args[1] - if y != v_1.Args[0] || !(is32Bit(off1+2*off2) && sym2 == nil) { + if y != v_1.Args[0] || !(is32Bit(int64(off1)+2*int64(off2)) && sym2 == nil) { break } v.reset(OpAMD64LEAQ4) - v.AuxInt = off1 + 2*off2 - v.Aux = sym1 + v.AuxInt = int32ToAuxInt(off1 + 2*off2) + v.Aux = symToAux(sym1) v.AddArg2(x, y) return true } // match: (LEAQ2 [off] {sym} x (MOVQconst [scale])) - // cond: is32Bit(off+scale*2) - // result: (LEAQ [off+scale*2] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*2) + // result: (LEAQ [off+int32(scale)*2] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVQconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*2)) { + scale := auxIntToInt64(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*2)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*2) + v.Aux = symToAux(sym) v.AddArg(x) return true } // match: (LEAQ2 [off] {sym} x (MOVLconst [scale])) - // cond: is32Bit(off+scale*2) - // result: (LEAQ [off+scale*2] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*2) + // result: (LEAQ [off+int32(scale)*2] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVLconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*2)) { + scale := auxIntToInt32(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*2)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*2) + v.Aux = symToAux(sym) v.AddArg(x) return true } @@ -9657,86 +9641,86 @@ func rewriteValueAMD64_OpAMD64LEAQ4(v *Value) bool { return true } // match: (LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB // result: (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) x := v_0.Args[0] y := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB) { break } v.reset(OpAMD64LEAQ4) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ4 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) - // cond: is32Bit(off1+4*off2) && sym2 == nil + // cond: is32Bit(int64(off1)+4*int64(off2)) && sym2 == nil // result: (LEAQ8 [off1+4*off2] {sym1} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64LEAQ1 { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) y := v_1.Args[1] - if y != v_1.Args[0] || !(is32Bit(off1+4*off2) && sym2 == nil) { + if y != v_1.Args[0] || !(is32Bit(int64(off1)+4*int64(off2)) && sym2 == nil) { break } v.reset(OpAMD64LEAQ8) - v.AuxInt = off1 + 4*off2 - v.Aux = sym1 + v.AuxInt = int32ToAuxInt(off1 + 4*off2) + v.Aux = symToAux(sym1) v.AddArg2(x, y) return true } // match: (LEAQ4 [off] {sym} x (MOVQconst [scale])) - // cond: is32Bit(off+scale*4) - // result: (LEAQ [off+scale*4] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*4) + // result: (LEAQ [off+int32(scale)*4] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVQconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*4)) { + scale := auxIntToInt64(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*4)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*4 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*4) + v.Aux = symToAux(sym) v.AddArg(x) return true } // match: (LEAQ4 [off] {sym} x (MOVLconst [scale])) - // cond: is32Bit(off+scale*4) - // result: (LEAQ [off+scale*4] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*4) + // result: (LEAQ [off+int32(scale)*4] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVLconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*4)) { + scale := auxIntToInt32(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*4)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*4 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*4) + v.Aux = symToAux(sym) v.AddArg(x) return true } @@ -9788,64 +9772,64 @@ func rewriteValueAMD64_OpAMD64LEAQ8(v *Value) bool { return true } // match: (LEAQ8 [off1] {sym1} (LEAQ [off2] {sym2} x) y) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB // result: (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) x := v_0.Args[0] y := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB) { break } v.reset(OpAMD64LEAQ8) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (LEAQ8 [off] {sym} x (MOVQconst [scale])) - // cond: is32Bit(off+scale*8) - // result: (LEAQ [off+scale*8] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*8) + // result: (LEAQ [off+int32(scale)*8] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVQconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*8)) { + scale := auxIntToInt64(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*8)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*8 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*8) + v.Aux = symToAux(sym) v.AddArg(x) return true } // match: (LEAQ8 [off] {sym} x (MOVLconst [scale])) - // cond: is32Bit(off+scale*8) - // result: (LEAQ [off+scale*8] {sym} x) + // cond: is32Bit(int64(off)+int64(scale)*8) + // result: (LEAQ [off+int32(scale)*8] {sym} x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 if v_1.Op != OpAMD64MOVLconst { break } - scale := v_1.AuxInt - if !(is32Bit(off + scale*8)) { + scale := auxIntToInt32(v_1.AuxInt) + if !(is32Bit(int64(off) + int64(scale)*8)) { break } v.reset(OpAMD64LEAQ) - v.AuxInt = off + scale*8 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off + int32(scale)*8) + v.Aux = symToAux(sym) v.AddArg(x) return true } @@ -10001,24 +9985,24 @@ func rewriteValueAMD64_OpAMD64MOVBQSXload(v *Value) bool { return true } // match: (MOVBQSXload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVBQSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVBQSXload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -10160,45 +10144,45 @@ func rewriteValueAMD64_OpAMD64MOVBatomicload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVBatomicload [off1] {sym} (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVBatomicload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDQconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVBatomicload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVBatomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) - // result: (MOVBatomicload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) + // result: (MOVBatomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVBatomicload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -10250,81 +10234,81 @@ func rewriteValueAMD64_OpAMD64MOVBload(v *Value) bool { return true } // match: (MOVBload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVBload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVBload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVBload [off1] {sym} (ADDLconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVBload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVBload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVBload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVLconst [int64(read8(sym, off))]) + // result: (MOVLconst [int32(read8(sym, int64(off)))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(read8(sym, off)) + v.AuxInt = int32ToAuxInt(int32(read8(sym, int64(off)))) return true } return false @@ -10646,25 +10630,25 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { return true } // match: (MOVBstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVBstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -10672,12 +10656,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && clobber(x0) // result: (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x0 := v_2 - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i-1 || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] @@ -10685,14 +10669,14 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRWconst || x0_1.AuxInt != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && clobber(x0)) { + if x0_1.Op != OpAMD64SHRWconst || auxIntToInt8(x0_1.AuxInt) != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && clobber(x0)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, w.Type) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v0.AddArg(w) v.AddArg3(p, v0, mem) return true @@ -10701,25 +10685,25 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0) // result: (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 w := v_1 x0 := v_2 - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] p0 := x0.Args[0] x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRWconst || x0_1.AuxInt != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0)) { + if x0_1.Op != OpAMD64SHRWconst || auxIntToInt8(x0_1.AuxInt) != 8 || w != x0_1.Args[0] || !(x0.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x0)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, w.Type) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v0.AddArg(w) v.AddArg3(p0, v0, mem) return true @@ -10728,12 +10712,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2) // result: (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x2 := v_2 - if x2.Op != OpAMD64MOVBstore || x2.AuxInt != i-1 || x2.Aux != s { + if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i-1 || auxToSym(x2.Aux) != s { break } _ = x2.Args[2] @@ -10741,11 +10725,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x2_1 := x2.Args[1] - if x2_1.Op != OpAMD64SHRLconst || x2_1.AuxInt != 8 || w != x2_1.Args[0] { + if x2_1.Op != OpAMD64SHRLconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] { break } x1 := x2.Args[2] - if x1.Op != OpAMD64MOVBstore || x1.AuxInt != i-2 || x1.Aux != s { + if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s { break } _ = x1.Args[2] @@ -10753,11 +10737,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x1_1 := x1.Args[1] - if x1_1.Op != OpAMD64SHRLconst || x1_1.AuxInt != 16 || w != x1_1.Args[0] { + if x1_1.Op != OpAMD64SHRLconst || auxIntToInt8(x1_1.AuxInt) != 16 || w != x1_1.Args[0] { break } x0 := x1.Args[2] - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i-3 || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-3 || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] @@ -10765,12 +10749,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRLconst || x0_1.AuxInt != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) { + if x0_1.Op != OpAMD64SHRLconst || auxIntToInt8(x0_1.AuxInt) != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 3 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 3) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, w.Type) v0.AddArg(w) v.AddArg3(p, v0, mem) @@ -10780,43 +10764,43 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2) // result: (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p3 := v_0 w := v_1 x2 := v_2 - if x2.Op != OpAMD64MOVBstore || x2.AuxInt != i || x2.Aux != s { + if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i || auxToSym(x2.Aux) != s { break } _ = x2.Args[2] p2 := x2.Args[0] x2_1 := x2.Args[1] - if x2_1.Op != OpAMD64SHRLconst || x2_1.AuxInt != 8 || w != x2_1.Args[0] { + if x2_1.Op != OpAMD64SHRLconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] { break } x1 := x2.Args[2] - if x1.Op != OpAMD64MOVBstore || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { break } _ = x1.Args[2] p1 := x1.Args[0] x1_1 := x1.Args[1] - if x1_1.Op != OpAMD64SHRLconst || x1_1.AuxInt != 16 || w != x1_1.Args[0] { + if x1_1.Op != OpAMD64SHRLconst || auxIntToInt8(x1_1.AuxInt) != 16 || w != x1_1.Args[0] { break } x0 := x1.Args[2] - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] p0 := x0.Args[0] x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRLconst || x0_1.AuxInt != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2)) { + if x0_1.Op != OpAMD64SHRLconst || auxIntToInt8(x0_1.AuxInt) != 24 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && clobber(x0, x1, x2)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, w.Type) v0.AddArg(w) v.AddArg3(p0, v0, mem) @@ -10826,12 +10810,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6) // result: (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x6 := v_2 - if x6.Op != OpAMD64MOVBstore || x6.AuxInt != i-1 || x6.Aux != s { + if x6.Op != OpAMD64MOVBstore || auxIntToInt32(x6.AuxInt) != i-1 || auxToSym(x6.Aux) != s { break } _ = x6.Args[2] @@ -10839,11 +10823,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x6_1 := x6.Args[1] - if x6_1.Op != OpAMD64SHRQconst || x6_1.AuxInt != 8 || w != x6_1.Args[0] { + if x6_1.Op != OpAMD64SHRQconst || auxIntToInt8(x6_1.AuxInt) != 8 || w != x6_1.Args[0] { break } x5 := x6.Args[2] - if x5.Op != OpAMD64MOVBstore || x5.AuxInt != i-2 || x5.Aux != s { + if x5.Op != OpAMD64MOVBstore || auxIntToInt32(x5.AuxInt) != i-2 || auxToSym(x5.Aux) != s { break } _ = x5.Args[2] @@ -10851,11 +10835,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x5_1 := x5.Args[1] - if x5_1.Op != OpAMD64SHRQconst || x5_1.AuxInt != 16 || w != x5_1.Args[0] { + if x5_1.Op != OpAMD64SHRQconst || auxIntToInt8(x5_1.AuxInt) != 16 || w != x5_1.Args[0] { break } x4 := x5.Args[2] - if x4.Op != OpAMD64MOVBstore || x4.AuxInt != i-3 || x4.Aux != s { + if x4.Op != OpAMD64MOVBstore || auxIntToInt32(x4.AuxInt) != i-3 || auxToSym(x4.Aux) != s { break } _ = x4.Args[2] @@ -10863,11 +10847,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x4_1 := x4.Args[1] - if x4_1.Op != OpAMD64SHRQconst || x4_1.AuxInt != 24 || w != x4_1.Args[0] { + if x4_1.Op != OpAMD64SHRQconst || auxIntToInt8(x4_1.AuxInt) != 24 || w != x4_1.Args[0] { break } x3 := x4.Args[2] - if x3.Op != OpAMD64MOVBstore || x3.AuxInt != i-4 || x3.Aux != s { + if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != i-4 || auxToSym(x3.Aux) != s { break } _ = x3.Args[2] @@ -10875,11 +10859,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x3_1 := x3.Args[1] - if x3_1.Op != OpAMD64SHRQconst || x3_1.AuxInt != 32 || w != x3_1.Args[0] { + if x3_1.Op != OpAMD64SHRQconst || auxIntToInt8(x3_1.AuxInt) != 32 || w != x3_1.Args[0] { break } x2 := x3.Args[2] - if x2.Op != OpAMD64MOVBstore || x2.AuxInt != i-5 || x2.Aux != s { + if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i-5 || auxToSym(x2.Aux) != s { break } _ = x2.Args[2] @@ -10887,11 +10871,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x2_1 := x2.Args[1] - if x2_1.Op != OpAMD64SHRQconst || x2_1.AuxInt != 40 || w != x2_1.Args[0] { + if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 40 || w != x2_1.Args[0] { break } x1 := x2.Args[2] - if x1.Op != OpAMD64MOVBstore || x1.AuxInt != i-6 || x1.Aux != s { + if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i-6 || auxToSym(x1.Aux) != s { break } _ = x1.Args[2] @@ -10899,11 +10883,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x1_1 := x1.Args[1] - if x1_1.Op != OpAMD64SHRQconst || x1_1.AuxInt != 48 || w != x1_1.Args[0] { + if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 48 || w != x1_1.Args[0] { break } x0 := x1.Args[2] - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i-7 || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i-7 || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] @@ -10911,12 +10895,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRQconst || x0_1.AuxInt != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)) { + if x0_1.Op != OpAMD64SHRQconst || auxIntToInt8(x0_1.AuxInt) != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - 7 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 7) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, w.Type) v0.AddArg(w) v.AddArg3(p, v0, mem) @@ -10926,83 +10910,83 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6) // result: (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p7 := v_0 w := v_1 x6 := v_2 - if x6.Op != OpAMD64MOVBstore || x6.AuxInt != i || x6.Aux != s { + if x6.Op != OpAMD64MOVBstore || auxIntToInt32(x6.AuxInt) != i || auxToSym(x6.Aux) != s { break } _ = x6.Args[2] p6 := x6.Args[0] x6_1 := x6.Args[1] - if x6_1.Op != OpAMD64SHRQconst || x6_1.AuxInt != 8 || w != x6_1.Args[0] { + if x6_1.Op != OpAMD64SHRQconst || auxIntToInt8(x6_1.AuxInt) != 8 || w != x6_1.Args[0] { break } x5 := x6.Args[2] - if x5.Op != OpAMD64MOVBstore || x5.AuxInt != i || x5.Aux != s { + if x5.Op != OpAMD64MOVBstore || auxIntToInt32(x5.AuxInt) != i || auxToSym(x5.Aux) != s { break } _ = x5.Args[2] p5 := x5.Args[0] x5_1 := x5.Args[1] - if x5_1.Op != OpAMD64SHRQconst || x5_1.AuxInt != 16 || w != x5_1.Args[0] { + if x5_1.Op != OpAMD64SHRQconst || auxIntToInt8(x5_1.AuxInt) != 16 || w != x5_1.Args[0] { break } x4 := x5.Args[2] - if x4.Op != OpAMD64MOVBstore || x4.AuxInt != i || x4.Aux != s { + if x4.Op != OpAMD64MOVBstore || auxIntToInt32(x4.AuxInt) != i || auxToSym(x4.Aux) != s { break } _ = x4.Args[2] p4 := x4.Args[0] x4_1 := x4.Args[1] - if x4_1.Op != OpAMD64SHRQconst || x4_1.AuxInt != 24 || w != x4_1.Args[0] { + if x4_1.Op != OpAMD64SHRQconst || auxIntToInt8(x4_1.AuxInt) != 24 || w != x4_1.Args[0] { break } x3 := x4.Args[2] - if x3.Op != OpAMD64MOVBstore || x3.AuxInt != i || x3.Aux != s { + if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != i || auxToSym(x3.Aux) != s { break } _ = x3.Args[2] p3 := x3.Args[0] x3_1 := x3.Args[1] - if x3_1.Op != OpAMD64SHRQconst || x3_1.AuxInt != 32 || w != x3_1.Args[0] { + if x3_1.Op != OpAMD64SHRQconst || auxIntToInt8(x3_1.AuxInt) != 32 || w != x3_1.Args[0] { break } x2 := x3.Args[2] - if x2.Op != OpAMD64MOVBstore || x2.AuxInt != i || x2.Aux != s { + if x2.Op != OpAMD64MOVBstore || auxIntToInt32(x2.AuxInt) != i || auxToSym(x2.Aux) != s { break } _ = x2.Args[2] p2 := x2.Args[0] x2_1 := x2.Args[1] - if x2_1.Op != OpAMD64SHRQconst || x2_1.AuxInt != 40 || w != x2_1.Args[0] { + if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 40 || w != x2_1.Args[0] { break } x1 := x2.Args[2] - if x1.Op != OpAMD64MOVBstore || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBstore || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { break } _ = x1.Args[2] p1 := x1.Args[0] x1_1 := x1.Args[1] - if x1_1.Op != OpAMD64SHRQconst || x1_1.AuxInt != 48 || w != x1_1.Args[0] { + if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 48 || w != x1_1.Args[0] { break } x0 := x1.Args[2] - if x0.Op != OpAMD64MOVBstore || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBstore || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { break } mem := x0.Args[2] p0 := x0.Args[0] x0_1 := x0.Args[1] - if x0_1.Op != OpAMD64SHRQconst || x0_1.AuxInt != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6)) { + if x0_1.Op != OpAMD64SHRQconst || auxIntToInt8(x0_1.AuxInt) != 56 || w != x0_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && sequentialAddresses(p0, p1, 1) && sequentialAddresses(p1, p2, 1) && sequentialAddresses(p2, p3, 1) && sequentialAddresses(p3, p4, 1) && sequentialAddresses(p4, p5, 1) && sequentialAddresses(p5, p6, 1) && sequentialAddresses(p6, p7, 1) && clobber(x0, x1, x2, x3, x4, x5, x6)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, w.Type) v0.AddArg(w) v.AddArg3(p0, v0, mem) @@ -11012,15 +10996,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRWconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRWconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i-1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11028,8 +11012,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11037,15 +11021,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRLconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i-1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11053,8 +11037,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11062,15 +11046,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i-1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11078,8 +11062,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11087,12 +11071,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i+1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11100,12 +11084,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRWconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { + if x_1.Op != OpAMD64SHRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11113,12 +11097,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i+1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11126,12 +11110,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRLconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { + if x_1.Op != OpAMD64SHRLconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11139,12 +11123,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i+1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i+1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11152,12 +11136,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRQconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { + if x_1.Op != OpAMD64SHRQconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -11165,16 +11149,16 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 if v_1.Op != OpAMD64SHRLconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i-1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11182,12 +11166,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } w0 := x.Args[1] - if w0.Op != OpAMD64SHRLconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { + if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v.AddArg3(p, w0, mem) return true } @@ -11195,16 +11179,16 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i-1 || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11212,12 +11196,12 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v.AddArg3(p, w0, mem) return true } @@ -11225,15 +11209,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRWconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRWconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11242,8 +11226,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11251,15 +11235,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRLconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11268,8 +11252,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11277,15 +11261,15 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 8 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 8 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -11294,8 +11278,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11303,23 +11287,23 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p0 := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p1 := x.Args[0] x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRWconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { + if x_1.Op != OpAMD64SHRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11327,23 +11311,23 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p0 := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p1 := x.Args[0] x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRLconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { + if x_1.Op != OpAMD64SHRLconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11351,23 +11335,23 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p0 := v_0 w := v_1 x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p1 := x.Args[0] x_1 := x.Args[1] - if x_1.Op != OpAMD64SHRQconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { + if x_1.Op != OpAMD64SHRQconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -11375,27 +11359,27 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 if v_1.Op != OpAMD64SHRLconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p0 := x.Args[0] w0 := x.Args[1] - if w0.Op != OpAMD64SHRLconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { + if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w0, mem) return true } @@ -11403,27 +11387,27 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x) // result: (MOVWstore [i] {s} p0 w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVBstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVBstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p0 := x.Args[0] w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 1) && clobber(x)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w0, mem) return true } @@ -11431,19 +11415,19 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { // cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) // result: (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x1 := v_1 if x1.Op != OpAMD64MOVBload { break } - j := x1.AuxInt - s2 := x1.Aux + j := auxIntToInt32(x1.AuxInt) + s2 := auxToSym(x1.Aux) mem := x1.Args[1] p2 := x1.Args[0] mem2 := v_2 - if mem2.Op != OpAMD64MOVBstore || mem2.AuxInt != i-1 || mem2.Aux != s { + if mem2.Op != OpAMD64MOVBstore || auxIntToInt32(mem2.AuxInt) != i-1 || auxToSym(mem2.Aux) != s { break } _ = mem2.Args[2] @@ -11451,7 +11435,7 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } x2 := mem2.Args[1] - if x2.Op != OpAMD64MOVBload || x2.AuxInt != j-1 || x2.Aux != s2 { + if x2.Op != OpAMD64MOVBload || auxIntToInt32(x2.AuxInt) != j-1 || auxToSym(x2.Aux) != s2 { break } _ = x2.Args[1] @@ -11459,57 +11443,57 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = i - 1 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 1) + v.Aux = symToAux(s) v0 := b.NewValue0(x2.Pos, OpAMD64MOVWload, typ.UInt16) - v0.AuxInt = j - 1 - v0.Aux = s2 + v0.AuxInt = int32ToAuxInt(j - 1) + v0.Aux = symToAux(s2) v0.AddArg2(p2, mem) v.AddArg3(p, v0, mem) return true } // match: (MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVBstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVBstore [off1] {sym} (ADDLconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVBstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVBstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -11540,117 +11524,117 @@ func rewriteValueAMD64_OpAMD64MOVBstoreconst(v *Value) bool { return true } // match: (MOVBstoreconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) + // result: (MOVBstoreconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off)) { break } v.reset(OpAMD64MOVBstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 1 == ValAndOff(c).Off() && clobber(x) - // result: (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem) + // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) + // result: (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem) for { - c := v.AuxInt - s := v.Aux + c := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVBstoreconst { break } - a := x.AuxInt - if x.Aux != s { + a := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+1 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVWstoreconst) - v.AuxInt = makeValAndOff(ValAndOff(a).Val()&0xff|ValAndOff(c).Val()<<8, ValAndOff(a).Off()) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xff|c.Val()<<8, a.Off())) + v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 1 == ValAndOff(c).Off() && clobber(x) - // result: (MOVWstoreconst [makeValAndOff(ValAndOff(a).Val()&0xff | ValAndOff(c).Val()<<8, ValAndOff(a).Off())] {s} p mem) + // cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x) + // result: (MOVWstoreconst [makeValAndOff64(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem) for { - a := v.AuxInt - s := v.Aux + a := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVBstoreconst { break } - c := x.AuxInt - if x.Aux != s { + c := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+1 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVWstoreconst) - v.AuxInt = makeValAndOff(ValAndOff(a).Val()&0xff|ValAndOff(c).Val()<<8, ValAndOff(a).Off()) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xff|c.Val()<<8, a.Off())) + v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVBstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) + // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && sc.canAdd32(off)) { break } v.reset(OpAMD64MOVBstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVBstoreconst [sc] {s} (ADDLconst [off] ptr) mem) - // cond: ValAndOff(sc).canAdd(off) - // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) + // cond: sc.canAdd32(off) + // result: (MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem) for { - sc := v.AuxInt - s := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off := v_0.AuxInt + off := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(ValAndOff(sc).canAdd(off)) { + if !(sc.canAdd32(off)) { break } v.reset(OpAMD64MOVBstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(s) v.AddArg2(ptr, mem) return true } @@ -11782,24 +11766,24 @@ func rewriteValueAMD64_OpAMD64MOVLQSXload(v *Value) bool { return true } // match: (MOVLQSXload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVLQSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVLQSXload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -11917,45 +11901,45 @@ func rewriteValueAMD64_OpAMD64MOVLatomicload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVLatomicload [off1] {sym} (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVLatomicload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDQconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVLatomicload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLatomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) - // result: (MOVLatomicload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) + // result: (MOVLatomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVLatomicload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -11973,16 +11957,16 @@ func rewriteValueAMD64_OpAMD64MOVLf2i(v *Value) bool { break } u := v_0.Type - off := v_0.AuxInt - sym := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) if !(t.Size() == u.Size()) { break } b = b.Func.Entry v0 := b.NewValue0(v.Pos, OpArg, t) v.copyOf(v0) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) return true } return false @@ -11999,16 +11983,16 @@ func rewriteValueAMD64_OpAMD64MOVLi2f(v *Value) bool { break } u := v_0.Type - off := v_0.AuxInt - sym := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) if !(t.Size() == u.Size()) { break } b = b.Func.Entry v0 := b.NewValue0(v.Pos, OpArg, t) v.copyOf(v0) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) return true } return false @@ -12061,77 +12045,77 @@ func rewriteValueAMD64_OpAMD64MOVLload(v *Value) bool { return true } // match: (MOVLload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVLload [off1] {sym} (ADDLconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVLload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVLload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLload [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) // result: (MOVLf2i val) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 - if v_1.Op != OpAMD64MOVSSstore || v_1.AuxInt != off || v_1.Aux != sym { + if v_1.Op != OpAMD64MOVSSstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { break } val := v_1.Args[1] @@ -12144,15 +12128,15 @@ func rewriteValueAMD64_OpAMD64MOVLload(v *Value) bool { } // match: (MOVLload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVQconst [int64(read32(sym, off, config.ctxt.Arch.ByteOrder))]) + // result: (MOVQconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(read32(sym, off, config.ctxt.Arch.ByteOrder)) + v.AuxInt = int64ToAuxInt(int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))) return true } return false @@ -12254,25 +12238,25 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { return true } // match: (MOVLstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -12280,15 +12264,15 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVQstore [i-4] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 32 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 32 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVLstore || x.AuxInt != i-4 || x.Aux != s { + if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -12296,8 +12280,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - 4 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 4) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -12305,16 +12289,16 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVQstore [i-4] {s} p w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVLstore || x.AuxInt != i-4 || x.Aux != s { + if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -12322,12 +12306,12 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - 4 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 4) + v.Aux = symToAux(s) v.AddArg3(p, w0, mem) return true } @@ -12335,15 +12319,15 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x) // result: (MOVQstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 32 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 32 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVLstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -12352,8 +12336,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -12361,27 +12345,27 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x) // result: (MOVQstore [i] {s} p0 w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVLstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVLstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p0 := x.Args[0] w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-32 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 4) && clobber(x)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w0, mem) return true } @@ -12389,19 +12373,19 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) // result: (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x1 := v_1 if x1.Op != OpAMD64MOVLload { break } - j := x1.AuxInt - s2 := x1.Aux + j := auxIntToInt32(x1.AuxInt) + s2 := auxToSym(x1.Aux) mem := x1.Args[1] p2 := x1.Args[0] mem2 := v_2 - if mem2.Op != OpAMD64MOVLstore || mem2.AuxInt != i-4 || mem2.Aux != s { + if mem2.Op != OpAMD64MOVLstore || auxIntToInt32(mem2.AuxInt) != i-4 || auxToSym(mem2.Aux) != s { break } _ = mem2.Args[2] @@ -12409,7 +12393,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } x2 := mem2.Args[1] - if x2.Op != OpAMD64MOVLload || x2.AuxInt != j-4 || x2.Aux != s2 { + if x2.Op != OpAMD64MOVLload || auxIntToInt32(x2.AuxInt) != j-4 || auxToSym(x2.Aux) != s2 { break } _ = x2.Args[1] @@ -12417,57 +12401,57 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = i - 4 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 4) + v.Aux = symToAux(s) v0 := b.NewValue0(x2.Pos, OpAMD64MOVQload, typ.UInt64) - v0.AuxInt = j - 4 - v0.Aux = s2 + v0.AuxInt = int32ToAuxInt(j - 4) + v0.Aux = symToAux(s2) v0.AddArg2(p2, mem) v.AddArg3(p, v0, mem) return true } // match: (MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVLstore [off1] {sym} (ADDLconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVLstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -12475,11 +12459,11 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ADDLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ADDLload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ADDLload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -12488,8 +12472,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64ADDLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12497,11 +12481,11 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ANDLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ANDLload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ANDLload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -12510,8 +12494,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64ANDLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12519,11 +12503,11 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ORLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ORLload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ORLload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -12532,8 +12516,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64ORLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12541,11 +12525,11 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (XORLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64XORLload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64XORLload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -12554,8 +12538,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64XORLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12563,8 +12547,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ADDLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ADDL { @@ -12575,7 +12559,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -12587,8 +12571,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { continue } v.reset(OpAMD64ADDLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12598,8 +12582,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (SUBLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64SUBL { @@ -12607,7 +12591,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -12615,8 +12599,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64SUBLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12624,8 +12608,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ANDLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ANDL { @@ -12636,7 +12620,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -12648,8 +12632,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { continue } v.reset(OpAMD64ANDLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12659,8 +12643,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ORLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ORL { @@ -12671,7 +12655,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -12683,8 +12667,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { continue } v.reset(OpAMD64ORLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12694,8 +12678,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (XORLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64XORL { @@ -12706,7 +12690,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -12718,8 +12702,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { continue } v.reset(OpAMD64XORLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12729,8 +12713,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTCLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTCL { @@ -12738,7 +12722,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -12746,8 +12730,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64BTCLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12755,8 +12739,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTRLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTRL { @@ -12764,7 +12748,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -12772,8 +12756,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64BTRLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -12781,8 +12765,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTSLmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTSL { @@ -12790,7 +12774,7 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -12798,205 +12782,205 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { break } v.reset(OpAMD64BTSLmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(ADDLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ADDLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ADDLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ADDLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ADDLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(ANDLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ANDLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ANDLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ANDLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ANDLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(ORLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ORLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ORLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ORLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ORLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(XORLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (XORLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (XORLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64XORLconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64XORLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(BTCLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTCLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTCLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTCLconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTCLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(BTRLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTRLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTRLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTRLconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTRLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr a:(BTSLconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTSLconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTSLconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTSLconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVLload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVLload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTSLconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVLstore [off] {sym} ptr (MOVLf2i val) mem) // result: (MOVSSstore [off] {sym} ptr val mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVLf2i { break @@ -13004,8 +12988,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool { val := v_1.Args[0] mem := v_2 v.reset(OpAMD64MOVSSstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -13038,121 +13022,121 @@ func rewriteValueAMD64_OpAMD64MOVLstoreconst(v *Value) bool { return true } // match: (MOVLstoreconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVLstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) + // result: (MOVLstoreconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off)) { break } v.reset(OpAMD64MOVLstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 4 == ValAndOff(c).Off() && clobber(x) - // result: (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem) + // cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x) + // result: (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem) for { - c := v.AuxInt - s := v.Aux + c := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVLstoreconst { break } - a := x.AuxInt - if x.Aux != s { + a := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+4 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = ValAndOff(a).Off() - v.Aux = s + v.AuxInt = int32ToAuxInt(a.Off32()) + v.Aux = symToAux(s) v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64) - v0.AuxInt = ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32 + v0.AuxInt = int64ToAuxInt(a.Val()&0xffffffff | c.Val()<<32) v.AddArg3(p, v0, mem) return true } // match: (MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 4 == ValAndOff(c).Off() && clobber(x) - // result: (MOVQstore [ValAndOff(a).Off()] {s} p (MOVQconst [ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32]) mem) + // cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x) + // result: (MOVQstore [a.Off32()] {s} p (MOVQconst [a.Val()&0xffffffff | c.Val()<<32]) mem) for { - a := v.AuxInt - s := v.Aux + a := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVLstoreconst { break } - c := x.AuxInt - if x.Aux != s { + c := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+4 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = ValAndOff(a).Off() - v.Aux = s + v.AuxInt = int32ToAuxInt(a.Off32()) + v.Aux = symToAux(s) v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64) - v0.AuxInt = ValAndOff(a).Val()&0xffffffff | ValAndOff(c).Val()<<32 + v0.AuxInt = int64ToAuxInt(a.Val()&0xffffffff | c.Val()<<32) v.AddArg3(p, v0, mem) return true } // match: (MOVLstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVLstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) + // result: (MOVLstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && sc.canAdd32(off)) { break } v.reset(OpAMD64MOVLstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVLstoreconst [sc] {s} (ADDLconst [off] ptr) mem) - // cond: ValAndOff(sc).canAdd(off) - // result: (MOVLstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) + // cond: sc.canAdd32(off) + // result: (MOVLstoreconst [sc.addOffset32(off)] {s} ptr mem) for { - sc := v.AuxInt - s := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off := v_0.AuxInt + off := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(ValAndOff(sc).canAdd(off)) { + if !(sc.canAdd32(off)) { break } v.reset(OpAMD64MOVLstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(s) v.AddArg2(ptr, mem) return true } @@ -13183,24 +13167,24 @@ func rewriteValueAMD64_OpAMD64MOVOload(v *Value) bool { return true } // match: (MOVOload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVOload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVOload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -13236,40 +13220,40 @@ func rewriteValueAMD64_OpAMD64MOVOstore(v *Value) bool { return true } // match: (MOVOstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVOstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVOstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) // cond: symIsRO(srcSym) - // result: (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, srcOff+8, config.ctxt.Arch.ByteOrder))]) (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, srcOff, config.ctxt.Arch.ByteOrder))]) mem)) + // result: (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))]) (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))]) mem)) for { - dstOff := v.AuxInt - dstSym := v.Aux + dstOff := auxIntToInt32(v.AuxInt) + dstSym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVOload { break } - srcOff := v_1.AuxInt - srcSym := v_1.Aux + srcOff := auxIntToInt32(v_1.AuxInt) + srcSym := auxToSym(v_1.Aux) v_1_0 := v_1.Args[0] if v_1_0.Op != OpSB { break @@ -13279,15 +13263,15 @@ func rewriteValueAMD64_OpAMD64MOVOstore(v *Value) bool { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = dstOff + 8 - v.Aux = dstSym + v.AuxInt = int32ToAuxInt(dstOff + 8) + v.Aux = symToAux(dstSym) v0 := b.NewValue0(v_1.Pos, OpAMD64MOVQconst, typ.UInt64) - v0.AuxInt = int64(read64(srcSym, srcOff+8, config.ctxt.Arch.ByteOrder)) + v0.AuxInt = int64ToAuxInt(int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))) v1 := b.NewValue0(v_1.Pos, OpAMD64MOVQstore, types.TypeMem) - v1.AuxInt = dstOff - v1.Aux = dstSym + v1.AuxInt = int32ToAuxInt(dstOff) + v1.Aux = symToAux(dstSym) v2 := b.NewValue0(v_1.Pos, OpAMD64MOVQconst, typ.UInt64) - v2.AuxInt = int64(read64(srcSym, srcOff, config.ctxt.Arch.ByteOrder)) + v2.AuxInt = int64ToAuxInt(int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))) v1.AddArg3(ptr, v2, mem) v.AddArg3(ptr, v0, v1) return true @@ -13298,45 +13282,45 @@ func rewriteValueAMD64_OpAMD64MOVQatomicload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVQatomicload [off1] {sym} (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVQatomicload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDQconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVQatomicload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQatomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) - // result: (MOVQatomicload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) + // result: (MOVQatomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVQatomicload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -13354,16 +13338,16 @@ func rewriteValueAMD64_OpAMD64MOVQf2i(v *Value) bool { break } u := v_0.Type - off := v_0.AuxInt - sym := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) if !(t.Size() == u.Size()) { break } b = b.Func.Entry v0 := b.NewValue0(v.Pos, OpArg, t) v.copyOf(v0) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) return true } return false @@ -13380,16 +13364,16 @@ func rewriteValueAMD64_OpAMD64MOVQi2f(v *Value) bool { break } u := v_0.Type - off := v_0.AuxInt - sym := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) if !(t.Size() == u.Size()) { break } b = b.Func.Entry v0 := b.NewValue0(v.Pos, OpArg, t) v.copyOf(v0) - v0.AuxInt = off - v0.Aux = sym + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) return true } return false @@ -13441,77 +13425,77 @@ func rewriteValueAMD64_OpAMD64MOVQload(v *Value) bool { return true } // match: (MOVQload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVQload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVQload [off1] {sym1} (LEAL [off2] {sym2} base) mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVQload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVQload [off1] {sym} (ADDLconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVQload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVQload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQload [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) // result: (MOVQf2i val) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 - if v_1.Op != OpAMD64MOVSDstore || v_1.AuxInt != off || v_1.Aux != sym { + if v_1.Op != OpAMD64MOVSDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { break } val := v_1.Args[1] @@ -13524,15 +13508,15 @@ func rewriteValueAMD64_OpAMD64MOVQload(v *Value) bool { } // match: (MOVQload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVQconst [int64(read64(sym, off, config.ctxt.Arch.ByteOrder))]) + // result: (MOVQconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(read64(sym, off, config.ctxt.Arch.ByteOrder)) + v.AuxInt = int64ToAuxInt(int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))) return true } return false @@ -13585,70 +13569,70 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { return true } // match: (MOVQstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVQstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVQstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVQstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVQstore [off1] {sym} (ADDLconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVQstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVQstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -13656,11 +13640,11 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ADDQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ADDQload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ADDQload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -13669,8 +13653,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64ADDQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13678,11 +13662,11 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ANDQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ANDQload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ANDQload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -13691,8 +13675,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64ANDQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13700,11 +13684,11 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (ORQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64ORQload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64ORQload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -13713,8 +13697,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64ORQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13722,11 +13706,11 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && clobber(y) // result: (XORQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 - if y.Op != OpAMD64XORQload || y.AuxInt != off || y.Aux != sym { + if y.Op != OpAMD64XORQload || auxIntToInt32(y.AuxInt) != off || auxToSym(y.Aux) != sym { break } mem := y.Args[2] @@ -13735,8 +13719,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64XORQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13744,8 +13728,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ADDQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ADDQ { @@ -13756,7 +13740,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -13768,8 +13752,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { continue } v.reset(OpAMD64ADDQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13779,8 +13763,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (SUBQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64SUBQ { @@ -13788,7 +13772,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -13796,8 +13780,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64SUBQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13805,8 +13789,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ANDQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ANDQ { @@ -13817,7 +13801,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -13829,8 +13813,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { continue } v.reset(OpAMD64ANDQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13840,8 +13824,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (ORQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64ORQ { @@ -13852,7 +13836,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -13864,8 +13848,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { continue } v.reset(OpAMD64ORQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13875,8 +13859,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (XORQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64XORQ { @@ -13887,7 +13871,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { y_1 := y.Args[1] for _i0 := 0; _i0 <= 1; _i0, y_0, y_1 = _i0+1, y_1, y_0 { l := y_0 - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { continue } mem := l.Args[1] @@ -13899,8 +13883,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { continue } v.reset(OpAMD64XORQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13910,8 +13894,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTCQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTCQ { @@ -13919,7 +13903,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -13927,8 +13911,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64BTCQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13936,8 +13920,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTRQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTRQ { @@ -13945,7 +13929,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -13953,8 +13937,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64BTRQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -13962,8 +13946,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { // cond: y.Uses==1 && l.Uses==1 && clobber(y, l) // result: (BTSQmodify [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 y := v_1 if y.Op != OpAMD64BTSQ { @@ -13971,7 +13955,7 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { } x := y.Args[1] l := y.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] @@ -13979,205 +13963,205 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { break } v.reset(OpAMD64BTSQmodify) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(ADDQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ADDQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ADDQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ADDQconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ADDQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(ANDQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ANDQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ANDQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ANDQconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ANDQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(ORQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (ORQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (ORQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64ORQconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64ORQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(XORQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (XORQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (XORQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64XORQconst { break } - c := a.AuxInt + c := auxIntToInt32(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64XORQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(BTCQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTCQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTCQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTCQconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTCQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(BTRQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTRQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTRQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTRQconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTRQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr a:(BTSQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) - // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l, a) - // result: (BTSQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) + // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c),int64(off)) && clobber(l, a) + // result: (BTSQconstmodify {sym} [makeValAndOff32(int32(c),off)] ptr mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 a := v_1 if a.Op != OpAMD64BTSQconst { break } - c := a.AuxInt + c := auxIntToInt8(a.AuxInt) l := a.Args[0] - if l.Op != OpAMD64MOVQload || l.AuxInt != off || l.Aux != sym { + if l.Op != OpAMD64MOVQload || auxIntToInt32(l.AuxInt) != off || auxToSym(l.Aux) != sym { break } mem := l.Args[1] ptr2 := l.Args[0] - if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c, off) && clobber(l, a)) { + if mem != v_2 || !(isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(int64(c), int64(off)) && clobber(l, a)) { break } v.reset(OpAMD64BTSQconstmodify) - v.AuxInt = makeValAndOff(c, off) - v.Aux = sym + v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off)) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVQstore [off] {sym} ptr (MOVQf2i val) mem) // result: (MOVSDstore [off] {sym} ptr val mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVQf2i { break @@ -14185,8 +14169,8 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool { val := v_1.Args[0] mem := v_2 v.reset(OpAMD64MOVSDstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -14219,94 +14203,94 @@ func rewriteValueAMD64_OpAMD64MOVQstoreconst(v *Value) bool { return true } // match: (MOVQstoreconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVQstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) + // result: (MOVQstoreconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off)) { break } v.reset(OpAMD64MOVQstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [c2] {s} p mem)) - // cond: config.useSSE && x.Uses == 1 && ValAndOff(c2).Off() + 8 == ValAndOff(c).Off() && ValAndOff(c).Val() == 0 && ValAndOff(c2).Val() == 0 && clobber(x) - // result: (MOVOstore [ValAndOff(c2).Off()] {s} p (MOVOconst [0]) mem) + // cond: config.useSSE && x.Uses == 1 && c2.Off() + 8 == c.Off() && c.Val() == 0 && c2.Val() == 0 && clobber(x) + // result: (MOVOstore [c2.Off32()] {s} p (MOVOconst [0]) mem) for { - c := v.AuxInt - s := v.Aux + c := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVQstoreconst { break } - c2 := x.AuxInt - if x.Aux != s { + c2 := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(config.useSSE && x.Uses == 1 && ValAndOff(c2).Off()+8 == ValAndOff(c).Off() && ValAndOff(c).Val() == 0 && ValAndOff(c2).Val() == 0 && clobber(x)) { + if p != x.Args[0] || !(config.useSSE && x.Uses == 1 && c2.Off()+8 == c.Off() && c.Val() == 0 && c2.Val() == 0 && clobber(x)) { break } v.reset(OpAMD64MOVOstore) - v.AuxInt = ValAndOff(c2).Off() - v.Aux = s + v.AuxInt = int32ToAuxInt(c2.Off32()) + v.Aux = symToAux(s) v0 := b.NewValue0(x.Pos, OpAMD64MOVOconst, types.TypeInt128) - v0.AuxInt = 0 + v0.AuxInt = int128ToAuxInt(0) v.AddArg3(p, v0, mem) return true } // match: (MOVQstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVQstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) + // result: (MOVQstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && sc.canAdd32(off)) { break } v.reset(OpAMD64MOVQstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVQstoreconst [sc] {s} (ADDLconst [off] ptr) mem) - // cond: ValAndOff(sc).canAdd(off) - // result: (MOVQstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) + // cond: sc.canAdd32(off) + // result: (MOVQstoreconst [sc.addOffset32(off)] {s} ptr mem) for { - sc := v.AuxInt - s := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off := v_0.AuxInt + off := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(ValAndOff(sc).canAdd(off)) { + if !(sc.canAdd32(off)) { break } v.reset(OpAMD64MOVQstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(s) v.AddArg2(ptr, mem) return true } @@ -14337,34 +14321,34 @@ func rewriteValueAMD64_OpAMD64MOVSDload(v *Value) bool { return true } // match: (MOVSDload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVSDload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVSDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVSDload [off] {sym} ptr (MOVQstore [off] {sym} ptr val _)) // result: (MOVQi2f val) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 - if v_1.Op != OpAMD64MOVQstore || v_1.AuxInt != off || v_1.Aux != sym { + if v_1.Op != OpAMD64MOVQstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { break } val := v_1.Args[1] @@ -14404,33 +14388,33 @@ func rewriteValueAMD64_OpAMD64MOVSDstore(v *Value) bool { return true } // match: (MOVSDstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVSDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVSDstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) // result: (MOVQstore [off] {sym} ptr val mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVQi2f { break @@ -14438,8 +14422,8 @@ func rewriteValueAMD64_OpAMD64MOVSDstore(v *Value) bool { val := v_1.Args[0] mem := v_2 v.reset(OpAMD64MOVQstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -14470,34 +14454,34 @@ func rewriteValueAMD64_OpAMD64MOVSSload(v *Value) bool { return true } // match: (MOVSSload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVSSload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVSSload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVSSload [off] {sym} ptr (MOVLstore [off] {sym} ptr val _)) // result: (MOVLi2f val) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 - if v_1.Op != OpAMD64MOVLstore || v_1.AuxInt != off || v_1.Aux != sym { + if v_1.Op != OpAMD64MOVLstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym { break } val := v_1.Args[1] @@ -14537,33 +14521,33 @@ func rewriteValueAMD64_OpAMD64MOVSSstore(v *Value) bool { return true } // match: (MOVSSstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVSSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVSSstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) // result: (MOVLstore [off] {sym} ptr val mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64MOVLi2f { break @@ -14571,8 +14555,8 @@ func rewriteValueAMD64_OpAMD64MOVSSstore(v *Value) bool { val := v_1.Args[0] mem := v_2 v.reset(OpAMD64MOVLstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -14716,24 +14700,24 @@ func rewriteValueAMD64_OpAMD64MOVWQSXload(v *Value) bool { return true } // match: (MOVWQSXload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVWQSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVWQSXload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -14907,81 +14891,81 @@ func rewriteValueAMD64_OpAMD64MOVWload(v *Value) bool { return true } // match: (MOVWload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVWload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVWload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } // match: (MOVWload [off1] {sym} (ADDLconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVWload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVWload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVWload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVLconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))]) + // result: (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(read16(sym, off, config.ctxt.Arch.ByteOrder)) + v.AuxInt = int32ToAuxInt(int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))) return true } return false @@ -15083,25 +15067,25 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { return true } // match: (MOVWstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -15109,15 +15093,15 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRLconst || v_1.AuxInt != 16 { + if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 16 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i-2 || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15125,8 +15109,8 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 2 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 2) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -15134,15 +15118,15 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 16 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 16 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i-2 || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15150,8 +15134,8 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 2 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 2) + v.Aux = symToAux(s) v.AddArg3(p, w, mem) return true } @@ -15159,16 +15143,16 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 if v_1.Op != OpAMD64SHRLconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i-2 || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15176,12 +15160,12 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } w0 := x.Args[1] - if w0.Op != OpAMD64SHRLconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { + if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 2 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 2) + v.Aux = symToAux(s) v.AddArg3(p, w0, mem) return true } @@ -15189,16 +15173,16 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i-2 || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15206,12 +15190,12 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 2 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 2) + v.Aux = symToAux(s) v.AddArg3(p, w0, mem) return true } @@ -15219,15 +15203,15 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) // result: (MOVLstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRLconst || v_1.AuxInt != 16 { + if v_1.Op != OpAMD64SHRLconst || auxIntToInt8(v_1.AuxInt) != 16 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15236,8 +15220,8 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -15245,15 +15229,15 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) // result: (MOVLstore [i] {s} p0 w mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 - if v_1.Op != OpAMD64SHRQconst || v_1.AuxInt != 16 { + if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 16 { break } w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] @@ -15262,8 +15246,8 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w, mem) return true } @@ -15271,27 +15255,27 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) // result: (MOVLstore [i] {s} p0 w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 if v_1.Op != OpAMD64SHRLconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p0 := x.Args[0] w0 := x.Args[1] - if w0.Op != OpAMD64SHRLconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) { + if w0.Op != OpAMD64SHRLconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w0, mem) return true } @@ -15299,27 +15283,27 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x) // result: (MOVLstore [i] {s} p0 w0 mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p1 := v_0 if v_1.Op != OpAMD64SHRQconst { break } - j := v_1.AuxInt + j := auxIntToInt8(v_1.AuxInt) w := v_1.Args[0] x := v_2 - if x.Op != OpAMD64MOVWstore || x.AuxInt != i || x.Aux != s { + if x.Op != OpAMD64MOVWstore || auxIntToInt32(x.AuxInt) != i || auxToSym(x.Aux) != s { break } mem := x.Args[2] p0 := x.Args[0] w0 := x.Args[1] - if w0.Op != OpAMD64SHRQconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) { + if w0.Op != OpAMD64SHRQconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && sequentialAddresses(p0, p1, 2) && clobber(x)) { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - v.Aux = s + v.AuxInt = int32ToAuxInt(i) + v.Aux = symToAux(s) v.AddArg3(p0, w0, mem) return true } @@ -15327,19 +15311,19 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { // cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1, x2, mem2) // result: (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem) for { - i := v.AuxInt - s := v.Aux + i := auxIntToInt32(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x1 := v_1 if x1.Op != OpAMD64MOVWload { break } - j := x1.AuxInt - s2 := x1.Aux + j := auxIntToInt32(x1.AuxInt) + s2 := auxToSym(x1.Aux) mem := x1.Args[1] p2 := x1.Args[0] mem2 := v_2 - if mem2.Op != OpAMD64MOVWstore || mem2.AuxInt != i-2 || mem2.Aux != s { + if mem2.Op != OpAMD64MOVWstore || auxIntToInt32(mem2.AuxInt) != i-2 || auxToSym(mem2.Aux) != s { break } _ = mem2.Args[2] @@ -15347,7 +15331,7 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } x2 := mem2.Args[1] - if x2.Op != OpAMD64MOVWload || x2.AuxInt != j-2 || x2.Aux != s2 { + if x2.Op != OpAMD64MOVWload || auxIntToInt32(x2.AuxInt) != j-2 || auxToSym(x2.Aux) != s2 { break } _ = x2.Args[1] @@ -15355,57 +15339,57 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool { break } v.reset(OpAMD64MOVLstore) - v.AuxInt = i - 2 - v.Aux = s + v.AuxInt = int32ToAuxInt(i - 2) + v.Aux = symToAux(s) v0 := b.NewValue0(x2.Pos, OpAMD64MOVLload, typ.UInt32) - v0.AuxInt = j - 2 - v0.Aux = s2 + v0.AuxInt = int32ToAuxInt(j - 2) + v0.Aux = symToAux(s2) v0.AddArg2(p2, mem) v.AddArg3(p, v0, mem) return true } // match: (MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) - // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) + // cond: canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) { + if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (MOVWstore [off1] {sym} (ADDLconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (MOVWstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64MOVWstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -15436,117 +15420,117 @@ func rewriteValueAMD64_OpAMD64MOVWstoreconst(v *Value) bool { return true } // match: (MOVWstoreconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) + // result: (MOVWstoreconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off)) { break } v.reset(OpAMD64MOVWstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x) - // result: (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem) + // cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x) + // result: (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem) for { - c := v.AuxInt - s := v.Aux + c := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVWstoreconst { break } - a := x.AuxInt - if x.Aux != s { + a := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+2 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVLstoreconst) - v.AuxInt = makeValAndOff(ValAndOff(a).Val()&0xffff|ValAndOff(c).Val()<<16, ValAndOff(a).Off()) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xffff|c.Val()<<16, a.Off())) + v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem)) - // cond: x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x) - // result: (MOVLstoreconst [makeValAndOff(ValAndOff(a).Val()&0xffff | ValAndOff(c).Val()<<16, ValAndOff(a).Off())] {s} p mem) + // cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x) + // result: (MOVLstoreconst [makeValAndOff64(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem) for { - a := v.AuxInt - s := v.Aux + a := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) p := v_0 x := v_1 if x.Op != OpAMD64MOVWstoreconst { break } - c := x.AuxInt - if x.Aux != s { + c := auxIntToValAndOff(x.AuxInt) + if auxToSym(x.Aux) != s { break } mem := x.Args[1] - if p != x.Args[0] || !(x.Uses == 1 && ValAndOff(a).Off()+2 == ValAndOff(c).Off() && clobber(x)) { + if p != x.Args[0] || !(x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) { break } v.reset(OpAMD64MOVLstoreconst) - v.AuxInt = makeValAndOff(ValAndOff(a).Val()&0xffff|ValAndOff(c).Val()<<16, ValAndOff(a).Off()) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(makeValAndOff64(a.Val()&0xffff|c.Val()<<16, a.Off())) + v.Aux = symToAux(s) v.AddArg2(p, mem) return true } // match: (MOVWstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) - // cond: canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) - // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) + // cond: canMergeSym(sym1, sym2) && sc.canAdd32(off) + // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { - sc := v.AuxInt - sym1 := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAL { break } - off := v_0.AuxInt - sym2 := v_0.Aux + off := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 - if !(canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) { + if !(canMergeSym(sym1, sym2) && sc.canAdd32(off)) { break } v.reset(OpAMD64MOVWstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } // match: (MOVWstoreconst [sc] {s} (ADDLconst [off] ptr) mem) - // cond: ValAndOff(sc).canAdd(off) - // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) + // cond: sc.canAdd32(off) + // result: (MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem) for { - sc := v.AuxInt - s := v.Aux + sc := auxIntToValAndOff(v.AuxInt) + s := auxToSym(v.Aux) if v_0.Op != OpAMD64ADDLconst { break } - off := v_0.AuxInt + off := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 - if !(ValAndOff(sc).canAdd(off)) { + if !(sc.canAdd32(off)) { break } v.reset(OpAMD64MOVWstoreconst) - v.AuxInt = ValAndOff(sc).add(off) - v.Aux = s + v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) + v.Aux = symToAux(s) v.AddArg2(ptr, mem) return true } @@ -15850,17 +15834,17 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool { return true } // match: (MULLconst [c] x) - // cond: isPowerOfTwo(int64(c)+1) && c >= 15 - // result: (SUBL (SHLLconst <v.Type> [int8(log2(int64(c)+1))] x) x) + // cond: isPowerOfTwo64(int64(c)+1) && c >= 15 + // result: (SUBL (SHLLconst <v.Type> [int8(log64(int64(c)+1))] x) x) for { c := auxIntToInt32(v.AuxInt) x := v_0 - if !(isPowerOfTwo(int64(c)+1) && c >= 15) { + if !(isPowerOfTwo64(int64(c)+1) && c >= 15) { break } v.reset(OpAMD64SUBL) v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type) - v0.AuxInt = int8ToAuxInt(int8(log2(int64(c) + 1))) + v0.AuxInt = int8ToAuxInt(int8(log64(int64(c) + 1))) v0.AddArg(x) v.AddArg2(v0, x) return true @@ -15978,15 +15962,15 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool { return true } // match: (MULLconst [c] (MOVLconst [d])) - // result: (MOVLconst [int64(int32(c*d))]) + // result: (MOVLconst [c*d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(int32(c * d)) + v.AuxInt = int32ToAuxInt(c * d) return true } return false @@ -16297,17 +16281,17 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool { return true } // match: (MULQconst [c] x) - // cond: isPowerOfTwo(int64(c)+1) && c >= 15 - // result: (SUBQ (SHLQconst <v.Type> [int8(log2(int64(c)+1))] x) x) + // cond: isPowerOfTwo64(int64(c)+1) && c >= 15 + // result: (SUBQ (SHLQconst <v.Type> [int8(log64(int64(c)+1))] x) x) for { c := auxIntToInt32(v.AuxInt) x := v_0 - if !(isPowerOfTwo(int64(c)+1) && c >= 15) { + if !(isPowerOfTwo64(int64(c)+1) && c >= 15) { break } v.reset(OpAMD64SUBQ) v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type) - v0.AuxInt = int8ToAuxInt(int8(log2(int64(c) + 1))) + v0.AuxInt = int8ToAuxInt(int8(log64(int64(c) + 1))) v0.AddArg(x) v.AddArg2(v0, x) return true @@ -16425,22 +16409,22 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool { return true } // match: (MULQconst [c] (MOVQconst [d])) - // result: (MOVQconst [c*d]) + // result: (MOVQconst [int64(c)*d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c * d + v.AuxInt = int64ToAuxInt(int64(c) * d) return true } // match: (MULQconst [c] (NEGQ x)) // cond: c != -(1<<31) // result: (MULQconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64NEGQ { break } @@ -16449,7 +16433,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool { break } v.reset(OpAMD64MULQconst) - v.AuxInt = -c + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } @@ -16468,16 +16452,16 @@ func rewriteValueAMD64_OpAMD64MULSD(v *Value) bool { if l.Op != OpAMD64MOVSDload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64MULSDload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -16514,36 +16498,36 @@ func rewriteValueAMD64_OpAMD64MULSDload(v *Value) bool { return true } // match: (MULSDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MULSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MULSDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (MULSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) // result: (MULSD x (MOVQi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVQstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVQstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -16571,16 +16555,16 @@ func rewriteValueAMD64_OpAMD64MULSS(v *Value) bool { if l.Op != OpAMD64MOVSSload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64MULSSload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -16617,36 +16601,36 @@ func rewriteValueAMD64_OpAMD64MULSSload(v *Value) bool { return true } // match: (MULSSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (MULSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64MULSSload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (MULSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) // result: (MULSS x (MOVLi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVLstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVLstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -16691,14 +16675,14 @@ func rewriteValueAMD64_OpAMD64NEGL(v *Value) bool { return true } // match: (NEGL (MOVLconst [c])) - // result: (MOVLconst [int64(int32(-c))]) + // result: (MOVLconst [-c]) for { if v_0.Op != OpAMD64MOVLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(int32(-c)) + v.AuxInt = int32ToAuxInt(-c) return true } return false @@ -16738,9 +16722,9 @@ func rewriteValueAMD64_OpAMD64NEGQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = -c + v.AuxInt = int64ToAuxInt(-c) return true } // match: (NEGQ (ADDQconst [c] (NEGQ x))) @@ -16750,7 +16734,7 @@ func rewriteValueAMD64_OpAMD64NEGQ(v *Value) bool { if v_0.Op != OpAMD64ADDQconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v_0_0 := v_0.Args[0] if v_0_0.Op != OpAMD64NEGQ { break @@ -16760,7 +16744,7 @@ func rewriteValueAMD64_OpAMD64NEGQ(v *Value) bool { break } v.reset(OpAMD64ADDQconst) - v.AuxInt = -c + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } @@ -16774,9 +16758,9 @@ func rewriteValueAMD64_OpAMD64NOTL(v *Value) bool { if v_0.Op != OpAMD64MOVLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = ^c + v.AuxInt = int32ToAuxInt(^c) return true } return false @@ -16789,9 +16773,9 @@ func rewriteValueAMD64_OpAMD64NOTQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = ^c + v.AuxInt = int64ToAuxInt(^c) return true } return false @@ -17141,7 +17125,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { _ = v_0.Args[1] x := v_0.Args[0] v_0_1 := v_0.Args[1] - if v_0_1.Op != OpAMD64ANDQconst || v_0_1.AuxInt != 15 { + if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 15 { continue } y := v_0_1.Args[0] @@ -17164,15 +17148,15 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { continue } v_1_0_1_0 := v_1_0_1.Args[0] - if v_1_0_1_0.Op != OpAMD64ADDQconst || v_1_0_1_0.AuxInt != -16 { + if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 { continue } v_1_0_1_0_0 := v_1_0_1_0.Args[0] - if v_1_0_1_0_0.Op != OpAMD64ANDQconst || v_1_0_1_0_0.AuxInt != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask { + if v_1_0_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask { continue } v_1_1_0 := v_1_1.Args[0] - if v_1_1_0.Op != OpAMD64CMPQconst || v_1_1_0.AuxInt != 16 { + if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 { continue } v_1_1_0_0 := v_1_1_0.Args[0] @@ -17180,11 +17164,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { continue } v_1_1_0_0_0 := v_1_1_0_0.Args[0] - if v_1_1_0_0_0.Op != OpAMD64ADDQconst || v_1_1_0_0_0.AuxInt != -16 { + if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 { continue } v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0] - if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || v_1_1_0_0_0_0.AuxInt != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) { + if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) { continue } v.reset(OpAMD64ROLW) @@ -17205,7 +17189,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { _ = v_0.Args[1] x := v_0.Args[0] v_0_1 := v_0.Args[1] - if v_0_1.Op != OpAMD64ANDLconst || v_0_1.AuxInt != 15 { + if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 15 { continue } y := v_0_1.Args[0] @@ -17228,15 +17212,15 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { continue } v_1_0_1_0 := v_1_0_1.Args[0] - if v_1_0_1_0.Op != OpAMD64ADDLconst || v_1_0_1_0.AuxInt != -16 { + if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 { continue } v_1_0_1_0_0 := v_1_0_1_0.Args[0] - if v_1_0_1_0_0.Op != OpAMD64ANDLconst || v_1_0_1_0_0.AuxInt != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask { + if v_1_0_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask { continue } v_1_1_0 := v_1_1.Args[0] - if v_1_1_0.Op != OpAMD64CMPLconst || v_1_1_0.AuxInt != 16 { + if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 { continue } v_1_1_0_0 := v_1_1_0.Args[0] @@ -17244,11 +17228,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { continue } v_1_1_0_0_0 := v_1_1_0_0.Args[0] - if v_1_1_0_0_0.Op != OpAMD64ADDLconst || v_1_1_0_0_0.AuxInt != -16 { + if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 { continue } v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0] - if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || v_1_1_0_0_0_0.AuxInt != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) { + if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) { continue } v.reset(OpAMD64ROLW) @@ -17565,20 +17549,20 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x1 := sh.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -17588,8 +17572,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) v.copyOf(v0) - v0.AuxInt = i0 - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i0) + v0.Aux = symToAux(s) v0.AddArg2(p, mem) return true } @@ -17604,16 +17588,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x0.Op != OpAMD64MOVBload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x1 := sh.Args[0] - if x1.Op != OpAMD64MOVBload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -17624,8 +17608,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) v.copyOf(v0) - v0.AuxInt = i - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i) + v0.Aux = symToAux(s) v0.AddArg2(p0, mem) return true } @@ -17640,20 +17624,20 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 { continue } x1 := sh.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -17663,8 +17647,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) v.copyOf(v0) - v0.AuxInt = i0 - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i0) + v0.Aux = symToAux(s) v0.AddArg2(p, mem) return true } @@ -17679,16 +17663,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x0.Op != OpAMD64MOVWload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 { continue } x1 := sh.Args[0] - if x1.Op != OpAMD64MOVWload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -17699,8 +17683,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) v.copyOf(v0) - v0.AuxInt = i - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i) + v0.Aux = symToAux(s) v0.AddArg2(p0, mem) return true } @@ -17715,13 +17699,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s1.Op != OpAMD64SHLLconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] or := v_1 @@ -17736,13 +17720,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s0.Op != OpAMD64SHLLconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17757,10 +17741,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLLconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v2.AuxInt = i0 - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i0) + v2.Aux = symToAux(s) v2.AddArg2(p, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -17778,13 +17762,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s1.Op != OpAMD64SHLLconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] or := v_1 @@ -17799,9 +17783,9 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s0.Op != OpAMD64SHLLconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] - if x0.Op != OpAMD64MOVBload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17817,10 +17801,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLLconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v2.AuxInt = i - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i) + v2.Aux = symToAux(s) v2.AddArg2(p0, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -17838,20 +17822,20 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x0 := sh.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17861,10 +17845,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type) v.copyOf(v0) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v1.AuxInt = i0 - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i0) + v1.Aux = symToAux(s) v1.AddArg2(p, mem) v0.AddArg(v1) return true @@ -17880,16 +17864,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if x1.Op != OpAMD64MOVBload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x0 := sh.Args[0] - if x0.Op != OpAMD64MOVBload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17900,10 +17884,10 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type) v.copyOf(v0) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v1.AuxInt = i - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i) + v1.Aux = symToAux(s) v1.AddArg2(p0, mem) v0.AddArg(v1) return true @@ -17916,31 +17900,31 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { r1 := v_0 - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 { continue } r0 := sh.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17951,8 +17935,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v1.AuxInt = i0 - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i0) + v1.Aux = symToAux(s) v1.AddArg2(p, mem) v0.AddArg(v1) return true @@ -17965,27 +17949,27 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { r1 := v_0 - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLLconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLLconst || auxIntToInt8(sh.AuxInt) != 16 { continue } r0 := sh.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] - if x0.Op != OpAMD64MOVWload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -17997,8 +17981,8 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v1.AuxInt = i - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i) + v1.Aux = symToAux(s) v1.AddArg2(p0, mem) v0.AddArg(v1) return true @@ -18014,13 +17998,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s0.Op != OpAMD64SHLLconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] or := v_1 @@ -18035,13 +18019,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s1.Op != OpAMD64SHLLconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18056,12 +18040,12 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLLconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16) - v2.AuxInt = 8 + v2.AuxInt = int8ToAuxInt(8) v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) - v3.AuxInt = i0 - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i0) + v3.Aux = symToAux(s) v3.AddArg2(p, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -18080,13 +18064,13 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s0.Op != OpAMD64SHLLconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] or := v_1 @@ -18101,9 +18085,9 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if s1.Op != OpAMD64SHLLconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] - if x1.Op != OpAMD64MOVBload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18119,12 +18103,12 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLLconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16) - v2.AuxInt = 8 + v2.AuxInt = int8ToAuxInt(8) v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) - v3.AuxInt = i - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i) + v3.Aux = symToAux(s) v3.AddArg2(p0, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -18144,16 +18128,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool { if l.Op != OpAMD64MOVLload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ORLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -18206,39 +18190,39 @@ func rewriteValueAMD64_OpAMD64ORLconst(v *Value) bool { return true } // match: (ORLconst [c] x) - // cond: int32(c)==0 + // cond: c==0 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 - if !(int32(c) == 0) { + if !(c == 0) { break } v.copyOf(x) return true } // match: (ORLconst [c] _) - // cond: int32(c)==-1 + // cond: c==-1 // result: (MOVLconst [-1]) for { - c := v.AuxInt - if !(int32(c) == -1) { + c := auxIntToInt32(v.AuxInt) + if !(c == -1) { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = -1 + v.AuxInt = int32ToAuxInt(-1) return true } // match: (ORLconst [c] (MOVLconst [d])) // result: (MOVLconst [c|d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = c | d + v.AuxInt = int32ToAuxInt(c | d) return true } return false @@ -18268,24 +18252,24 @@ func rewriteValueAMD64_OpAMD64ORLconstmodify(v *Value) bool { return true } // match: (ORLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ORLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ORLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -18320,36 +18304,36 @@ func rewriteValueAMD64_OpAMD64ORLload(v *Value) bool { return true } // match: (ORLload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ORLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: ( ORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) // result: ( ORL x (MOVLf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSSstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSSstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -18391,25 +18375,25 @@ func rewriteValueAMD64_OpAMD64ORLmodify(v *Value) bool { return true } // match: (ORLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ORLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -18441,7 +18425,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { } // match: (ORQ (MOVQconst [c]) x) // cond: isUint64PowerOfTwo(c) && uint64(c) >= 128 - // result: (BTSQconst [int8(log2(c))] x) + // result: (BTSQconst [int8(log64(c))] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVQconst { @@ -18453,7 +18437,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { continue } v.reset(OpAMD64BTSQconst) - v.AuxInt = int8ToAuxInt(int8(log2(c))) + v.AuxInt = int8ToAuxInt(int8(log64(c))) v.AddArg(x) return true } @@ -18726,13 +18710,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if v_0.Op != OpAMD64MOVQconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpAMD64MOVQconst { continue } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c | d + v.AuxInt = int64ToAuxInt(c | d) return true } break @@ -18756,20 +18740,20 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x1 := sh.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18779,8 +18763,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) v.copyOf(v0) - v0.AuxInt = i0 - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i0) + v0.Aux = symToAux(s) v0.AddArg2(p, mem) return true } @@ -18795,16 +18779,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVBload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x1 := sh.Args[0] - if x1.Op != OpAMD64MOVBload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18815,8 +18799,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) v.copyOf(v0) - v0.AuxInt = i - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i) + v0.Aux = symToAux(s) v0.AddArg2(p0, mem) return true } @@ -18831,20 +18815,20 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 { continue } x1 := sh.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18854,8 +18838,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) v.copyOf(v0) - v0.AuxInt = i0 - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i0) + v0.Aux = symToAux(s) v0.AddArg2(p, mem) return true } @@ -18870,16 +18854,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVWload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 { continue } x1 := sh.Args[0] - if x1.Op != OpAMD64MOVWload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18890,8 +18874,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) v.copyOf(v0) - v0.AuxInt = i - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i) + v0.Aux = symToAux(s) v0.AddArg2(p0, mem) return true } @@ -18906,20 +18890,20 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVLload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 32 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 { continue } x1 := sh.Args[0] if x1.Op != OpAMD64MOVLload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18929,8 +18913,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVQload, typ.UInt64) v.copyOf(v0) - v0.AuxInt = i0 - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i0) + v0.Aux = symToAux(s) v0.AddArg2(p, mem) return true } @@ -18945,16 +18929,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVLload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 32 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 { continue } x1 := sh.Args[0] - if x1.Op != OpAMD64MOVLload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVLload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -18965,8 +18949,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x1.Pos, OpAMD64MOVQload, typ.UInt64) v.copyOf(v0) - v0.AuxInt = i - v0.Aux = s + v0.AuxInt = int32ToAuxInt(i) + v0.Aux = symToAux(s) v0.AddArg2(p0, mem) return true } @@ -18981,13 +18965,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] or := v_1 @@ -19002,13 +18986,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19023,10 +19007,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v2.AuxInt = i0 - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i0) + v2.Aux = symToAux(s) v2.AddArg2(p, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -19044,13 +19028,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] or := v_1 @@ -19065,9 +19049,9 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] - if x0.Op != OpAMD64MOVBload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19083,10 +19067,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v2.AuxInt = i - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i) + v2.Aux = symToAux(s) v2.AddArg2(p0, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -19104,13 +19088,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] or := v_1 @@ -19125,13 +19109,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19146,10 +19130,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v2.AuxInt = i0 - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i0) + v2.Aux = symToAux(s) v2.AddArg2(p, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -19167,13 +19151,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] or := v_1 @@ -19188,9 +19172,9 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] - if x0.Op != OpAMD64MOVWload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19206,10 +19190,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j0 + v1.AuxInt = int8ToAuxInt(j0) v2 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v2.AuxInt = i - v2.Aux = s + v2.AuxInt = int32ToAuxInt(i) + v2.Aux = symToAux(s) v2.AddArg2(p0, mem) v1.AddArg(v2) v0.AddArg2(v1, y) @@ -19227,20 +19211,20 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x0 := sh.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19250,10 +19234,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type) v.copyOf(v0) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v1.AuxInt = i0 - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i0) + v1.Aux = symToAux(s) v1.AddArg2(p, mem) v0.AddArg(v1) return true @@ -19269,16 +19253,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x1.Op != OpAMD64MOVBload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 8 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 8 { continue } x0 := sh.Args[0] - if x0.Op != OpAMD64MOVBload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVBload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19289,10 +19273,10 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { b = mergePoint(b, x0, x1) v0 := b.NewValue0(x0.Pos, OpAMD64ROLWconst, v.Type) v.copyOf(v0) - v0.AuxInt = 8 + v0.AuxInt = int8ToAuxInt(8) v1 := b.NewValue0(x0.Pos, OpAMD64MOVWload, typ.UInt16) - v1.AuxInt = i - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i) + v1.Aux = symToAux(s) v1.AddArg2(p0, mem) v0.AddArg(v1) return true @@ -19305,31 +19289,31 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { r1 := v_0 - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 { continue } r0 := sh.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19340,8 +19324,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v1.AuxInt = i0 - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i0) + v1.Aux = symToAux(s) v1.AddArg2(p, mem) v0.AddArg(v1) return true @@ -19354,27 +19338,27 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { r1 := v_0 - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 16 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 16 { continue } r0 := sh.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] - if x0.Op != OpAMD64MOVWload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVWload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19386,8 +19370,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPL, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVLload, typ.UInt32) - v1.AuxInt = i - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i) + v1.Aux = symToAux(s) v1.AddArg2(p0, mem) v0.AddArg(v1) return true @@ -19407,12 +19391,12 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x1.Op != OpAMD64MOVLload { continue } - i1 := x1.AuxInt - s := x1.Aux + i1 := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 32 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 { continue } r0 := sh.Args[0] @@ -19423,8 +19407,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x0.Op != OpAMD64MOVLload { continue } - i0 := x0.AuxInt - if x0.Aux != s { + i0 := auxIntToInt32(x0.AuxInt) + if auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19435,8 +19419,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVQload, typ.UInt64) - v1.AuxInt = i0 - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i0) + v1.Aux = symToAux(s) v1.AddArg2(p, mem) v0.AddArg(v1) return true @@ -19456,12 +19440,12 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if x1.Op != OpAMD64MOVLload { continue } - i := x1.AuxInt - s := x1.Aux + i := auxIntToInt32(x1.AuxInt) + s := auxToSym(x1.Aux) mem := x1.Args[1] p1 := x1.Args[0] sh := v_1 - if sh.Op != OpAMD64SHLQconst || sh.AuxInt != 32 { + if sh.Op != OpAMD64SHLQconst || auxIntToInt8(sh.AuxInt) != 32 { continue } r0 := sh.Args[0] @@ -19469,7 +19453,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { continue } x0 := r0.Args[0] - if x0.Op != OpAMD64MOVLload || x0.AuxInt != i || x0.Aux != s { + if x0.Op != OpAMD64MOVLload || auxIntToInt32(x0.AuxInt) != i || auxToSym(x0.Aux) != s { continue } _ = x0.Args[1] @@ -19481,8 +19465,8 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x0.Pos, OpAMD64BSWAPQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x0.Pos, OpAMD64MOVQload, typ.UInt64) - v1.AuxInt = i - v1.Aux = s + v1.AuxInt = int32ToAuxInt(i) + v1.Aux = symToAux(s) v1.AddArg2(p0, mem) v0.AddArg(v1) return true @@ -19498,13 +19482,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] or := v_1 @@ -19519,13 +19503,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] if x1.Op != OpAMD64MOVBload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -19540,12 +19524,12 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16) - v2.AuxInt = 8 + v2.AuxInt = int8ToAuxInt(8) v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) - v3.AuxInt = i0 - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i0) + v3.Aux = symToAux(s) v3.AddArg2(p, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -19564,13 +19548,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) x0 := s0.Args[0] if x0.Op != OpAMD64MOVBload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] or := v_1 @@ -19585,9 +19569,9 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) x1 := s1.Args[0] - if x1.Op != OpAMD64MOVBload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVBload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -19603,12 +19587,12 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64ROLWconst, typ.UInt16) - v2.AuxInt = 8 + v2.AuxInt = int8ToAuxInt(8) v3 := b.NewValue0(x1.Pos, OpAMD64MOVWload, typ.UInt16) - v3.AuxInt = i - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i) + v3.Aux = symToAux(s) v3.AddArg2(p0, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -19627,17 +19611,17 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) r0 := s0.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] if x0.Op != OpAMD64MOVWload { continue } - i0 := x0.AuxInt - s := x0.Aux + i0 := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p := x0.Args[0] or := v_1 @@ -19652,17 +19636,17 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) r1 := s1.Args[0] - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] if x1.Op != OpAMD64MOVWload { continue } - i1 := x1.AuxInt - if x1.Aux != s { + i1 := auxIntToInt32(x1.AuxInt) + if auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -19677,11 +19661,11 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64BSWAPL, typ.UInt32) v3 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) - v3.AuxInt = i0 - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i0) + v3.Aux = symToAux(s) v3.AddArg2(p, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -19700,17 +19684,17 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s0.Op != OpAMD64SHLQconst { continue } - j0 := s0.AuxInt + j0 := auxIntToInt8(s0.AuxInt) r0 := s0.Args[0] - if r0.Op != OpAMD64ROLWconst || r0.AuxInt != 8 { + if r0.Op != OpAMD64ROLWconst || auxIntToInt8(r0.AuxInt) != 8 { continue } x0 := r0.Args[0] if x0.Op != OpAMD64MOVWload { continue } - i := x0.AuxInt - s := x0.Aux + i := auxIntToInt32(x0.AuxInt) + s := auxToSym(x0.Aux) mem := x0.Args[1] p0 := x0.Args[0] or := v_1 @@ -19725,13 +19709,13 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if s1.Op != OpAMD64SHLQconst { continue } - j1 := s1.AuxInt + j1 := auxIntToInt8(s1.AuxInt) r1 := s1.Args[0] - if r1.Op != OpAMD64ROLWconst || r1.AuxInt != 8 { + if r1.Op != OpAMD64ROLWconst || auxIntToInt8(r1.AuxInt) != 8 { continue } x1 := r1.Args[0] - if x1.Op != OpAMD64MOVWload || x1.AuxInt != i || x1.Aux != s { + if x1.Op != OpAMD64MOVWload || auxIntToInt32(x1.AuxInt) != i || auxToSym(x1.Aux) != s { continue } _ = x1.Args[1] @@ -19747,11 +19731,11 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { v0 := b.NewValue0(x1.Pos, OpAMD64ORQ, v.Type) v.copyOf(v0) v1 := b.NewValue0(x1.Pos, OpAMD64SHLQconst, v.Type) - v1.AuxInt = j1 + v1.AuxInt = int8ToAuxInt(j1) v2 := b.NewValue0(x1.Pos, OpAMD64BSWAPL, typ.UInt32) v3 := b.NewValue0(x1.Pos, OpAMD64MOVLload, typ.UInt32) - v3.AuxInt = i - v3.Aux = s + v3.AuxInt = int32ToAuxInt(i) + v3.Aux = symToAux(s) v3.AddArg2(p0, mem) v2.AddArg(v3) v1.AddArg(v2) @@ -19771,16 +19755,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool { if l.Op != OpAMD64MOVQload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64ORQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -19839,7 +19823,7 @@ func rewriteValueAMD64_OpAMD64ORQconst(v *Value) bool { // match: (ORQconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -19849,23 +19833,23 @@ func rewriteValueAMD64_OpAMD64ORQconst(v *Value) bool { // match: (ORQconst [-1] _) // result: (MOVQconst [-1]) for { - if v.AuxInt != -1 { + if auxIntToInt32(v.AuxInt) != -1 { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (ORQconst [c] (MOVQconst [d])) - // result: (MOVQconst [c|d]) + // result: (MOVQconst [int64(c)|d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c | d + v.AuxInt = int64ToAuxInt(int64(c) | d) return true } return false @@ -19895,24 +19879,24 @@ func rewriteValueAMD64_OpAMD64ORQconstmodify(v *Value) bool { return true } // match: (ORQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (ORQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (ORQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -19947,36 +19931,36 @@ func rewriteValueAMD64_OpAMD64ORQload(v *Value) bool { return true } // match: (ORQload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ORQload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: ( ORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) // result: ( ORQ x (MOVQf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSDstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSDstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -20018,25 +20002,25 @@ func rewriteValueAMD64_OpAMD64ORQmodify(v *Value) bool { return true } // match: (ORQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (ORQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64ORQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -20640,13 +20624,13 @@ func rewriteValueAMD64_OpAMD64SARBconst(v *Value) bool { // match: (SARBconst [c] (MOVQconst [d])) // result: (MOVQconst [int64(int8(d))>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(int8(d)) >> uint64(c) + v.AuxInt = int64ToAuxInt(int64(int8(d)) >> uint64(c)) return true } return false @@ -20862,13 +20846,13 @@ func rewriteValueAMD64_OpAMD64SARLconst(v *Value) bool { // match: (SARLconst [c] (MOVQconst [d])) // result: (MOVQconst [int64(int32(d))>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(int32(d)) >> uint64(c) + v.AuxInt = int64ToAuxInt(int64(int32(d)) >> uint64(c)) return true } return false @@ -21084,13 +21068,13 @@ func rewriteValueAMD64_OpAMD64SARQconst(v *Value) bool { // match: (SARQconst [c] (MOVQconst [d])) // result: (MOVQconst [d>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = d >> uint64(c) + v.AuxInt = int64ToAuxInt(d >> uint64(c)) return true } return false @@ -21141,13 +21125,13 @@ func rewriteValueAMD64_OpAMD64SARWconst(v *Value) bool { // match: (SARWconst [c] (MOVQconst [d])) // result: (MOVQconst [int64(int16(d))>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(int16(d)) >> uint64(c) + v.AuxInt = int64ToAuxInt(int64(int16(d)) >> uint64(c)) return true } return false @@ -21161,7 +21145,7 @@ func rewriteValueAMD64_OpAMD64SBBLcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SBBLcarrymask (FlagLT_ULT)) @@ -21171,7 +21155,7 @@ func rewriteValueAMD64_OpAMD64SBBLcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = -1 + v.AuxInt = int32ToAuxInt(-1) return true } // match: (SBBLcarrymask (FlagLT_UGT)) @@ -21181,7 +21165,7 @@ func rewriteValueAMD64_OpAMD64SBBLcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SBBLcarrymask (FlagGT_ULT)) @@ -21191,7 +21175,7 @@ func rewriteValueAMD64_OpAMD64SBBLcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = -1 + v.AuxInt = int32ToAuxInt(-1) return true } // match: (SBBLcarrymask (FlagGT_UGT)) @@ -21201,7 +21185,7 @@ func rewriteValueAMD64_OpAMD64SBBLcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -21251,7 +21235,7 @@ func rewriteValueAMD64_OpAMD64SBBQcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (SBBQcarrymask (FlagLT_ULT)) @@ -21261,7 +21245,7 @@ func rewriteValueAMD64_OpAMD64SBBQcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (SBBQcarrymask (FlagLT_UGT)) @@ -21271,7 +21255,7 @@ func rewriteValueAMD64_OpAMD64SBBQcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (SBBQcarrymask (FlagGT_ULT)) @@ -21281,7 +21265,7 @@ func rewriteValueAMD64_OpAMD64SBBQcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (SBBQcarrymask (FlagGT_UGT)) @@ -21291,7 +21275,7 @@ func rewriteValueAMD64_OpAMD64SBBQcarrymask(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } return false @@ -21334,7 +21318,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETA (FlagLT_ULT)) @@ -21344,7 +21328,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETA (FlagLT_UGT)) @@ -21354,7 +21338,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETA (FlagGT_ULT)) @@ -21364,7 +21348,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETA (FlagGT_UGT)) @@ -21374,7 +21358,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } return false @@ -21455,7 +21439,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETAE (FlagLT_ULT)) @@ -21465,7 +21449,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETAE (FlagLT_UGT)) @@ -21475,7 +21459,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETAE (FlagGT_ULT)) @@ -21485,7 +21469,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETAE (FlagGT_UGT)) @@ -21495,7 +21479,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } return false @@ -21546,115 +21530,115 @@ func rewriteValueAMD64_OpAMD64SETAEstore(v *Value) bool { return true } // match: (SETAEstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETAEstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETAEstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETAEstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETAEstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETAEstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETAEstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETAEstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } @@ -21706,115 +21690,115 @@ func rewriteValueAMD64_OpAMD64SETAstore(v *Value) bool { return true } // match: (SETAstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETAstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETAstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETAstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETAstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETAstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETAstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETAstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } @@ -21920,7 +21904,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETB (FlagLT_ULT)) @@ -21930,7 +21914,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETB (FlagLT_UGT)) @@ -21940,7 +21924,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETB (FlagGT_ULT)) @@ -21950,7 +21934,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETB (FlagGT_UGT)) @@ -21960,7 +21944,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -21985,7 +21969,7 @@ func rewriteValueAMD64_OpAMD64SETBE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETBE (FlagLT_ULT)) @@ -21995,7 +21979,7 @@ func rewriteValueAMD64_OpAMD64SETBE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETBE (FlagLT_UGT)) @@ -22005,7 +21989,7 @@ func rewriteValueAMD64_OpAMD64SETBE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETBE (FlagGT_ULT)) @@ -22015,7 +21999,7 @@ func rewriteValueAMD64_OpAMD64SETBE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETBE (FlagGT_UGT)) @@ -22025,7 +22009,7 @@ func rewriteValueAMD64_OpAMD64SETBE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -22076,115 +22060,115 @@ func rewriteValueAMD64_OpAMD64SETBEstore(v *Value) bool { return true } // match: (SETBEstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETBEstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETBEstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETBEstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETBEstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETBEstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETBEstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETBEstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } @@ -22236,115 +22220,115 @@ func rewriteValueAMD64_OpAMD64SETBstore(v *Value) bool { return true } // match: (SETBstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETBstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETBstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETBstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETBstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETBstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETBstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } @@ -22447,7 +22431,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { } // match: (SETEQ (TESTQ (MOVQconst [c]) x)) // cond: isUint64PowerOfTwo(c) - // result: (SETAE (BTQconst [int8(log2(c))] x)) + // result: (SETAE (BTQconst [int8(log64(c))] x)) for { if v_0.Op != OpAMD64TESTQ { break @@ -22466,7 +22450,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { } v.reset(OpAMD64SETAE) v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) v.AddArg(v0) return true @@ -22715,7 +22699,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETEQ (FlagLT_ULT)) @@ -22725,7 +22709,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETEQ (FlagLT_UGT)) @@ -22735,7 +22719,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETEQ (FlagGT_ULT)) @@ -22745,7 +22729,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETEQ (FlagGT_UGT)) @@ -22755,7 +22739,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -22884,7 +22868,7 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool { } // match: (SETEQstore [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) // cond: isUint64PowerOfTwo(c) - // result: (SETAEstore [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem) + // result: (SETAEstore [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem) for { off := auxIntToInt32(v.AuxInt) sym := auxToSym(v.Aux) @@ -22909,7 +22893,7 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool { v.AuxInt = int32ToAuxInt(off) v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) v.AddArg3(ptr, v0, mem) return true @@ -23228,115 +23212,115 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool { return true } // match: (SETEQstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETEQstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETEQstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETEQstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETEQstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETEQstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETEQstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETEQstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } @@ -23362,7 +23346,7 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETG (FlagLT_ULT)) @@ -23372,7 +23356,7 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETG (FlagLT_UGT)) @@ -23382,7 +23366,7 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETG (FlagGT_ULT)) @@ -23392,7 +23376,7 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETG (FlagGT_UGT)) @@ -23402,7 +23386,7 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } return false @@ -23427,7 +23411,7 @@ func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETGE (FlagLT_ULT)) @@ -23437,7 +23421,7 @@ func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETGE (FlagLT_UGT)) @@ -23447,7 +23431,7 @@ func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETGE (FlagGT_ULT)) @@ -23457,7 +23441,7 @@ func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETGE (FlagGT_UGT)) @@ -23467,7 +23451,7 @@ func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } return false @@ -23518,115 +23502,115 @@ func rewriteValueAMD64_OpAMD64SETGEstore(v *Value) bool { return true } // match: (SETGEstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETGEstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETGEstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETGEstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETGEstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETGEstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETGEstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETGEstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } @@ -23678,115 +23662,115 @@ func rewriteValueAMD64_OpAMD64SETGstore(v *Value) bool { return true } // match: (SETGstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETGstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETGstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETGstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETGstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETGstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETGstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETGstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } @@ -23812,7 +23796,7 @@ func rewriteValueAMD64_OpAMD64SETL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETL (FlagLT_ULT)) @@ -23822,7 +23806,7 @@ func rewriteValueAMD64_OpAMD64SETL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETL (FlagLT_UGT)) @@ -23832,7 +23816,7 @@ func rewriteValueAMD64_OpAMD64SETL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETL (FlagGT_ULT)) @@ -23842,7 +23826,7 @@ func rewriteValueAMD64_OpAMD64SETL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETL (FlagGT_UGT)) @@ -23852,7 +23836,7 @@ func rewriteValueAMD64_OpAMD64SETL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -23877,7 +23861,7 @@ func rewriteValueAMD64_OpAMD64SETLE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETLE (FlagLT_ULT)) @@ -23887,7 +23871,7 @@ func rewriteValueAMD64_OpAMD64SETLE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETLE (FlagLT_UGT)) @@ -23897,7 +23881,7 @@ func rewriteValueAMD64_OpAMD64SETLE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETLE (FlagGT_ULT)) @@ -23907,7 +23891,7 @@ func rewriteValueAMD64_OpAMD64SETLE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETLE (FlagGT_UGT)) @@ -23917,7 +23901,7 @@ func rewriteValueAMD64_OpAMD64SETLE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -23968,115 +23952,115 @@ func rewriteValueAMD64_OpAMD64SETLEstore(v *Value) bool { return true } // match: (SETLEstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETLEstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETLEstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETLEstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETLEstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETLEstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETLEstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETLEstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } @@ -24128,115 +24112,115 @@ func rewriteValueAMD64_OpAMD64SETLstore(v *Value) bool { return true } // match: (SETLstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETLstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETLstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETLstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETLstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETLstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETLstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } @@ -24363,7 +24347,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { } // match: (SETNE (TESTQ (MOVQconst [c]) x)) // cond: isUint64PowerOfTwo(c) - // result: (SETB (BTQconst [int8(log2(c))] x)) + // result: (SETB (BTQconst [int8(log64(c))] x)) for { if v_0.Op != OpAMD64TESTQ { break @@ -24382,7 +24366,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { } v.reset(OpAMD64SETB) v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) v.AddArg(v0) return true @@ -24631,7 +24615,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SETNE (FlagLT_ULT)) @@ -24641,7 +24625,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETNE (FlagLT_UGT)) @@ -24651,7 +24635,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETNE (FlagGT_ULT)) @@ -24661,7 +24645,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } // match: (SETNE (FlagGT_UGT)) @@ -24671,7 +24655,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) return true } return false @@ -24800,7 +24784,7 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool { } // match: (SETNEstore [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) // cond: isUint64PowerOfTwo(c) - // result: (SETBstore [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem) + // result: (SETBstore [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem) for { off := auxIntToInt32(v.AuxInt) sym := auxToSym(v.Aux) @@ -24825,7 +24809,7 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool { v.AuxInt = int32ToAuxInt(off) v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) v.AddArg3(ptr, v0, mem) return true @@ -25144,115 +25128,115 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool { return true } // match: (SETNEstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SETNEstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SETNEstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } // match: (SETNEstore [off] {sym} ptr (FlagEQ) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagEQ { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (SETNEstore [off] {sym} ptr (FlagLT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETNEstore [off] {sym} ptr (FlagLT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagLT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETNEstore [off] {sym} ptr (FlagGT_ULT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_ULT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } // match: (SETNEstore [off] {sym} ptr (FlagGT_UGT) mem) // result: (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpAMD64FlagGT_UGT { break } mem := v_2 v.reset(OpAMD64MOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v.AddArg3(ptr, v0, mem) return true } @@ -25479,15 +25463,15 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool { return true } // match: (SHLLconst [d] (MOVLconst [c])) - // result: (MOVLconst [int64(int32(c)) << uint64(d)]) + // result: (MOVLconst [c << uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(int32(c)) << uint64(d) + v.AuxInt = int32ToAuxInt(c << uint64(d)) return true } return false @@ -25715,25 +25699,25 @@ func rewriteValueAMD64_OpAMD64SHLQconst(v *Value) bool { // match: (SHLQconst [d] (MOVQconst [c])) // result: (MOVQconst [c << uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c << uint64(d) + v.AuxInt = int64ToAuxInt(c << uint64(d)) return true } // match: (SHLQconst [d] (MOVLconst [c])) - // result: (MOVQconst [int64(int32(c)) << uint64(d)]) + // result: (MOVQconst [int64(c) << uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt8(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = int64(int32(c)) << uint64(d) + v.AuxInt = int64ToAuxInt(int64(c) << uint64(d)) return true } return false @@ -26388,7 +26372,7 @@ func rewriteValueAMD64_OpAMD64SUBL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SUBL x l:(MOVLload [off] {sym} ptr mem)) @@ -26400,16 +26384,16 @@ func rewriteValueAMD64_OpAMD64SUBL(v *Value) bool { if l.Op != OpAMD64MOVLload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64SUBLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -26418,24 +26402,24 @@ func rewriteValueAMD64_OpAMD64SUBL(v *Value) bool { func rewriteValueAMD64_OpAMD64SUBLconst(v *Value) bool { v_0 := v.Args[0] // match: (SUBLconst [c] x) - // cond: int32(c) == 0 + // cond: c==0 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 - if !(int32(c) == 0) { + if !(c == 0) { break } v.copyOf(x) return true } // match: (SUBLconst [c] x) - // result: (ADDLconst [int64(int32(-c))] x) + // result: (ADDLconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 v.reset(OpAMD64ADDLconst) - v.AuxInt = int64(int32(-c)) + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } @@ -26469,36 +26453,36 @@ func rewriteValueAMD64_OpAMD64SUBLload(v *Value) bool { return true } // match: (SUBLload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (SUBLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) // result: (SUBL x (MOVLf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSSstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSSstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -26540,25 +26524,25 @@ func rewriteValueAMD64_OpAMD64SUBLmodify(v *Value) bool { return true } // match: (SUBLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -26612,7 +26596,7 @@ func rewriteValueAMD64_OpAMD64SUBQ(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (SUBQ x l:(MOVQload [off] {sym} ptr mem)) @@ -26624,16 +26608,16 @@ func rewriteValueAMD64_OpAMD64SUBQ(v *Value) bool { if l.Op != OpAMD64MOVQload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64SUBQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -26666,7 +26650,7 @@ func rewriteValueAMD64_OpAMD64SUBQconst(v *Value) bool { // match: (SUBQconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -26677,43 +26661,43 @@ func rewriteValueAMD64_OpAMD64SUBQconst(v *Value) bool { // cond: c != -(1<<31) // result: (ADDQconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(c != -(1 << 31)) { break } v.reset(OpAMD64ADDQconst) - v.AuxInt = -c + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } // match: (SUBQconst (MOVQconst [d]) [c]) - // result: (MOVQconst [d-c]) + // result: (MOVQconst [d-int64(c)]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = d - c + v.AuxInt = int64ToAuxInt(d - int64(c)) return true } // match: (SUBQconst (SUBQconst x [d]) [c]) - // cond: is32Bit(-c-d) + // cond: is32Bit(int64(-c)-int64(d)) // result: (ADDQconst [-c-d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64SUBQconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] - if !(is32Bit(-c - d)) { + if !(is32Bit(int64(-c) - int64(d))) { break } v.reset(OpAMD64ADDQconst) - v.AuxInt = -c - d + v.AuxInt = int32ToAuxInt(-c - d) v.AddArg(x) return true } @@ -26748,36 +26732,36 @@ func rewriteValueAMD64_OpAMD64SUBQload(v *Value) bool { return true } // match: (SUBQload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBQload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (SUBQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) // result: (SUBQ x (MOVQf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSDstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSDstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -26819,25 +26803,25 @@ func rewriteValueAMD64_OpAMD64SUBQmodify(v *Value) bool { return true } // match: (SUBQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -26855,16 +26839,16 @@ func rewriteValueAMD64_OpAMD64SUBSD(v *Value) bool { if l.Op != OpAMD64MOVSDload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64SUBSDload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -26899,36 +26883,36 @@ func rewriteValueAMD64_OpAMD64SUBSDload(v *Value) bool { return true } // match: (SUBSDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBSDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBSDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (SUBSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) // result: (SUBSD x (MOVQi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVQstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVQstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -26955,16 +26939,16 @@ func rewriteValueAMD64_OpAMD64SUBSS(v *Value) bool { if l.Op != OpAMD64MOVSSload { break } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { break } v.reset(OpAMD64SUBSSload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -26999,36 +26983,36 @@ func rewriteValueAMD64_OpAMD64SUBSSload(v *Value) bool { return true } // match: (SUBSSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (SUBSSload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64SUBSSload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (SUBSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) // result: (SUBSS x (MOVLi2f y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVLstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVLstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -27048,43 +27032,43 @@ func rewriteValueAMD64_OpAMD64TESTB(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (TESTB (MOVLconst [c]) x) - // result: (TESTBconst [c] x) + // result: (TESTBconst [int8(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVLconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpAMD64TESTBconst) - v.AuxInt = c + v.AuxInt = int8ToAuxInt(int8(c)) v.AddArg(x) return true } break } // match: (TESTB l:(MOVBload {sym} [off] ptr mem) l2) - // cond: l == l2 && l.Uses == 2 && validValAndOff(0,off) && clobber(l) - // result: @l.Block (CMPBconstload {sym} [makeValAndOff(0,off)] ptr mem) + // cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l) + // result: @l.Block (CMPBconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { l := v_0 if l.Op != OpAMD64MOVBload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] l2 := v_1 - if !(l == l2 && l.Uses == 2 && validValAndOff(0, off) && clobber(l)) { + if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) { continue } b = l.Block v0 := b.NewValue0(l.Pos, OpAMD64CMPBconstload, types.TypeFlags) v.copyOf(v0) - v0.AuxInt = makeValAndOff(0, off) - v0.Aux = sym + v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off))) + v0.Aux = symToAux(sym) v0.AddArg2(ptr, mem) return true } @@ -27098,7 +27082,7 @@ func rewriteValueAMD64_OpAMD64TESTBconst(v *Value) bool { // cond: x.Op != OpAMD64MOVLconst // result: (TESTB x x) for { - if v.AuxInt != -1 { + if auxIntToInt8(v.AuxInt) != -1 { break } x := v_0 @@ -27122,37 +27106,37 @@ func rewriteValueAMD64_OpAMD64TESTL(v *Value) bool { if v_0.Op != OpAMD64MOVLconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpAMD64TESTLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } break } // match: (TESTL l:(MOVLload {sym} [off] ptr mem) l2) - // cond: l == l2 && l.Uses == 2 && validValAndOff(0,off) && clobber(l) - // result: @l.Block (CMPLconstload {sym} [makeValAndOff(0,off)] ptr mem) + // cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l) + // result: @l.Block (CMPLconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { l := v_0 if l.Op != OpAMD64MOVLload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] l2 := v_1 - if !(l == l2 && l.Uses == 2 && validValAndOff(0, off) && clobber(l)) { + if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) { continue } b = l.Block v0 := b.NewValue0(l.Pos, OpAMD64CMPLconstload, types.TypeFlags) v.copyOf(v0) - v0.AuxInt = makeValAndOff(0, off) - v0.Aux = sym + v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off))) + v0.Aux = symToAux(sym) v0.AddArg2(ptr, mem) return true } @@ -27166,8 +27150,8 @@ func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool { // cond: c == 0 // result: (FlagEQ) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c == 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0.AuxInt) != c || !(c == 0) { break } v.reset(OpAMD64FlagEQ) @@ -27177,8 +27161,8 @@ func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool { // cond: c < 0 // result: (FlagLT_UGT) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c < 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0.AuxInt) != c || !(c < 0) { break } v.reset(OpAMD64FlagLT_UGT) @@ -27188,8 +27172,8 @@ func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool { // cond: c > 0 // result: (FlagGT_UGT) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVLconst || v_0.AuxInt != c || !(c > 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0.AuxInt) != c || !(c > 0) { break } v.reset(OpAMD64FlagGT_UGT) @@ -27199,7 +27183,7 @@ func rewriteValueAMD64_OpAMD64TESTLconst(v *Value) bool { // cond: x.Op != OpAMD64MOVLconst // result: (TESTL x x) for { - if v.AuxInt != -1 { + if auxIntToInt32(v.AuxInt) != -1 { break } x := v_0 @@ -27218,46 +27202,46 @@ func rewriteValueAMD64_OpAMD64TESTQ(v *Value) bool { b := v.Block // match: (TESTQ (MOVQconst [c]) x) // cond: is32Bit(c) - // result: (TESTQconst [c] x) + // result: (TESTQconst [int32(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVQconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 if !(is32Bit(c)) { continue } v.reset(OpAMD64TESTQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } break } // match: (TESTQ l:(MOVQload {sym} [off] ptr mem) l2) - // cond: l == l2 && l.Uses == 2 && validValAndOff(0,off) && clobber(l) - // result: @l.Block (CMPQconstload {sym} [makeValAndOff(0,off)] ptr mem) + // cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l) + // result: @l.Block (CMPQconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { l := v_0 if l.Op != OpAMD64MOVQload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] l2 := v_1 - if !(l == l2 && l.Uses == 2 && validValAndOff(0, off) && clobber(l)) { + if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) { continue } b = l.Block v0 := b.NewValue0(l.Pos, OpAMD64CMPQconstload, types.TypeFlags) v.copyOf(v0) - v0.AuxInt = makeValAndOff(0, off) - v0.Aux = sym + v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off))) + v0.Aux = symToAux(sym) v0.AddArg2(ptr, mem) return true } @@ -27267,34 +27251,46 @@ func rewriteValueAMD64_OpAMD64TESTQ(v *Value) bool { } func rewriteValueAMD64_OpAMD64TESTQconst(v *Value) bool { v_0 := v.Args[0] - // match: (TESTQconst [c] (MOVQconst [c])) - // cond: c == 0 + // match: (TESTQconst [c] (MOVQconst [d])) + // cond: int64(c) == d && c == 0 // result: (FlagEQ) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c == 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVQconst { + break + } + d := auxIntToInt64(v_0.AuxInt) + if !(int64(c) == d && c == 0) { break } v.reset(OpAMD64FlagEQ) return true } - // match: (TESTQconst [c] (MOVQconst [c])) - // cond: c < 0 + // match: (TESTQconst [c] (MOVQconst [d])) + // cond: int64(c) == d && c < 0 // result: (FlagLT_UGT) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c < 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVQconst { + break + } + d := auxIntToInt64(v_0.AuxInt) + if !(int64(c) == d && c < 0) { break } v.reset(OpAMD64FlagLT_UGT) return true } - // match: (TESTQconst [c] (MOVQconst [c])) - // cond: c > 0 + // match: (TESTQconst [c] (MOVQconst [d])) + // cond: int64(c) == d && c > 0 // result: (FlagGT_UGT) for { - c := v.AuxInt - if v_0.Op != OpAMD64MOVQconst || v_0.AuxInt != c || !(c > 0) { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpAMD64MOVQconst { + break + } + d := auxIntToInt64(v_0.AuxInt) + if !(int64(c) == d && c > 0) { break } v.reset(OpAMD64FlagGT_UGT) @@ -27304,7 +27300,7 @@ func rewriteValueAMD64_OpAMD64TESTQconst(v *Value) bool { // cond: x.Op != OpAMD64MOVQconst // result: (TESTQ x x) for { - if v.AuxInt != -1 { + if auxIntToInt32(v.AuxInt) != -1 { break } x := v_0 @@ -27322,43 +27318,43 @@ func rewriteValueAMD64_OpAMD64TESTW(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (TESTW (MOVLconst [c]) x) - // result: (TESTWconst [c] x) + // result: (TESTWconst [int16(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVLconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpAMD64TESTWconst) - v.AuxInt = c + v.AuxInt = int16ToAuxInt(int16(c)) v.AddArg(x) return true } break } // match: (TESTW l:(MOVWload {sym} [off] ptr mem) l2) - // cond: l == l2 && l.Uses == 2 && validValAndOff(0,off) && clobber(l) - // result: @l.Block (CMPWconstload {sym} [makeValAndOff(0,off)] ptr mem) + // cond: l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l) + // result: @l.Block (CMPWconstload {sym} [makeValAndOff64(0, int64(off))] ptr mem) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { l := v_0 if l.Op != OpAMD64MOVWload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] l2 := v_1 - if !(l == l2 && l.Uses == 2 && validValAndOff(0, off) && clobber(l)) { + if !(l == l2 && l.Uses == 2 && validValAndOff(0, int64(off)) && clobber(l)) { continue } b = l.Block v0 := b.NewValue0(l.Pos, OpAMD64CMPWconstload, types.TypeFlags) v.copyOf(v0) - v0.AuxInt = makeValAndOff(0, off) - v0.Aux = sym + v0.AuxInt = valAndOffToAuxInt(makeValAndOff64(0, int64(off))) + v0.Aux = symToAux(sym) v0.AddArg2(ptr, mem) return true } @@ -27372,7 +27368,7 @@ func rewriteValueAMD64_OpAMD64TESTWconst(v *Value) bool { // cond: x.Op != OpAMD64MOVLconst // result: (TESTW x x) for { - if v.AuxInt != -1 { + if auxIntToInt16(v.AuxInt) != -1 { break } x := v_0 @@ -27390,24 +27386,24 @@ func rewriteValueAMD64_OpAMD64XADDLlock(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (XADDLlock [off1] {sym} val (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (XADDLlock [off1+off2] {sym} val ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64ADDQconst { break } - off2 := v_1.AuxInt + off2 := auxIntToInt32(v_1.AuxInt) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64XADDLlock) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(val, ptr, mem) return true } @@ -27418,24 +27414,24 @@ func rewriteValueAMD64_OpAMD64XADDQlock(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (XADDQlock [off1] {sym} val (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (XADDQlock [off1+off2] {sym} val ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64ADDQconst { break } - off2 := v_1.AuxInt + off2 := auxIntToInt32(v_1.AuxInt) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64XADDQlock) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(val, ptr, mem) return true } @@ -27446,47 +27442,47 @@ func rewriteValueAMD64_OpAMD64XCHGL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (XCHGL [off1] {sym} val (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (XCHGL [off1+off2] {sym} val ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64ADDQconst { break } - off2 := v_1.AuxInt + off2 := auxIntToInt32(v_1.AuxInt) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64XCHGL) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(val, ptr, mem) return true } // match: (XCHGL [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB // result: (XCHGL [off1+off2] {mergeSym(sym1,sym2)} val ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB) { break } v.reset(OpAMD64XCHGL) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, ptr, mem) return true } @@ -27497,47 +27493,47 @@ func rewriteValueAMD64_OpAMD64XCHGQ(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (XCHGQ [off1] {sym} val (ADDQconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) + // cond: is32Bit(int64(off1)+int64(off2)) // result: (XCHGQ [off1+off2] {sym} val ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64ADDQconst { break } - off2 := v_1.AuxInt + off2 := auxIntToInt32(v_1.AuxInt) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1 + off2)) { + if !(is32Bit(int64(off1) + int64(off2))) { break } v.reset(OpAMD64XCHGQ) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(val, ptr, mem) return true } // match: (XCHGQ [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB // result: (XCHGQ [off1+off2] {mergeSym(sym1,sym2)} val ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) ptr := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && ptr.Op != OpSB) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB) { break } v.reset(OpAMD64XCHGQ) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, ptr, mem) return true } @@ -27683,7 +27679,7 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool { break } v.reset(OpAMD64MOVLconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (XORL x l:(MOVLload [off] {sym} ptr mem)) @@ -27696,16 +27692,16 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool { if l.Op != OpAMD64MOVLload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64XORLload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -27868,12 +27864,12 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool { return true } // match: (XORLconst [c] x) - // cond: int32(c)==0 + // cond: c==0 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 - if !(int32(c) == 0) { + if !(c == 0) { break } v.copyOf(x) @@ -27882,13 +27878,13 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool { // match: (XORLconst [c] (MOVLconst [d])) // result: (MOVLconst [c^d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVLconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = c ^ d + v.AuxInt = int32ToAuxInt(c ^ d) return true } return false @@ -27918,24 +27914,24 @@ func rewriteValueAMD64_OpAMD64XORLconstmodify(v *Value) bool { return true } // match: (XORLconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (XORLconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (XORLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORLconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -27970,36 +27966,36 @@ func rewriteValueAMD64_OpAMD64XORLload(v *Value) bool { return true } // match: (XORLload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (XORLload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORLload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (XORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) // result: (XORL x (MOVLf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSSstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSSstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -28041,25 +28037,25 @@ func rewriteValueAMD64_OpAMD64XORLmodify(v *Value) bool { return true } // match: (XORLmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (XORLmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORLmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -28089,7 +28085,7 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool { } // match: (XORQ (MOVQconst [c]) x) // cond: isUint64PowerOfTwo(c) && uint64(c) >= 128 - // result: (BTCQconst [int8(log2(c))] x) + // result: (BTCQconst [int8(log64(c))] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpAMD64MOVQconst { @@ -28101,7 +28097,7 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool { continue } v.reset(OpAMD64BTCQconst) - v.AuxInt = int8ToAuxInt(int8(log2(c))) + v.AuxInt = int8ToAuxInt(int8(log64(c))) v.AddArg(x) return true } @@ -28159,7 +28155,7 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool { break } v.reset(OpAMD64MOVQconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (XORQ x l:(MOVQload [off] {sym} ptr mem)) @@ -28172,16 +28168,16 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool { if l.Op != OpAMD64MOVQload { continue } - off := l.AuxInt - sym := l.Aux + off := auxIntToInt32(l.AuxInt) + sym := auxToSym(l.Aux) mem := l.Args[1] ptr := l.Args[0] if !(canMergeLoadClobber(v, l, x) && clobber(l)) { continue } v.reset(OpAMD64XORQload) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(x, ptr, mem) return true } @@ -28240,7 +28236,7 @@ func rewriteValueAMD64_OpAMD64XORQconst(v *Value) bool { // match: (XORQconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -28248,15 +28244,15 @@ func rewriteValueAMD64_OpAMD64XORQconst(v *Value) bool { return true } // match: (XORQconst [c] (MOVQconst [d])) - // result: (MOVQconst [c^d]) + // result: (MOVQconst [int64(c)^d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpAMD64MOVQconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpAMD64MOVQconst) - v.AuxInt = c ^ d + v.AuxInt = int64ToAuxInt(int64(c) ^ d) return true } return false @@ -28286,24 +28282,24 @@ func rewriteValueAMD64_OpAMD64XORQconstmodify(v *Value) bool { return true } // match: (XORQconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) - // cond: ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2) - // result: (XORQconstmodify [ValAndOff(valoff1).add(off2)] {mergeSym(sym1,sym2)} base mem) + // cond: ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) + // result: (XORQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) for { - valoff1 := v.AuxInt - sym1 := v.Aux + valoff1 := auxIntToValAndOff(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] mem := v_1 - if !(ValAndOff(valoff1).canAdd(off2) && canMergeSym(sym1, sym2)) { + if !(ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORQconstmodify) - v.AuxInt = ValAndOff(valoff1).add(off2) - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -28338,36 +28334,36 @@ func rewriteValueAMD64_OpAMD64XORQload(v *Value) bool { return true } // match: (XORQload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (XORQload [off1+off2] {mergeSym(sym1,sym2)} val base mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) val := v_0 if v_1.Op != OpAMD64LEAQ { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) base := v_1.Args[0] mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORQload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(val, base, mem) return true } // match: (XORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) // result: (XORQ x (MOVQf2i y)) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) x := v_0 ptr := v_1 - if v_2.Op != OpAMD64MOVSDstore || v_2.AuxInt != off || v_2.Aux != sym { + if v_2.Op != OpAMD64MOVSDstore || auxIntToInt32(v_2.AuxInt) != off || auxToSym(v_2.Aux) != sym { break } y := v_2.Args[1] @@ -28409,30 +28405,43 @@ func rewriteValueAMD64_OpAMD64XORQmodify(v *Value) bool { return true } // match: (XORQmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) - // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) + // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) // result: (XORQmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpAMD64LEAQ { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) base := v_0.Args[0] val := v_1 mem := v_2 - if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) { + if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)) { break } v.reset(OpAMD64XORQmodify) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } return false } +func rewriteValueAMD64_OpAddr(v *Value) bool { + v_0 := v.Args[0] + // match: (Addr {sym} base) + // result: (LEAQ {sym} base) + for { + sym := auxToSym(v.Aux) + base := v_0 + v.reset(OpAMD64LEAQ) + v.Aux = symToAux(sym) + v.AddArg(base) + return true + } +} func rewriteValueAMD64_OpAtomicAdd32(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -28471,6 +28480,70 @@ func rewriteValueAMD64_OpAtomicAdd64(v *Value) bool { return true } } +func rewriteValueAMD64_OpAtomicAnd32(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicAnd32 ptr val mem) + // result: (ANDLlock ptr val mem) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpAMD64ANDLlock) + v.AddArg3(ptr, val, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicAnd8(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicAnd8 ptr val mem) + // result: (ANDBlock ptr val mem) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpAMD64ANDBlock) + v.AddArg3(ptr, val, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicCompareAndSwap32(v *Value) bool { + v_3 := v.Args[3] + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicCompareAndSwap32 ptr old new_ mem) + // result: (CMPXCHGLlock ptr old new_ mem) + for { + ptr := v_0 + old := v_1 + new_ := v_2 + mem := v_3 + v.reset(OpAMD64CMPXCHGLlock) + v.AddArg4(ptr, old, new_, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicCompareAndSwap64(v *Value) bool { + v_3 := v.Args[3] + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicCompareAndSwap64 ptr old new_ mem) + // result: (CMPXCHGQlock ptr old new_ mem) + for { + ptr := v_0 + old := v_1 + new_ := v_2 + mem := v_3 + v.reset(OpAMD64CMPXCHGQlock) + v.AddArg4(ptr, old, new_, mem) + return true + } +} func rewriteValueAMD64_OpAtomicExchange32(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -28501,6 +28574,88 @@ func rewriteValueAMD64_OpAtomicExchange64(v *Value) bool { return true } } +func rewriteValueAMD64_OpAtomicLoad32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicLoad32 ptr mem) + // result: (MOVLatomicload ptr mem) + for { + ptr := v_0 + mem := v_1 + v.reset(OpAMD64MOVLatomicload) + v.AddArg2(ptr, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicLoad64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicLoad64 ptr mem) + // result: (MOVQatomicload ptr mem) + for { + ptr := v_0 + mem := v_1 + v.reset(OpAMD64MOVQatomicload) + v.AddArg2(ptr, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicLoad8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicLoad8 ptr mem) + // result: (MOVBatomicload ptr mem) + for { + ptr := v_0 + mem := v_1 + v.reset(OpAMD64MOVBatomicload) + v.AddArg2(ptr, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicLoadPtr(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicLoadPtr ptr mem) + // result: (MOVQatomicload ptr mem) + for { + ptr := v_0 + mem := v_1 + v.reset(OpAMD64MOVQatomicload) + v.AddArg2(ptr, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicOr32(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicOr32 ptr val mem) + // result: (ORLlock ptr val mem) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpAMD64ORLlock) + v.AddArg3(ptr, val, mem) + return true + } +} +func rewriteValueAMD64_OpAtomicOr8(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicOr8 ptr val mem) + // result: (ORBlock ptr val mem) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpAMD64ORBlock) + v.AddArg3(ptr, val, mem) + return true + } +} func rewriteValueAMD64_OpAtomicStore32(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -29499,7 +29654,7 @@ func rewriteValueAMD64_OpCondSelect(v *Value) bool { } v.reset(OpAMD64CMOVQNE) v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(check) v.AddArg3(y, x, v0) return true @@ -29517,7 +29672,7 @@ func rewriteValueAMD64_OpCondSelect(v *Value) bool { } v.reset(OpAMD64CMOVLNE) v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(check) v.AddArg3(y, x, v0) return true @@ -29535,7 +29690,7 @@ func rewriteValueAMD64_OpCondSelect(v *Value) bool { } v.reset(OpAMD64CMOVWNE) v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(check) v.AddArg3(y, x, v0) return true @@ -29564,11 +29719,11 @@ func rewriteValueAMD64_OpConst8(v *Value) bool { } func rewriteValueAMD64_OpConstBool(v *Value) bool { // match: (ConstBool [c]) - // result: (MOVLconst [int32(b2i(c))]) + // result: (MOVLconst [b2i32(c)]) for { c := auxIntToBool(v.AuxInt) v.reset(OpAMD64MOVLconst) - v.AuxInt = int32ToAuxInt(int32(b2i(c))) + v.AuxInt = int32ToAuxInt(b2i32(c)) return true } } @@ -34273,7 +34428,7 @@ func rewriteBlockAMD64(b *Block) bool { } // match: (EQ (TESTQ (MOVQconst [c]) x)) // cond: isUint64PowerOfTwo(c) - // result: (UGE (BTQconst [int8(log2(c))] x)) + // result: (UGE (BTQconst [int8(log64(c))] x)) for b.Controls[0].Op == OpAMD64TESTQ { v_0 := b.Controls[0] _ = v_0.Args[1] @@ -34289,7 +34444,7 @@ func rewriteBlockAMD64(b *Block) bool { continue } v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) b.resetWithControl(BlockAMD64UGE, v0) return true @@ -35076,7 +35231,7 @@ func rewriteBlockAMD64(b *Block) bool { } // match: (NE (TESTQ (MOVQconst [c]) x)) // cond: isUint64PowerOfTwo(c) - // result: (ULT (BTQconst [int8(log2(c))] x)) + // result: (ULT (BTQconst [int8(log64(c))] x)) for b.Controls[0].Op == OpAMD64TESTQ { v_0 := b.Controls[0] _ = v_0.Args[1] @@ -35092,7 +35247,7 @@ func rewriteBlockAMD64(b *Block) bool { continue } v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags) - v0.AuxInt = int8ToAuxInt(int8(log2(c))) + v0.AuxInt = int8ToAuxInt(int8(log64(c))) v0.AddArg(x) b.resetWithControl(BlockAMD64ULT, v0) return true diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go index eaf20e27b7..d9d439fa63 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM.go +++ b/src/cmd/compile/internal/ssa/rewriteARM.go @@ -448,8 +448,7 @@ func rewriteValueARM(v *Value) bool { v.Op = OpARMADD return true case OpAddr: - v.Op = OpARMMOVWaddr - return true + return rewriteValueARM_OpAddr(v) case OpAnd16: v.Op = OpARMAND return true @@ -481,23 +480,17 @@ func rewriteValueARM(v *Value) bool { v.Op = OpARMMVN return true case OpConst16: - v.Op = OpARMMOVWconst - return true + return rewriteValueARM_OpConst16(v) case OpConst32: - v.Op = OpARMMOVWconst - return true + return rewriteValueARM_OpConst32(v) case OpConst32F: - v.Op = OpARMMOVFconst - return true + return rewriteValueARM_OpConst32F(v) case OpConst64F: - v.Op = OpARMMOVDconst - return true + return rewriteValueARM_OpConst64F(v) case OpConst8: - v.Op = OpARMMOVWconst - return true + return rewriteValueARM_OpConst8(v) case OpConstBool: - v.Op = OpARMMOVWconst - return true + return rewriteValueARM_OpConstBool(v) case OpConstNil: return rewriteValueARM_OpConstNil(v) case OpCtz16: @@ -905,11 +898,11 @@ func rewriteValueARM_OpARMADC(v *Value) bool { if v_0.Op != OpARMMOVWconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, flags) return true } @@ -923,11 +916,11 @@ func rewriteValueARM_OpARMADC(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMADCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -941,11 +934,11 @@ func rewriteValueARM_OpARMADC(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMADCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -959,11 +952,11 @@ func rewriteValueARM_OpARMADC(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMADCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -1026,32 +1019,32 @@ func rewriteValueARM_OpARMADCconst(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (ADCconst [c] (ADDconst [d] x) flags) - // result: (ADCconst [int64(int32(c+d))] x flags) + // result: (ADCconst [c+d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMADCconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg2(x, flags) return true } // match: (ADCconst [c] (SUBconst [d] x) flags) - // result: (ADCconst [int64(int32(c-d))] x flags) + // result: (ADCconst [c-d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMADCconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg2(x, flags) return true } @@ -1065,33 +1058,33 @@ func rewriteValueARM_OpARMADCshiftLL(v *Value) bool { // match: (ADCshiftLL (MOVWconst [c]) x [d] flags) // result: (ADCconst [c] (SLLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (ADCshiftLL x (MOVWconst [c]) [d] flags) - // result: (ADCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) + // result: (ADCconst x [c<<uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg2(x, flags) return true } @@ -1109,12 +1102,12 @@ func rewriteValueARM_OpARMADCshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -1128,10 +1121,10 @@ func rewriteValueARM_OpARMADCshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMADCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -1145,33 +1138,33 @@ func rewriteValueARM_OpARMADCshiftRA(v *Value) bool { // match: (ADCshiftRA (MOVWconst [c]) x [d] flags) // result: (ADCconst [c] (SRAconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (ADCshiftRA x (MOVWconst [c]) [d] flags) - // result: (ADCconst x [int64(int32(c)>>uint64(d))] flags) + // result: (ADCconst x [c>>uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg2(x, flags) return true } @@ -1189,12 +1182,12 @@ func rewriteValueARM_OpARMADCshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -1208,10 +1201,10 @@ func rewriteValueARM_OpARMADCshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMADCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -1225,33 +1218,33 @@ func rewriteValueARM_OpARMADCshiftRL(v *Value) bool { // match: (ADCshiftRL (MOVWconst [c]) x [d] flags) // result: (ADCconst [c] (SRLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (ADCshiftRL x (MOVWconst [c]) [d] flags) - // result: (ADCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) + // result: (ADCconst x [int32(uint32(c)>>uint64(d))] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMADCconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg2(x, flags) return true } @@ -1269,12 +1262,12 @@ func rewriteValueARM_OpARMADCshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMADCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -1288,10 +1281,10 @@ func rewriteValueARM_OpARMADCshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMADCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -1309,9 +1302,9 @@ func rewriteValueARM_OpARMADD(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -1325,10 +1318,10 @@ func rewriteValueARM_OpARMADD(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1342,10 +1335,10 @@ func rewriteValueARM_OpARMADD(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1359,10 +1352,10 @@ func rewriteValueARM_OpARMADD(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1421,7 +1414,7 @@ func rewriteValueARM_OpARMADD(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARMRSBconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMRSBconst || auxIntToInt32(v_1.AuxInt) != 0 { continue } y := v_1.Args[0] @@ -1439,15 +1432,15 @@ func rewriteValueARM_OpARMADD(v *Value) bool { if v_0.Op != OpARMRSBconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] if v_1.Op != OpARMRSBconst { continue } - d := v_1.AuxInt + d := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMRSBconst) - v.AuxInt = c + d + v.AuxInt = int32ToAuxInt(c + d) v0 := b.NewValue0(v.Pos, OpARMADD, t) v0.AddArg2(x, y) v.AddArg(v0) @@ -1574,9 +1567,9 @@ func rewriteValueARM_OpARMADDS(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -1590,10 +1583,10 @@ func rewriteValueARM_OpARMADDS(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1607,10 +1600,10 @@ func rewriteValueARM_OpARMADDS(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1624,10 +1617,10 @@ func rewriteValueARM_OpARMADDS(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMADDSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1690,31 +1683,31 @@ func rewriteValueARM_OpARMADDSshiftLL(v *Value) bool { // match: (ADDSshiftLL (MOVWconst [c]) x [d]) // result: (ADDSconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDSshiftLL x (MOVWconst [c]) [d]) - // result: (ADDSconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (ADDSconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDSconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -1731,11 +1724,11 @@ func rewriteValueARM_OpARMADDSshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -1749,9 +1742,9 @@ func rewriteValueARM_OpARMADDSshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1764,31 +1757,31 @@ func rewriteValueARM_OpARMADDSshiftRA(v *Value) bool { // match: (ADDSshiftRA (MOVWconst [c]) x [d]) // result: (ADDSconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDSshiftRA x (MOVWconst [c]) [d]) - // result: (ADDSconst x [int64(int32(c)>>uint64(d))]) + // result: (ADDSconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDSconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -1805,11 +1798,11 @@ func rewriteValueARM_OpARMADDSshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -1823,9 +1816,9 @@ func rewriteValueARM_OpARMADDSshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1838,31 +1831,31 @@ func rewriteValueARM_OpARMADDSshiftRL(v *Value) bool { // match: (ADDSshiftRL (MOVWconst [c]) x [d]) // result: (ADDSconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDSshiftRL x (MOVWconst [c]) [d]) - // result: (ADDSconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (ADDSconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDSconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -1879,11 +1872,11 @@ func rewriteValueARM_OpARMADDSshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -1897,9 +1890,9 @@ func rewriteValueARM_OpARMADDSshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -1910,23 +1903,23 @@ func rewriteValueARM_OpARMADDconst(v *Value) bool { // match: (ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) // result: (MOVWaddr [off1+off2] {sym} ptr) for { - off1 := v.AuxInt + off1 := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) ptr := v_0.Args[0] v.reset(OpARMMOVWaddr) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg(ptr) return true } // match: (ADDconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -1935,83 +1928,83 @@ func rewriteValueARM_OpARMADDconst(v *Value) bool { } // match: (ADDconst [c] x) // cond: !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) - // result: (SUBconst [int64(int32(-c))] x) + // result: (SUBconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(!isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c))) { break } v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(-c)) + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } // match: (ADDconst [c] x) // cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff - // result: (SUBconst [int64(int32(-c))] x) + // result: (SUBconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) { break } v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(-c)) + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } // match: (ADDconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(c+d))]) + // result: (MOVWconst [c+d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) return true } // match: (ADDconst [c] (ADDconst [d] x)) - // result: (ADDconst [int64(int32(c+d))] x) + // result: (ADDconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMADDconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg(x) return true } // match: (ADDconst [c] (SUBconst [d] x)) - // result: (ADDconst [int64(int32(c-d))] x) + // result: (ADDconst [c-d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMADDconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg(x) return true } // match: (ADDconst [c] (RSBconst [d] x)) - // result: (RSBconst [int64(int32(c+d))] x) + // result: (RSBconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMRSBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg(x) return true } @@ -2025,39 +2018,39 @@ func rewriteValueARM_OpARMADDshiftLL(v *Value) bool { // match: (ADDshiftLL (MOVWconst [c]) x [d]) // result: (ADDconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDshiftLL x (MOVWconst [c]) [d]) - // result: (ADDconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (ADDconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } // match: (ADDshiftLL [c] (SRLconst x [32-c]) x) // result: (SRRconst [32-c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSRLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -2065,7 +2058,7 @@ func rewriteValueARM_OpARMADDshiftLL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = 32 - c + v.AuxInt = int32ToAuxInt(32 - c) v.AddArg(x) return true } @@ -2087,11 +2080,11 @@ func rewriteValueARM_OpARMADDshiftLL(v *Value) bool { // cond: objabi.GOARM>=6 // result: (REV16 x) for { - if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || v_0.AuxInt != 24 { + if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 { break } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpARMSLLconst || v_0_0.AuxInt != 16 { + if v_0_0.Op != OpARMSLLconst || auxIntToInt32(v_0_0.AuxInt) != 16 { break } x := v_0_0.Args[0] @@ -2115,11 +2108,11 @@ func rewriteValueARM_OpARMADDshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2133,9 +2126,9 @@ func rewriteValueARM_OpARMADDshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2148,31 +2141,31 @@ func rewriteValueARM_OpARMADDshiftRA(v *Value) bool { // match: (ADDshiftRA (MOVWconst [c]) x [d]) // result: (ADDconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDshiftRA x (MOVWconst [c]) [d]) - // result: (ADDconst x [int64(int32(c)>>uint64(d))]) + // result: (ADDconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -2189,11 +2182,11 @@ func rewriteValueARM_OpARMADDshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2207,9 +2200,9 @@ func rewriteValueARM_OpARMADDshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2222,39 +2215,39 @@ func rewriteValueARM_OpARMADDshiftRL(v *Value) bool { // match: (ADDshiftRL (MOVWconst [c]) x [d]) // result: (ADDconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ADDshiftRL x (MOVWconst [c]) [d]) - // result: (ADDconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (ADDconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMADDconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } // match: (ADDshiftRL [c] (SLLconst x [32-c]) x) // result: (SRRconst [ c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSLLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -2262,7 +2255,7 @@ func rewriteValueARM_OpARMADDshiftRL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -2279,11 +2272,11 @@ func rewriteValueARM_OpARMADDshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMADDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2297,9 +2290,9 @@ func rewriteValueARM_OpARMADDshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMADDshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2316,9 +2309,9 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -2332,10 +2325,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMANDshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2349,10 +2342,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMANDshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2366,10 +2359,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMANDshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2456,10 +2449,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMMVNshiftLL { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2473,10 +2466,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMMVNshiftRL { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2490,10 +2483,10 @@ func rewriteValueARM_OpARMAND(v *Value) bool { if v_1.Op != OpARMMVNshiftRA { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2506,18 +2499,18 @@ func rewriteValueARM_OpARMANDconst(v *Value) bool { // match: (ANDconst [0] _) // result: (MOVWconst [0]) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (ANDconst [c] x) // cond: int32(c)==-1 // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(int32(c) == -1) { break @@ -2527,55 +2520,55 @@ func rewriteValueARM_OpARMANDconst(v *Value) bool { } // match: (ANDconst [c] x) // cond: !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) - // result: (BICconst [int64(int32(^uint32(c)))] x) + // result: (BICconst [int32(^uint32(c))] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(!isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c))) { break } v.reset(OpARMBICconst) - v.AuxInt = int64(int32(^uint32(c))) + v.AuxInt = int32ToAuxInt(int32(^uint32(c))) v.AddArg(x) return true } // match: (ANDconst [c] x) // cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff - // result: (BICconst [int64(int32(^uint32(c)))] x) + // result: (BICconst [int32(^uint32(c))] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) { break } v.reset(OpARMBICconst) - v.AuxInt = int64(int32(^uint32(c))) + v.AuxInt = int32ToAuxInt(int32(^uint32(c))) v.AddArg(x) return true } // match: (ANDconst [c] (MOVWconst [d])) // result: (MOVWconst [c&d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = c & d + v.AuxInt = int32ToAuxInt(c & d) return true } // match: (ANDconst [c] (ANDconst [d] x)) // result: (ANDconst [c&d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMANDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMANDconst) - v.AuxInt = c & d + v.AuxInt = int32ToAuxInt(c & d) v.AddArg(x) return true } @@ -2588,31 +2581,31 @@ func rewriteValueARM_OpARMANDshiftLL(v *Value) bool { // match: (ANDshiftLL (MOVWconst [c]) x [d]) // result: (ANDconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ANDshiftLL x (MOVWconst [c]) [d]) - // result: (ANDconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (ANDconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMANDconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -2620,13 +2613,13 @@ func rewriteValueARM_OpARMANDshiftLL(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSLLconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -2646,11 +2639,11 @@ func rewriteValueARM_OpARMANDshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2664,9 +2657,9 @@ func rewriteValueARM_OpARMANDshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMANDshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2679,31 +2672,31 @@ func rewriteValueARM_OpARMANDshiftRA(v *Value) bool { // match: (ANDshiftRA (MOVWconst [c]) x [d]) // result: (ANDconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ANDshiftRA x (MOVWconst [c]) [d]) - // result: (ANDconst x [int64(int32(c)>>uint64(d))]) + // result: (ANDconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMANDconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -2711,13 +2704,13 @@ func rewriteValueARM_OpARMANDshiftRA(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSRAconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -2737,11 +2730,11 @@ func rewriteValueARM_OpARMANDshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2755,9 +2748,9 @@ func rewriteValueARM_OpARMANDshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMANDshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2770,31 +2763,31 @@ func rewriteValueARM_OpARMANDshiftRL(v *Value) bool { // match: (ANDshiftRL (MOVWconst [c]) x [d]) // result: (ANDconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ANDshiftRL x (MOVWconst [c]) [d]) - // result: (ANDconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (ANDconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMANDconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -2802,13 +2795,13 @@ func rewriteValueARM_OpARMANDshiftRL(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSRLconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -2828,11 +2821,11 @@ func rewriteValueARM_OpARMANDshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMANDconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -2846,9 +2839,9 @@ func rewriteValueARM_OpARMANDshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMANDshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2857,15 +2850,15 @@ func rewriteValueARM_OpARMANDshiftRLreg(v *Value) bool { func rewriteValueARM_OpARMBFX(v *Value) bool { v_0 := v.Args[0] // match: (BFX [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))]) + // result: (MOVWconst [d<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8))) + v.AuxInt = int32ToAuxInt(d << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8))) return true } return false @@ -2873,15 +2866,15 @@ func rewriteValueARM_OpARMBFX(v *Value) bool { func rewriteValueARM_OpARMBFXU(v *Value) bool { v_0 := v.Args[0] // match: (BFXU [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))))]) + // result: (MOVWconst [int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(uint32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8)))) + v.AuxInt = int32ToAuxInt(int32(uint32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8)))) return true } return false @@ -2896,9 +2889,9 @@ func rewriteValueARM_OpARMBIC(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMBICconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -2909,10 +2902,10 @@ func rewriteValueARM_OpARMBIC(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2923,10 +2916,10 @@ func rewriteValueARM_OpARMBIC(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2937,10 +2930,10 @@ func rewriteValueARM_OpARMBIC(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMBICshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -2991,7 +2984,7 @@ func rewriteValueARM_OpARMBIC(v *Value) bool { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -3001,7 +2994,7 @@ func rewriteValueARM_OpARMBICconst(v *Value) bool { // match: (BICconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -3012,65 +3005,65 @@ func rewriteValueARM_OpARMBICconst(v *Value) bool { // cond: int32(c)==-1 // result: (MOVWconst [0]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if !(int32(c) == -1) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (BICconst [c] x) // cond: !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) - // result: (ANDconst [int64(int32(^uint32(c)))] x) + // result: (ANDconst [int32(^uint32(c))] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(!isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c))) { break } v.reset(OpARMANDconst) - v.AuxInt = int64(int32(^uint32(c))) + v.AuxInt = int32ToAuxInt(int32(^uint32(c))) v.AddArg(x) return true } // match: (BICconst [c] x) // cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff - // result: (ANDconst [int64(int32(^uint32(c)))] x) + // result: (ANDconst [int32(^uint32(c))] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) { break } v.reset(OpARMANDconst) - v.AuxInt = int64(int32(^uint32(c))) + v.AuxInt = int32ToAuxInt(int32(^uint32(c))) v.AddArg(x) return true } // match: (BICconst [c] (MOVWconst [d])) // result: (MOVWconst [d&^c]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = d &^ c + v.AuxInt = int32ToAuxInt(d &^ c) return true } // match: (BICconst [c] (BICconst [d] x)) - // result: (BICconst [int64(int32(c|d))] x) + // result: (BICconst [c|d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMBICconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMBICconst) - v.AuxInt = int64(int32(c | d)) + v.AuxInt = int32ToAuxInt(c | d) v.AddArg(x) return true } @@ -3080,16 +3073,16 @@ func rewriteValueARM_OpARMBICshiftLL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (BICshiftLL x (MOVWconst [c]) [d]) - // result: (BICconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (BICconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMBICconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -3097,17 +3090,17 @@ func rewriteValueARM_OpARMBICshiftLL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -3124,9 +3117,9 @@ func rewriteValueARM_OpARMBICshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMBICshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3136,16 +3129,16 @@ func rewriteValueARM_OpARMBICshiftRA(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (BICshiftRA x (MOVWconst [c]) [d]) - // result: (BICconst x [int64(int32(c)>>uint64(d))]) + // result: (BICconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMBICconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -3153,17 +3146,17 @@ func rewriteValueARM_OpARMBICshiftRA(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -3180,9 +3173,9 @@ func rewriteValueARM_OpARMBICshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMBICshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3192,16 +3185,16 @@ func rewriteValueARM_OpARMBICshiftRL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (BICshiftRL x (MOVWconst [c]) [d]) - // result: (BICconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (BICconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMBICconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -3209,17 +3202,17 @@ func rewriteValueARM_OpARMBICshiftRL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -3236,9 +3229,9 @@ func rewriteValueARM_OpARMBICshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMBICshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3255,9 +3248,9 @@ func rewriteValueARM_OpARMCMN(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -3271,10 +3264,10 @@ func rewriteValueARM_OpARMCMN(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMNshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3288,10 +3281,10 @@ func rewriteValueARM_OpARMCMN(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMNshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3305,10 +3298,10 @@ func rewriteValueARM_OpARMCMN(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMNshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3362,21 +3355,6 @@ func rewriteValueARM_OpARMCMN(v *Value) bool { } break } - // match: (CMN x (RSBconst [0] y)) - // result: (CMP x y) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - x := v_0 - if v_1.Op != OpARMRSBconst || v_1.AuxInt != 0 { - continue - } - y := v_1.Args[0] - v.reset(OpARMCMP) - v.AddArg2(x, y) - return true - } - break - } return false } func rewriteValueARM_OpARMCMNconst(v *Value) bool { @@ -3402,31 +3380,31 @@ func rewriteValueARM_OpARMCMNshiftLL(v *Value) bool { // match: (CMNshiftLL (MOVWconst [c]) x [d]) // result: (CMNconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (CMNshiftLL x (MOVWconst [c]) [d]) - // result: (CMNconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (CMNconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMNconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -3443,11 +3421,11 @@ func rewriteValueARM_OpARMCMNshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -3461,9 +3439,9 @@ func rewriteValueARM_OpARMCMNshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMNshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3476,31 +3454,31 @@ func rewriteValueARM_OpARMCMNshiftRA(v *Value) bool { // match: (CMNshiftRA (MOVWconst [c]) x [d]) // result: (CMNconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (CMNshiftRA x (MOVWconst [c]) [d]) - // result: (CMNconst x [int64(int32(c)>>uint64(d))]) + // result: (CMNconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMNconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -3517,11 +3495,11 @@ func rewriteValueARM_OpARMCMNshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -3535,9 +3513,9 @@ func rewriteValueARM_OpARMCMNshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMNshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3550,31 +3528,31 @@ func rewriteValueARM_OpARMCMNshiftRL(v *Value) bool { // match: (CMNshiftRL (MOVWconst [c]) x [d]) // result: (CMNconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (CMNshiftRL x (MOVWconst [c]) [d]) - // result: (CMNconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (CMNconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMNconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -3591,11 +3569,11 @@ func rewriteValueARM_OpARMCMNshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMCMNconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -3609,9 +3587,9 @@ func rewriteValueARM_OpARMCMNshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMNshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3654,14 +3632,14 @@ func rewriteValueARM_OpARMCMOVWHSconst(v *Value) bool { // match: (CMOVWHSconst x (InvertFlags flags) [c]) // result: (CMOVWLSconst x flags [c]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMInvertFlags { break } flags := v_1.Args[0] v.reset(OpARMCMOVWLSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, flags) return true } @@ -3704,14 +3682,14 @@ func rewriteValueARM_OpARMCMOVWLSconst(v *Value) bool { // match: (CMOVWLSconst x (InvertFlags flags) [c]) // result: (CMOVWHSconst x flags [c]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMInvertFlags { break } flags := v_1.Args[0] v.reset(OpARMCMOVWHSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, flags) return true } @@ -3728,9 +3706,9 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMPconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -3740,11 +3718,11 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) v.AddArg(v0) return true @@ -3771,10 +3749,10 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMPshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3784,12 +3762,12 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) v.AddArg(v0) return true @@ -3801,10 +3779,10 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMPshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3814,12 +3792,12 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) v.AddArg(v0) return true @@ -3831,10 +3809,10 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMCMPshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -3844,12 +3822,12 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) v.AddArg(v0) return true @@ -3938,18 +3916,6 @@ func rewriteValueARM_OpARMCMP(v *Value) bool { v.AddArg(v0) return true } - // match: (CMP x (RSBconst [0] y)) - // result: (CMN x y) - for { - x := v_0 - if v_1.Op != OpARMRSBconst || v_1.AuxInt != 0 { - break - } - y := v_1.Args[0] - v.reset(OpARMCMN) - v.AddArg2(x, y) - return true - } return false } func rewriteValueARM_OpARMCMPD(v *Value) bool { @@ -3959,7 +3925,7 @@ func rewriteValueARM_OpARMCMPD(v *Value) bool { // result: (CMPD0 x) for { x := v_0 - if v_1.Op != OpARMMOVDconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMMOVDconst || auxIntToFloat64(v_1.AuxInt) != 0 { break } v.reset(OpARMCMPD0) @@ -3975,7 +3941,7 @@ func rewriteValueARM_OpARMCMPF(v *Value) bool { // result: (CMPF0 x) for { x := v_0 - if v_1.Op != OpARMMOVFconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMMOVFconst || auxIntToFloat64(v_1.AuxInt) != 0 { break } v.reset(OpARMCMPF0) @@ -4063,33 +4029,33 @@ func rewriteValueARM_OpARMCMPshiftLL(v *Value) bool { // match: (CMPshiftLL (MOVWconst [c]) x [d]) // result: (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d]))) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v1.AuxInt = d + v1.AuxInt = int32ToAuxInt(d) v1.AddArg(x) v0.AddArg(v1) v.AddArg(v0) return true } // match: (CMPshiftLL x (MOVWconst [c]) [d]) - // result: (CMPconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (CMPconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMPconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -4106,12 +4072,12 @@ func rewriteValueARM_OpARMCMPshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v1.AddArg2(x, y) v0.AddArg(v1) @@ -4126,9 +4092,9 @@ func rewriteValueARM_OpARMCMPshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMPshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -4141,33 +4107,33 @@ func rewriteValueARM_OpARMCMPshiftRA(v *Value) bool { // match: (CMPshiftRA (MOVWconst [c]) x [d]) // result: (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d]))) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v1.AuxInt = d + v1.AuxInt = int32ToAuxInt(d) v1.AddArg(x) v0.AddArg(v1) v.AddArg(v0) return true } // match: (CMPshiftRA x (MOVWconst [c]) [d]) - // result: (CMPconst x [int64(int32(c)>>uint64(d))]) + // result: (CMPconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMPconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -4184,12 +4150,12 @@ func rewriteValueARM_OpARMCMPshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v1.AddArg2(x, y) v0.AddArg(v1) @@ -4204,9 +4170,9 @@ func rewriteValueARM_OpARMCMPshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMPshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -4219,33 +4185,33 @@ func rewriteValueARM_OpARMCMPshiftRL(v *Value) bool { // match: (CMPshiftRL (MOVWconst [c]) x [d]) // result: (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d]))) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v1.AuxInt = d + v1.AuxInt = int32ToAuxInt(d) v1.AddArg(x) v0.AddArg(v1) v.AddArg(v0) return true } // match: (CMPshiftRL x (MOVWconst [c]) [d]) - // result: (CMPconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (CMPconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMCMPconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -4262,12 +4228,12 @@ func rewriteValueARM_OpARMCMPshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMInvertFlags) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v1 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1.AddArg2(x, y) v0.AddArg(v1) @@ -4282,9 +4248,9 @@ func rewriteValueARM_OpARMCMPshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMCMPshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -4530,34 +4496,34 @@ func rewriteValueARM_OpARMMOVBUload(v *Value) bool { // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVBUload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVBUload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVBUload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVBUload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -4565,21 +4531,21 @@ func rewriteValueARM_OpARMMOVBUload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVBUload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4587,14 +4553,14 @@ func rewriteValueARM_OpARMMOVBUload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: (MOVBUreg x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVBstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -4608,10 +4574,10 @@ func rewriteValueARM_OpARMMOVBUload(v *Value) bool { // cond: sym == nil // result: (MOVBUloadidx ptr idx mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -4627,15 +4593,15 @@ func rewriteValueARM_OpARMMOVBUload(v *Value) bool { } // match: (MOVBUload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVWconst [int64(read8(sym, off))]) + // result: (MOVWconst [int32(read8(sym, int64(off)))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpARMMOVWconst) - v.AuxInt = int64(read8(sym, off)) + v.AuxInt = int32ToAuxInt(int32(read8(sym, int64(off)))) return true } return false @@ -4669,10 +4635,10 @@ func rewriteValueARM_OpARMMOVBUloadidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVBUload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -4682,11 +4648,11 @@ func rewriteValueARM_OpARMMOVBUloadidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 mem := v_2 v.reset(OpARMMOVBUload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -4711,10 +4677,10 @@ func rewriteValueARM_OpARMMOVBUreg(v *Value) bool { if v_0.Op != OpARMANDconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMANDconst) - v.AuxInt = c & 0xff + v.AuxInt = int32ToAuxInt(c & 0xff) v.AddArg(x) return true } @@ -4730,14 +4696,14 @@ func rewriteValueARM_OpARMMOVBUreg(v *Value) bool { return true } // match: (MOVBUreg (MOVWconst [c])) - // result: (MOVWconst [int64(uint8(c))]) + // result: (MOVWconst [int32(uint8(c))]) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(uint8(c)) + v.AuxInt = int32ToAuxInt(int32(uint8(c))) return true } return false @@ -4748,34 +4714,34 @@ func rewriteValueARM_OpARMMOVBload(v *Value) bool { // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVBload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVBload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVBload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVBload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -4783,21 +4749,21 @@ func rewriteValueARM_OpARMMOVBload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVBload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4805,14 +4771,14 @@ func rewriteValueARM_OpARMMOVBload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: (MOVBreg x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVBstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -4826,10 +4792,10 @@ func rewriteValueARM_OpARMMOVBload(v *Value) bool { // cond: sym == nil // result: (MOVBloadidx ptr idx mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -4874,10 +4840,10 @@ func rewriteValueARM_OpARMMOVBloadidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVBload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -4887,11 +4853,11 @@ func rewriteValueARM_OpARMMOVBloadidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 mem := v_2 v.reset(OpARMMOVBload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -4917,13 +4883,13 @@ func rewriteValueARM_OpARMMOVBreg(v *Value) bool { if v_0.Op != OpARMANDconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] if !(c&0x80 == 0) { break } v.reset(OpARMANDconst) - v.AuxInt = c & 0x7f + v.AuxInt = int32ToAuxInt(c & 0x7f) v.AddArg(x) return true } @@ -4939,14 +4905,14 @@ func rewriteValueARM_OpARMMOVBreg(v *Value) bool { return true } // match: (MOVBreg (MOVWconst [c])) - // result: (MOVWconst [int64(int8(c))]) + // result: (MOVWconst [int32(int8(c))]) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int8(c)) + v.AuxInt = int32ToAuxInt(int32(int8(c))) return true } return false @@ -4958,36 +4924,36 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) // result: (MOVBstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } // match: (MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) // result: (MOVBstore [off1-off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -4995,13 +4961,13 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] val := v_1 mem := v_2 @@ -5009,16 +4975,16 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { break } v.reset(OpARMMOVBstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } // match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem) // result: (MOVBstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVBreg { break @@ -5026,16 +4992,16 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem) // result: (MOVBstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVBUreg { break @@ -5043,16 +5009,16 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem) // result: (MOVBstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHreg { break @@ -5060,16 +5026,16 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem) // result: (MOVBstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHUreg { break @@ -5077,8 +5043,8 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -5086,10 +5052,10 @@ func rewriteValueARM_OpARMMOVBstore(v *Value) bool { // cond: sym == nil // result: (MOVBstoreidx ptr idx val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -5118,11 +5084,11 @@ func rewriteValueARM_OpARMMOVBstoreidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVBstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -5132,12 +5098,12 @@ func rewriteValueARM_OpARMMOVBstoreidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVBstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -5149,34 +5115,34 @@ func rewriteValueARM_OpARMMOVDload(v *Value) bool { // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVDload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVDload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVDload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVDload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -5184,21 +5150,21 @@ func rewriteValueARM_OpARMMOVDload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVDload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5206,14 +5172,14 @@ func rewriteValueARM_OpARMMOVDload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: x for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVDstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -5231,36 +5197,36 @@ func rewriteValueARM_OpARMMOVDstore(v *Value) bool { // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) // result: (MOVDstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVDstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } // match: (MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) // result: (MOVDstore [off1-off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVDstore) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -5268,13 +5234,13 @@ func rewriteValueARM_OpARMMOVDstore(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] val := v_1 mem := v_2 @@ -5282,8 +5248,8 @@ func rewriteValueARM_OpARMMOVDstore(v *Value) bool { break } v.reset(OpARMMOVDstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -5295,34 +5261,34 @@ func rewriteValueARM_OpARMMOVFload(v *Value) bool { // match: (MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVFload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVFload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVFload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVFload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -5330,21 +5296,21 @@ func rewriteValueARM_OpARMMOVFload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVFload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5352,14 +5318,14 @@ func rewriteValueARM_OpARMMOVFload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: x for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVFstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -5377,36 +5343,36 @@ func rewriteValueARM_OpARMMOVFstore(v *Value) bool { // match: (MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) // result: (MOVFstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVFstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } // match: (MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) // result: (MOVFstore [off1-off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVFstore) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -5414,13 +5380,13 @@ func rewriteValueARM_OpARMMOVFstore(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] val := v_1 mem := v_2 @@ -5428,8 +5394,8 @@ func rewriteValueARM_OpARMMOVFstore(v *Value) bool { break } v.reset(OpARMMOVFstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -5443,34 +5409,34 @@ func rewriteValueARM_OpARMMOVHUload(v *Value) bool { // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVHUload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVHUload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVHUload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVHUload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -5478,21 +5444,21 @@ func rewriteValueARM_OpARMMOVHUload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVHUload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5500,14 +5466,14 @@ func rewriteValueARM_OpARMMOVHUload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: (MOVHUreg x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -5521,10 +5487,10 @@ func rewriteValueARM_OpARMMOVHUload(v *Value) bool { // cond: sym == nil // result: (MOVHUloadidx ptr idx mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -5540,15 +5506,15 @@ func rewriteValueARM_OpARMMOVHUload(v *Value) bool { } // match: (MOVHUload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVWconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))]) + // result: (MOVWconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpARMMOVWconst) - v.AuxInt = int64(read16(sym, off, config.ctxt.Arch.ByteOrder)) + v.AuxInt = int32ToAuxInt(int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))) return true } return false @@ -5582,10 +5548,10 @@ func rewriteValueARM_OpARMMOVHUloadidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVHUload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -5595,11 +5561,11 @@ func rewriteValueARM_OpARMMOVHUloadidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 mem := v_2 v.reset(OpARMMOVHUload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -5635,10 +5601,10 @@ func rewriteValueARM_OpARMMOVHUreg(v *Value) bool { if v_0.Op != OpARMANDconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMANDconst) - v.AuxInt = c & 0xffff + v.AuxInt = int32ToAuxInt(c & 0xffff) v.AddArg(x) return true } @@ -5665,14 +5631,14 @@ func rewriteValueARM_OpARMMOVHUreg(v *Value) bool { return true } // match: (MOVHUreg (MOVWconst [c])) - // result: (MOVWconst [int64(uint16(c))]) + // result: (MOVWconst [int32(uint16(c))]) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(uint16(c)) + v.AuxInt = int32ToAuxInt(int32(uint16(c))) return true } return false @@ -5683,34 +5649,34 @@ func rewriteValueARM_OpARMMOVHload(v *Value) bool { // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVHload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVHload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVHload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVHload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -5718,21 +5684,21 @@ func rewriteValueARM_OpARMMOVHload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVHload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5740,14 +5706,14 @@ func rewriteValueARM_OpARMMOVHload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: (MOVHreg x) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -5761,10 +5727,10 @@ func rewriteValueARM_OpARMMOVHload(v *Value) bool { // cond: sym == nil // result: (MOVHloadidx ptr idx mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -5809,10 +5775,10 @@ func rewriteValueARM_OpARMMOVHloadidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVHload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -5822,11 +5788,11 @@ func rewriteValueARM_OpARMMOVHloadidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 mem := v_2 v.reset(OpARMMOVHload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -5874,13 +5840,13 @@ func rewriteValueARM_OpARMMOVHreg(v *Value) bool { if v_0.Op != OpARMANDconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] if !(c&0x8000 == 0) { break } v.reset(OpARMANDconst) - v.AuxInt = c & 0x7fff + v.AuxInt = int32ToAuxInt(c & 0x7fff) v.AddArg(x) return true } @@ -5918,14 +5884,14 @@ func rewriteValueARM_OpARMMOVHreg(v *Value) bool { return true } // match: (MOVHreg (MOVWconst [c])) - // result: (MOVWconst [int64(int16(c))]) + // result: (MOVWconst [int32(int16(c))]) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int16(c)) + v.AuxInt = int32ToAuxInt(int32(int16(c))) return true } return false @@ -5937,36 +5903,36 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) // result: (MOVHstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVHstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } // match: (MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) // result: (MOVHstore [off1-off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVHstore) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -5974,13 +5940,13 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] val := v_1 mem := v_2 @@ -5988,16 +5954,16 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { break } v.reset(OpARMMOVHstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem) // result: (MOVHstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHreg { break @@ -6005,16 +5971,16 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVHstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) // result: (MOVHstore [off] {sym} ptr x mem) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVHUreg { break @@ -6022,8 +5988,8 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { x := v_1.Args[0] mem := v_2 v.reset(OpARMMOVHstore) - v.AuxInt = off - v.Aux = sym + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) v.AddArg3(ptr, x, mem) return true } @@ -6031,10 +5997,10 @@ func rewriteValueARM_OpARMMOVHstore(v *Value) bool { // cond: sym == nil // result: (MOVHstoreidx ptr idx val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -6063,11 +6029,11 @@ func rewriteValueARM_OpARMMOVHstoreidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVHstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -6077,12 +6043,12 @@ func rewriteValueARM_OpARMMOVHstoreidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVHstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -6096,34 +6062,34 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) // result: (MOVWload [off1+off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVWload) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } // match: (MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) // result: (MOVWload [off1-off2] {sym} ptr mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] mem := v_1 v.reset(OpARMMOVWload) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg2(ptr, mem) return true } @@ -6131,21 +6097,21 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] mem := v_1 if !(canMergeSym(sym1, sym2)) { break } v.reset(OpARMMOVWload) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -6153,14 +6119,14 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: x for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) ptr := v_0 if v_1.Op != OpARMMOVWstore { break } - off2 := v_1.AuxInt - sym2 := v_1.Aux + off2 := auxIntToInt32(v_1.AuxInt) + sym2 := auxToSym(v_1.Aux) x := v_1.Args[1] ptr2 := v_1.Args[0] if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) { @@ -6173,10 +6139,10 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: sym == nil // result: (MOVWloadidx ptr idx mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -6194,14 +6160,14 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: sym == nil // result: (MOVWloadshiftLL ptr idx [c] mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftLL { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] mem := v_1 @@ -6209,7 +6175,7 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { break } v.reset(OpARMMOVWloadshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6217,14 +6183,14 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: sym == nil // result: (MOVWloadshiftRL ptr idx [c] mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftRL { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] mem := v_1 @@ -6232,7 +6198,7 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { break } v.reset(OpARMMOVWloadshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6240,14 +6206,14 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { // cond: sym == nil // result: (MOVWloadshiftRA ptr idx [c] mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftRA { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] mem := v_1 @@ -6255,21 +6221,21 @@ func rewriteValueARM_OpARMMOVWload(v *Value) bool { break } v.reset(OpARMMOVWloadshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } // match: (MOVWload [off] {sym} (SB) _) // cond: symIsRO(sym) - // result: (MOVWconst [int64(int32(read32(sym, off, config.ctxt.Arch.ByteOrder)))]) + // result: (MOVWconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))]) for { - off := v.AuxInt - sym := v.Aux + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpSB || !(symIsRO(sym)) { break } v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(read32(sym, off, config.ctxt.Arch.ByteOrder))) + v.AuxInt = int32ToAuxInt(int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))) return true } return false @@ -6302,10 +6268,10 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVWload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -6315,11 +6281,11 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 mem := v_2 v.reset(OpARMMOVWload) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(ptr, mem) return true } @@ -6330,11 +6296,11 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] mem := v_2 v.reset(OpARMMOVWloadshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6344,12 +6310,12 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 mem := v_2 v.reset(OpARMMOVWloadshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6360,11 +6326,11 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] mem := v_2 v.reset(OpARMMOVWloadshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6374,12 +6340,12 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 mem := v_2 v.reset(OpARMMOVWloadshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6390,11 +6356,11 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] mem := v_2 v.reset(OpARMMOVWloadshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6404,12 +6370,12 @@ func rewriteValueARM_OpARMMOVWloadidx(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 mem := v_2 v.reset(OpARMMOVWloadshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, idx, mem) return true } @@ -6423,13 +6389,13 @@ func rewriteValueARM_OpARMMOVWloadshiftLL(v *Value) bool { // cond: c==d && isSamePtr(ptr, ptr2) // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) ptr := v_0 idx := v_1 if v_2.Op != OpARMMOVWstoreshiftLL { break } - d := v_2.AuxInt + d := auxIntToInt32(v_2.AuxInt) x := v_2.Args[2] ptr2 := v_2.Args[0] if idx != v_2.Args[1] || !(c == d && isSamePtr(ptr, ptr2)) { @@ -6439,17 +6405,17 @@ func rewriteValueARM_OpARMMOVWloadshiftLL(v *Value) bool { return true } // match: (MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) - // result: (MOVWload [int64(uint32(c)<<uint64(d))] ptr mem) + // result: (MOVWload [int32(uint32(c)<<uint64(d))] ptr mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVWload) - v.AuxInt = int64(uint32(c) << uint64(d)) + v.AuxInt = int32ToAuxInt(int32(uint32(c) << uint64(d))) v.AddArg2(ptr, mem) return true } @@ -6463,13 +6429,13 @@ func rewriteValueARM_OpARMMOVWloadshiftRA(v *Value) bool { // cond: c==d && isSamePtr(ptr, ptr2) // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) ptr := v_0 idx := v_1 if v_2.Op != OpARMMOVWstoreshiftRA { break } - d := v_2.AuxInt + d := auxIntToInt32(v_2.AuxInt) x := v_2.Args[2] ptr2 := v_2.Args[0] if idx != v_2.Args[1] || !(c == d && isSamePtr(ptr, ptr2)) { @@ -6479,17 +6445,17 @@ func rewriteValueARM_OpARMMOVWloadshiftRA(v *Value) bool { return true } // match: (MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) - // result: (MOVWload [int64(int32(c)>>uint64(d))] ptr mem) + // result: (MOVWload [c>>uint64(d)] ptr mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVWload) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg2(ptr, mem) return true } @@ -6503,13 +6469,13 @@ func rewriteValueARM_OpARMMOVWloadshiftRL(v *Value) bool { // cond: c==d && isSamePtr(ptr, ptr2) // result: x for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) ptr := v_0 idx := v_1 if v_2.Op != OpARMMOVWstoreshiftRL { break } - d := v_2.AuxInt + d := auxIntToInt32(v_2.AuxInt) x := v_2.Args[2] ptr2 := v_2.Args[0] if idx != v_2.Args[1] || !(c == d && isSamePtr(ptr, ptr2)) { @@ -6519,17 +6485,17 @@ func rewriteValueARM_OpARMMOVWloadshiftRL(v *Value) bool { return true } // match: (MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) - // result: (MOVWload [int64(uint32(c)>>uint64(d))] ptr mem) + // result: (MOVWload [int32(uint32(c)>>uint64(d))] ptr mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) mem := v_2 v.reset(OpARMMOVWload) - v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg2(ptr, mem) return true } @@ -6555,9 +6521,9 @@ func rewriteValueARM_OpARMMOVWreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) return true } return false @@ -6569,36 +6535,36 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) // result: (MOVWstore [off1+off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVWstore) - v.AuxInt = off1 + off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } // match: (MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) // result: (MOVWstore [off1-off2] {sym} ptr val mem) for { - off1 := v.AuxInt - sym := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) if v_0.Op != OpARMSUBconst { break } - off2 := v_0.AuxInt + off2 := auxIntToInt32(v_0.AuxInt) ptr := v_0.Args[0] val := v_1 mem := v_2 v.reset(OpARMMOVWstore) - v.AuxInt = off1 - off2 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off1 - off2) + v.Aux = symToAux(sym) v.AddArg3(ptr, val, mem) return true } @@ -6606,13 +6572,13 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // cond: canMergeSym(sym1,sym2) // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { - off1 := v.AuxInt - sym1 := v.Aux + off1 := auxIntToInt32(v.AuxInt) + sym1 := auxToSym(v.Aux) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym2 := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym2 := auxToSym(v_0.Aux) ptr := v_0.Args[0] val := v_1 mem := v_2 @@ -6620,8 +6586,8 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { break } v.reset(OpARMMOVWstore) - v.AuxInt = off1 + off2 - v.Aux = mergeSym(sym1, sym2) + v.AuxInt = int32ToAuxInt(off1 + off2) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -6629,10 +6595,10 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // cond: sym == nil // result: (MOVWstoreidx ptr idx val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADD { break } @@ -6651,14 +6617,14 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // cond: sym == nil // result: (MOVWstoreshiftLL ptr idx [c] val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftLL { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] val := v_1 @@ -6667,7 +6633,7 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { break } v.reset(OpARMMOVWstoreshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6675,14 +6641,14 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // cond: sym == nil // result: (MOVWstoreshiftRL ptr idx [c] val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftRL { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] val := v_1 @@ -6691,7 +6657,7 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { break } v.reset(OpARMMOVWstoreshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6699,14 +6665,14 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { // cond: sym == nil // result: (MOVWstoreshiftRA ptr idx [c] val mem) for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } - sym := v.Aux + sym := auxToSym(v.Aux) if v_0.Op != OpARMADDshiftRA { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[1] ptr := v_0.Args[0] val := v_1 @@ -6715,7 +6681,7 @@ func rewriteValueARM_OpARMMOVWstore(v *Value) bool { break } v.reset(OpARMMOVWstoreshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6733,11 +6699,11 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVWstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -6747,12 +6713,12 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVWstore) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(ptr, val, mem) return true } @@ -6763,12 +6729,12 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6778,13 +6744,13 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6795,12 +6761,12 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6810,13 +6776,13 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6827,12 +6793,12 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) idx := v_1.Args[0] val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6842,13 +6808,13 @@ func rewriteValueARM_OpARMMOVWstoreidx(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) idx := v_0.Args[0] ptr := v_1 val := v_2 mem := v_3 v.reset(OpARMMOVWstoreshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg4(ptr, idx, val, mem) return true } @@ -6860,18 +6826,18 @@ func rewriteValueARM_OpARMMOVWstoreshiftLL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) - // result: (MOVWstore [int64(uint32(c)<<uint64(d))] ptr val mem) + // result: (MOVWstore [int32(uint32(c)<<uint64(d))] ptr val mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVWstore) - v.AuxInt = int64(uint32(c) << uint64(d)) + v.AuxInt = int32ToAuxInt(int32(uint32(c) << uint64(d))) v.AddArg3(ptr, val, mem) return true } @@ -6883,18 +6849,18 @@ func rewriteValueARM_OpARMMOVWstoreshiftRA(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) - // result: (MOVWstore [int64(int32(c)>>uint64(d))] ptr val mem) + // result: (MOVWstore [c>>uint64(d)] ptr val mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVWstore) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg3(ptr, val, mem) return true } @@ -6906,18 +6872,18 @@ func rewriteValueARM_OpARMMOVWstoreshiftRL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) - // result: (MOVWstore [int64(uint32(c)>>uint64(d))] ptr val mem) + // result: (MOVWstore [int32(uint32(c)>>uint64(d))] ptr val mem) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) ptr := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) val := v_2 mem := v_3 v.reset(OpARMMOVWstore) - v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg3(ptr, val, mem) return true } @@ -6936,12 +6902,12 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if !(int32(c) == -1) { continue } v.reset(OpARMRSBconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v.AddArg(x) return true } @@ -6951,11 +6917,11 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { // result: (MOVWconst [0]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 0 { continue } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } break @@ -6965,7 +6931,7 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 1 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 1 { continue } v.copyOf(x) @@ -6974,82 +6940,82 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { break } // match: (MUL x (MOVWconst [c])) - // cond: isPowerOfTwo(c) - // result: (SLLconst [log2(c)] x) + // cond: isPowerOfTwo32(c) + // result: (SLLconst [int32(log32(c))] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt32(v_1.AuxInt) + if !(isPowerOfTwo32(c)) { continue } v.reset(OpARMSLLconst) - v.AuxInt = log2(c) + v.AuxInt = int32ToAuxInt(int32(log32(c))) v.AddArg(x) return true } break } // match: (MUL x (MOVWconst [c])) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (ADDshiftLL x x [log2(c-1)]) + // cond: isPowerOfTwo32(c-1) && c >= 3 + // result: (ADDshiftLL x x [int32(log32(c-1))]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + c := auxIntToInt32(v_1.AuxInt) + if !(isPowerOfTwo32(c-1) && c >= 3) { continue } v.reset(OpARMADDshiftLL) - v.AuxInt = log2(c - 1) + v.AuxInt = int32ToAuxInt(int32(log32(c - 1))) v.AddArg2(x, x) return true } break } // match: (MUL x (MOVWconst [c])) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (RSBshiftLL x x [log2(c+1)]) + // cond: isPowerOfTwo32(c+1) && c >= 7 + // result: (RSBshiftLL x x [int32(log32(c+1))]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + c := auxIntToInt32(v_1.AuxInt) + if !(isPowerOfTwo32(c+1) && c >= 7) { continue } v.reset(OpARMRSBshiftLL) - v.AuxInt = log2(c + 1) + v.AuxInt = int32ToAuxInt(int32(log32(c + 1))) v.AddArg2(x, x) return true } break } // match: (MUL x (MOVWconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) + // cond: c%3 == 0 && isPowerOfTwo32(c/3) + // result: (SLLconst [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + c := auxIntToInt32(v_1.AuxInt) + if !(c%3 == 0 && isPowerOfTwo32(c/3)) { continue } v.reset(OpARMSLLconst) - v.AuxInt = log2(c / 3) + v.AuxInt = int32ToAuxInt(int32(log32(c / 3))) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -7057,22 +7023,22 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { break } // match: (MUL x (MOVWconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) + // cond: c%5 == 0 && isPowerOfTwo32(c/5) + // result: (SLLconst [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + c := auxIntToInt32(v_1.AuxInt) + if !(c%5 == 0 && isPowerOfTwo32(c/5)) { continue } v.reset(OpARMSLLconst) - v.AuxInt = log2(c / 5) + v.AuxInt = int32ToAuxInt(int32(log32(c / 5))) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int32ToAuxInt(2) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -7080,22 +7046,22 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { break } // match: (MUL x (MOVWconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (SLLconst [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) + // cond: c%7 == 0 && isPowerOfTwo32(c/7) + // result: (SLLconst [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + c := auxIntToInt32(v_1.AuxInt) + if !(c%7 == 0 && isPowerOfTwo32(c/7)) { continue } v.reset(OpARMSLLconst) - v.AuxInt = log2(c / 7) + v.AuxInt = int32ToAuxInt(int32(log32(c / 7))) v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int32ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -7103,22 +7069,22 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { break } // match: (MUL x (MOVWconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) + // cond: c%9 == 0 && isPowerOfTwo32(c/9) + // result: (SLLconst [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + c := auxIntToInt32(v_1.AuxInt) + if !(c%9 == 0 && isPowerOfTwo32(c/9)) { continue } v.reset(OpARMSLLconst) - v.AuxInt = log2(c / 9) + v.AuxInt = int32ToAuxInt(int32(log32(c / 9))) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int32ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -7126,19 +7092,19 @@ func rewriteValueARM_OpARMMUL(v *Value) bool { break } // match: (MUL (MOVWconst [c]) (MOVWconst [d])) - // result: (MOVWconst [int64(int32(c*d))]) + // result: (MOVWconst [c*d]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpARMMOVWconst { continue } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) if v_1.Op != OpARMMOVWconst { continue } - d := v_1.AuxInt + d := auxIntToInt32(v_1.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(c * d)) + v.AuxInt = int32ToAuxInt(c * d) return true } break @@ -7151,16 +7117,16 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (MULA x (MOVWconst [c]) a) - // cond: int32(c) == -1 + // cond: c == -1 // result: (SUB a x) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(int32(c) == -1) { + if !(c == -1) { break } v.reset(OpARMSUB) @@ -7170,7 +7136,7 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { // match: (MULA _ (MOVWconst [0]) a) // result: a for { - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 0 { break } a := v_2 @@ -7181,7 +7147,7 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { // result: (ADD x a) for { x := v_0 - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 1 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 1 { break } a := v_2 @@ -7190,168 +7156,168 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { return true } // match: (MULA x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c) - // result: (ADD (SLLconst <x.Type> [log2(c)] x) a) + // cond: isPowerOfTwo32(c) + // result: (ADD (SLLconst <x.Type> [int32(log32(c))] x) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int32ToAuxInt(int32(log32(c))) v0.AddArg(x) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (ADD (ADDshiftLL <x.Type> x x [log2(c-1)]) a) + // cond: isPowerOfTwo32(c-1) && c >= 3 + // result: (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo32(c-1) && c >= 3) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c - 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (ADD (RSBshiftLL <x.Type> x x [log2(c+1)]) a) + // cond: isPowerOfTwo32(c+1) && c >= 7 + // result: (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo32(c+1) && c >= 7) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c + 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) + // cond: c%3 == 0 && isPowerOfTwo32(c/3) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo32(c/3)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 3) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 3))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) + // cond: c%5 == 0 && isPowerOfTwo32(c/5) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo32(c/5)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 5))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) + // cond: c%7 == 0 && isPowerOfTwo32(c/7) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo32(c/7)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 7) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 7))) v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA x (MOVWconst [c]) a) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) + // cond: c%9 == 0 && isPowerOfTwo32(c/9) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo32(c/9)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 9))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: int32(c) == -1 + // cond: c == -1 // result: (SUB a x) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(int32(c) == -1) { + if !(c == -1) { break } v.reset(OpARMSUB) @@ -7361,7 +7327,7 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { // match: (MULA (MOVWconst [0]) _ a) // result: a for { - if v_0.Op != OpARMMOVWconst || v_0.AuxInt != 0 { + if v_0.Op != OpARMMOVWconst || auxIntToInt32(v_0.AuxInt) != 0 { break } a := v_2 @@ -7371,7 +7337,7 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { // match: (MULA (MOVWconst [1]) x a) // result: (ADD x a) for { - if v_0.Op != OpARMMOVWconst || v_0.AuxInt != 1 { + if v_0.Op != OpARMMOVWconst || auxIntToInt32(v_0.AuxInt) != 1 { break } x := v_1 @@ -7381,171 +7347,171 @@ func rewriteValueARM_OpARMMULA(v *Value) bool { return true } // match: (MULA (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c) - // result: (ADD (SLLconst <x.Type> [log2(c)] x) a) + // cond: isPowerOfTwo32(c) + // result: (ADD (SLLconst <x.Type> [int32(log32(c))] x) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int32ToAuxInt(int32(log32(c))) v0.AddArg(x) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (ADD (ADDshiftLL <x.Type> x x [log2(c-1)]) a) + // cond: isPowerOfTwo32(c-1) && c >= 3 + // result: (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo32(c-1) && c >= 3) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c - 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (ADD (RSBshiftLL <x.Type> x x [log2(c+1)]) a) + // cond: isPowerOfTwo32(c+1) && c >= 7 + // result: (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo32(c+1) && c >= 7) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c + 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) + // cond: c%3 == 0 && isPowerOfTwo32(c/3) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo32(c/3)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 3) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 3))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) + // cond: c%5 == 0 && isPowerOfTwo32(c/5) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo32(c/5)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 5))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) + // cond: c%7 == 0 && isPowerOfTwo32(c/7) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo32(c/7)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 7) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 7))) v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) x a) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) + // cond: c%9 == 0 && isPowerOfTwo32(c/9) + // result: (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo32(c/9)) { break } v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 9))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULA (MOVWconst [c]) (MOVWconst [d]) a) - // result: (ADDconst [int64(int32(c*d))] a) + // result: (ADDconst [c*d] a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) if v_1.Op != OpARMMOVWconst { break } - d := v_1.AuxInt + d := auxIntToInt32(v_1.AuxInt) a := v_2 v.reset(OpARMADDconst) - v.AuxInt = int64(int32(c * d)) + v.AuxInt = int32ToAuxInt(c * d) v.AddArg(a) return true } @@ -7605,16 +7571,16 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { v_0 := v.Args[0] b := v.Block // match: (MULS x (MOVWconst [c]) a) - // cond: int32(c) == -1 + // cond: c == -1 // result: (ADD a x) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(int32(c) == -1) { + if !(c == -1) { break } v.reset(OpARMADD) @@ -7624,7 +7590,7 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { // match: (MULS _ (MOVWconst [0]) a) // result: a for { - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 0 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 0 { break } a := v_2 @@ -7635,7 +7601,7 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { // result: (RSB x a) for { x := v_0 - if v_1.Op != OpARMMOVWconst || v_1.AuxInt != 1 { + if v_1.Op != OpARMMOVWconst || auxIntToInt32(v_1.AuxInt) != 1 { break } a := v_2 @@ -7644,168 +7610,168 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { return true } // match: (MULS x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c) - // result: (RSB (SLLconst <x.Type> [log2(c)] x) a) + // cond: isPowerOfTwo32(c) + // result: (RSB (SLLconst <x.Type> [int32(log32(c))] x) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int32ToAuxInt(int32(log32(c))) v0.AddArg(x) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a) + // cond: isPowerOfTwo32(c-1) && c >= 3 + // result: (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo32(c-1) && c >= 3) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c - 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a) + // cond: isPowerOfTwo32(c+1) && c >= 7 + // result: (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo32(c+1) && c >= 7) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c + 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) + // cond: c%3 == 0 && isPowerOfTwo32(c/3) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo32(c/3)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 3) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 3))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) + // cond: c%5 == 0 && isPowerOfTwo32(c/5) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo32(c/5)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 5))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) + // cond: c%7 == 0 && isPowerOfTwo32(c/7) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo32(c/7)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 7) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 7))) v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS x (MOVWconst [c]) a) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) + // cond: c%9 == 0 && isPowerOfTwo32(c/9) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) for { x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) a := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo32(c/9)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 9))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: int32(c) == -1 + // cond: c == -1 // result: (ADD a x) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(int32(c) == -1) { + if !(c == -1) { break } v.reset(OpARMADD) @@ -7815,7 +7781,7 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { // match: (MULS (MOVWconst [0]) _ a) // result: a for { - if v_0.Op != OpARMMOVWconst || v_0.AuxInt != 0 { + if v_0.Op != OpARMMOVWconst || auxIntToInt32(v_0.AuxInt) != 0 { break } a := v_2 @@ -7825,7 +7791,7 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { // match: (MULS (MOVWconst [1]) x a) // result: (RSB x a) for { - if v_0.Op != OpARMMOVWconst || v_0.AuxInt != 1 { + if v_0.Op != OpARMMOVWconst || auxIntToInt32(v_0.AuxInt) != 1 { break } x := v_1 @@ -7835,171 +7801,171 @@ func rewriteValueARM_OpARMMULS(v *Value) bool { return true } // match: (MULS (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c) - // result: (RSB (SLLconst <x.Type> [log2(c)] x) a) + // cond: isPowerOfTwo32(c) + // result: (RSB (SLLconst <x.Type> [int32(log32(c))] x) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int32ToAuxInt(int32(log32(c))) v0.AddArg(x) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (RSB (ADDshiftLL <x.Type> x x [log2(c-1)]) a) + // cond: isPowerOfTwo32(c-1) && c >= 3 + // result: (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo32(c-1) && c >= 3) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c - 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (RSB (RSBshiftLL <x.Type> x x [log2(c+1)]) a) + // cond: isPowerOfTwo32(c+1) && c >= 7 + // result: (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo32(c+1) && c >= 7) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int32ToAuxInt(int32(log32(c + 1))) v0.AddArg2(x, x) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) a) + // cond: c%3 == 0 && isPowerOfTwo32(c/3) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo32(c/3)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 3) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 3))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) a) + // cond: c%5 == 0 && isPowerOfTwo32(c/5) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo32(c/5)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 5))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/7)] (RSBshiftLL <x.Type> x x [3])) a) + // cond: c%7 == 0 && isPowerOfTwo32(c/7) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo32(c/7)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 7) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 7))) v1 := b.NewValue0(v.Pos, OpARMRSBshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) x a) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (RSB (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a) + // cond: c%9 == 0 && isPowerOfTwo32(c/9) + // result: (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 a := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo32(c/9)) { break } v.reset(OpARMRSB) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int32ToAuxInt(int32(log32(c / 9))) v1 := b.NewValue0(v.Pos, OpARMADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int32ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg2(v0, a) return true } // match: (MULS (MOVWconst [c]) (MOVWconst [d]) a) - // result: (SUBconst [int64(int32(c*d))] a) + // result: (SUBconst [c*d] a) for { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) if v_1.Op != OpARMMOVWconst { break } - d := v_1.AuxInt + d := auxIntToInt32(v_1.AuxInt) a := v_2 v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(c * d)) + v.AuxInt = int32ToAuxInt(c * d) v.AddArg(a) return true } @@ -8013,9 +7979,9 @@ func rewriteValueARM_OpARMMVN(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = ^c + v.AuxInt = int32ToAuxInt(^c) return true } // match: (MVN (SLLconst [c] x)) @@ -8024,10 +7990,10 @@ func rewriteValueARM_OpARMMVN(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMMVNshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8037,10 +8003,10 @@ func rewriteValueARM_OpARMMVN(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMMVNshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8050,10 +8016,10 @@ func rewriteValueARM_OpARMMVN(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMMVNshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8098,15 +8064,15 @@ func rewriteValueARM_OpARMMVN(v *Value) bool { func rewriteValueARM_OpARMMVNshiftLL(v *Value) bool { v_0 := v.Args[0] // match: (MVNshiftLL (MOVWconst [c]) [d]) - // result: (MOVWconst [^int64(uint32(c)<<uint64(d))]) + // result: (MOVWconst [^(c<<uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = ^int64(uint32(c) << uint64(d)) + v.AuxInt = int32ToAuxInt(^(c << uint64(d))) return true } return false @@ -8121,9 +8087,9 @@ func rewriteValueARM_OpARMMVNshiftLLreg(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMMVNshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8132,15 +8098,15 @@ func rewriteValueARM_OpARMMVNshiftLLreg(v *Value) bool { func rewriteValueARM_OpARMMVNshiftRA(v *Value) bool { v_0 := v.Args[0] // match: (MVNshiftRA (MOVWconst [c]) [d]) - // result: (MOVWconst [^int64(int32(c)>>uint64(d))]) + // result: (MOVWconst [int32(c)>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = ^int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(int32(c) >> uint64(d)) return true } return false @@ -8155,9 +8121,9 @@ func rewriteValueARM_OpARMMVNshiftRAreg(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMMVNshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8166,15 +8132,15 @@ func rewriteValueARM_OpARMMVNshiftRAreg(v *Value) bool { func rewriteValueARM_OpARMMVNshiftRL(v *Value) bool { v_0 := v.Args[0] // match: (MVNshiftRL (MOVWconst [c]) [d]) - // result: (MOVWconst [^int64(uint32(c)>>uint64(d))]) + // result: (MOVWconst [^int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = ^int64(uint32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(^int32(uint32(c) >> uint64(d))) return true } return false @@ -8189,9 +8155,9 @@ func rewriteValueARM_OpARMMVNshiftRLreg(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMMVNshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8314,9 +8280,9 @@ func rewriteValueARM_OpARMOR(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8330,10 +8296,10 @@ func rewriteValueARM_OpARMOR(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMORshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8347,10 +8313,10 @@ func rewriteValueARM_OpARMOR(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMORshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8364,10 +8330,10 @@ func rewriteValueARM_OpARMOR(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMORshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8438,7 +8404,7 @@ func rewriteValueARM_OpARMORconst(v *Value) bool { // match: (ORconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -8449,37 +8415,37 @@ func rewriteValueARM_OpARMORconst(v *Value) bool { // cond: int32(c)==-1 // result: (MOVWconst [-1]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if !(int32(c) == -1) { break } v.reset(OpARMMOVWconst) - v.AuxInt = -1 + v.AuxInt = int32ToAuxInt(-1) return true } // match: (ORconst [c] (MOVWconst [d])) // result: (MOVWconst [c|d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = c | d + v.AuxInt = int32ToAuxInt(c | d) return true } // match: (ORconst [c] (ORconst [d] x)) // result: (ORconst [c|d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMORconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMORconst) - v.AuxInt = c | d + v.AuxInt = int32ToAuxInt(c | d) v.AddArg(x) return true } @@ -8493,39 +8459,39 @@ func rewriteValueARM_OpARMORshiftLL(v *Value) bool { // match: (ORshiftLL (MOVWconst [c]) x [d]) // result: (ORconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ORshiftLL x (MOVWconst [c]) [d]) - // result: (ORconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (ORconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMORconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } // match: ( ORshiftLL [c] (SRLconst x [32-c]) x) // result: (SRRconst [32-c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSRLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -8533,7 +8499,7 @@ func rewriteValueARM_OpARMORshiftLL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = 32 - c + v.AuxInt = int32ToAuxInt(32 - c) v.AddArg(x) return true } @@ -8555,11 +8521,11 @@ func rewriteValueARM_OpARMORshiftLL(v *Value) bool { // cond: objabi.GOARM>=6 // result: (REV16 x) for { - if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || v_0.AuxInt != 24 { + if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 { break } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpARMSLLconst || v_0_0.AuxInt != 16 { + if v_0_0.Op != OpARMSLLconst || auxIntToInt32(v_0_0.AuxInt) != 16 { break } x := v_0_0.Args[0] @@ -8574,13 +8540,13 @@ func rewriteValueARM_OpARMORshiftLL(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSLLconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -8600,11 +8566,11 @@ func rewriteValueARM_OpARMORshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -8618,9 +8584,9 @@ func rewriteValueARM_OpARMORshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMORshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8633,31 +8599,31 @@ func rewriteValueARM_OpARMORshiftRA(v *Value) bool { // match: (ORshiftRA (MOVWconst [c]) x [d]) // result: (ORconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ORshiftRA x (MOVWconst [c]) [d]) - // result: (ORconst x [int64(int32(c)>>uint64(d))]) + // result: (ORconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMORconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -8665,13 +8631,13 @@ func rewriteValueARM_OpARMORshiftRA(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSRAconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -8691,11 +8657,11 @@ func rewriteValueARM_OpARMORshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -8709,9 +8675,9 @@ func rewriteValueARM_OpARMORshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMORshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8724,39 +8690,39 @@ func rewriteValueARM_OpARMORshiftRL(v *Value) bool { // match: (ORshiftRL (MOVWconst [c]) x [d]) // result: (ORconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (ORshiftRL x (MOVWconst [c]) [d]) - // result: (ORconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (ORconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMORconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } // match: ( ORshiftRL [c] (SLLconst x [32-c]) x) // result: (SRRconst [ c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSLLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -8764,7 +8730,7 @@ func rewriteValueARM_OpARMORshiftRL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8772,13 +8738,13 @@ func rewriteValueARM_OpARMORshiftRL(v *Value) bool { // cond: c==d // result: y for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 y := v_1 if y.Op != OpARMSRLconst { break } - c := y.AuxInt + c := auxIntToInt32(y.AuxInt) if x != y.Args[0] || !(c == d) { break } @@ -8798,11 +8764,11 @@ func rewriteValueARM_OpARMORshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -8816,9 +8782,9 @@ func rewriteValueARM_OpARMORshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMORshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8833,10 +8799,10 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8847,9 +8813,9 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -8860,10 +8826,10 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMRSBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8873,11 +8839,11 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMSUBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8888,10 +8854,10 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMRSBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8901,11 +8867,11 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMSUBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8916,10 +8882,10 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMRSBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -8929,11 +8895,11 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMSUBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9023,7 +8989,7 @@ func rewriteValueARM_OpARMRSB(v *Value) bool { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (RSB (MUL x y) a) @@ -9052,31 +9018,31 @@ func rewriteValueARM_OpARMRSBSshiftLL(v *Value) bool { // match: (RSBSshiftLL (MOVWconst [c]) x [d]) // result: (SUBSconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBSshiftLL x (MOVWconst [c]) [d]) - // result: (RSBSconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (RSBSconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBSconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -9093,11 +9059,11 @@ func rewriteValueARM_OpARMRSBSshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9111,9 +9077,9 @@ func rewriteValueARM_OpARMRSBSshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9126,31 +9092,31 @@ func rewriteValueARM_OpARMRSBSshiftRA(v *Value) bool { // match: (RSBSshiftRA (MOVWconst [c]) x [d]) // result: (SUBSconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBSshiftRA x (MOVWconst [c]) [d]) - // result: (RSBSconst x [int64(int32(c)>>uint64(d))]) + // result: (RSBSconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBSconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -9167,11 +9133,11 @@ func rewriteValueARM_OpARMRSBSshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9185,9 +9151,9 @@ func rewriteValueARM_OpARMRSBSshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9200,31 +9166,31 @@ func rewriteValueARM_OpARMRSBSshiftRL(v *Value) bool { // match: (RSBSshiftRL (MOVWconst [c]) x [d]) // result: (SUBSconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBSshiftRL x (MOVWconst [c]) [d]) - // result: (RSBSconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (RSBSconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBSconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -9241,11 +9207,11 @@ func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9259,9 +9225,9 @@ func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9270,56 +9236,56 @@ func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value) bool { func rewriteValueARM_OpARMRSBconst(v *Value) bool { v_0 := v.Args[0] // match: (RSBconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(c-d))]) + // result: (MOVWconst [c-d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) return true } // match: (RSBconst [c] (RSBconst [d] x)) - // result: (ADDconst [int64(int32(c-d))] x) + // result: (ADDconst [c-d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMRSBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMADDconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg(x) return true } // match: (RSBconst [c] (ADDconst [d] x)) - // result: (RSBconst [int64(int32(c-d))] x) + // result: (RSBconst [c-d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg(x) return true } // match: (RSBconst [c] (SUBconst [d] x)) - // result: (RSBconst [int64(int32(c+d))] x) + // result: (RSBconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg(x) return true } @@ -9332,31 +9298,31 @@ func rewriteValueARM_OpARMRSBshiftLL(v *Value) bool { // match: (RSBshiftLL (MOVWconst [c]) x [d]) // result: (SUBconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBshiftLL x (MOVWconst [c]) [d]) - // result: (RSBconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (RSBconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -9364,17 +9330,17 @@ func rewriteValueARM_OpARMRSBshiftLL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -9390,11 +9356,11 @@ func rewriteValueARM_OpARMRSBshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9408,9 +9374,9 @@ func rewriteValueARM_OpARMRSBshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9423,31 +9389,31 @@ func rewriteValueARM_OpARMRSBshiftRA(v *Value) bool { // match: (RSBshiftRA (MOVWconst [c]) x [d]) // result: (SUBconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBshiftRA x (MOVWconst [c]) [d]) - // result: (RSBconst x [int64(int32(c)>>uint64(d))]) + // result: (RSBconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -9455,17 +9421,17 @@ func rewriteValueARM_OpARMRSBshiftRA(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -9481,11 +9447,11 @@ func rewriteValueARM_OpARMRSBshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9499,9 +9465,9 @@ func rewriteValueARM_OpARMRSBshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9514,31 +9480,31 @@ func rewriteValueARM_OpARMRSBshiftRL(v *Value) bool { // match: (RSBshiftRL (MOVWconst [c]) x [d]) // result: (SUBconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (RSBshiftRL x (MOVWconst [c]) [d]) - // result: (RSBconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (RSBconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -9546,17 +9512,17 @@ func rewriteValueARM_OpARMRSBshiftRL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -9572,11 +9538,11 @@ func rewriteValueARM_OpARMRSBshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -9590,9 +9556,9 @@ func rewriteValueARM_OpARMRSBshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMRSBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -9602,32 +9568,32 @@ func rewriteValueARM_OpARMRSCconst(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (RSCconst [c] (ADDconst [d] x) flags) - // result: (RSCconst [int64(int32(c-d))] x flags) + // result: (RSCconst [c-d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMRSCconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg2(x, flags) return true } // match: (RSCconst [c] (SUBconst [d] x) flags) - // result: (RSCconst [int64(int32(c+d))] x flags) + // result: (RSCconst [c+d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMRSCconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg2(x, flags) return true } @@ -9641,33 +9607,33 @@ func rewriteValueARM_OpARMRSCshiftLL(v *Value) bool { // match: (RSCshiftLL (MOVWconst [c]) x [d] flags) // result: (SBCconst [c] (SLLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (RSCshiftLL x (MOVWconst [c]) [d] flags) - // result: (RSCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) + // result: (RSCconst x [c<<uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg2(x, flags) return true } @@ -9685,12 +9651,12 @@ func rewriteValueARM_OpARMRSCshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -9704,10 +9670,10 @@ func rewriteValueARM_OpARMRSCshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMRSCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9721,33 +9687,33 @@ func rewriteValueARM_OpARMRSCshiftRA(v *Value) bool { // match: (RSCshiftRA (MOVWconst [c]) x [d] flags) // result: (SBCconst [c] (SRAconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (RSCshiftRA x (MOVWconst [c]) [d] flags) - // result: (RSCconst x [int64(int32(c)>>uint64(d))] flags) + // result: (RSCconst x [c>>uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg2(x, flags) return true } @@ -9765,12 +9731,12 @@ func rewriteValueARM_OpARMRSCshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -9784,10 +9750,10 @@ func rewriteValueARM_OpARMRSCshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMRSCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9801,33 +9767,33 @@ func rewriteValueARM_OpARMRSCshiftRL(v *Value) bool { // match: (RSCshiftRL (MOVWconst [c]) x [d] flags) // result: (SBCconst [c] (SRLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (RSCshiftRL x (MOVWconst [c]) [d] flags) - // result: (RSCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) + // result: (RSCconst x [int32(uint32(c)>>uint64(d))] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg2(x, flags) return true } @@ -9845,12 +9811,12 @@ func rewriteValueARM_OpARMRSCshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -9864,10 +9830,10 @@ func rewriteValueARM_OpARMRSCshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMRSCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9883,11 +9849,11 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, flags) return true } @@ -9898,10 +9864,10 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, flags) return true } @@ -9912,11 +9878,11 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMSBCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9926,12 +9892,12 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 flags := v_2 v.reset(OpARMRSCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9942,11 +9908,11 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMSBCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9956,12 +9922,12 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 flags := v_2 v.reset(OpARMRSCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9972,11 +9938,11 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] flags := v_2 v.reset(OpARMSBCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -9986,12 +9952,12 @@ func rewriteValueARM_OpARMSBC(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 flags := v_2 v.reset(OpARMRSCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -10085,32 +10051,32 @@ func rewriteValueARM_OpARMSBCconst(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (SBCconst [c] (ADDconst [d] x) flags) - // result: (SBCconst [int64(int32(c-d))] x flags) + // result: (SBCconst [c-d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMSBCconst) - v.AuxInt = int64(int32(c - d)) + v.AuxInt = int32ToAuxInt(c - d) v.AddArg2(x, flags) return true } // match: (SBCconst [c] (SUBconst [d] x) flags) - // result: (SBCconst [int64(int32(c+d))] x flags) + // result: (SBCconst [c+d] x flags) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] flags := v_1 v.reset(OpARMSBCconst) - v.AuxInt = int64(int32(c + d)) + v.AuxInt = int32ToAuxInt(c + d) v.AddArg2(x, flags) return true } @@ -10124,33 +10090,33 @@ func rewriteValueARM_OpARMSBCshiftLL(v *Value) bool { // match: (SBCshiftLL (MOVWconst [c]) x [d] flags) // result: (RSCconst [c] (SLLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (SBCshiftLL x (MOVWconst [c]) [d] flags) - // result: (SBCconst x [int64(int32(uint32(c)<<uint64(d)))] flags) + // result: (SBCconst x [c<<uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg2(x, flags) return true } @@ -10168,12 +10134,12 @@ func rewriteValueARM_OpARMSBCshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -10187,10 +10153,10 @@ func rewriteValueARM_OpARMSBCshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMSBCshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -10204,33 +10170,33 @@ func rewriteValueARM_OpARMSBCshiftRA(v *Value) bool { // match: (SBCshiftRA (MOVWconst [c]) x [d] flags) // result: (RSCconst [c] (SRAconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (SBCshiftRA x (MOVWconst [c]) [d] flags) - // result: (SBCconst x [int64(int32(c)>>uint64(d))] flags) + // result: (SBCconst x [c>>uint64(d)] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg2(x, flags) return true } @@ -10248,12 +10214,12 @@ func rewriteValueARM_OpARMSBCshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -10267,10 +10233,10 @@ func rewriteValueARM_OpARMSBCshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMSBCshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -10284,33 +10250,33 @@ func rewriteValueARM_OpARMSBCshiftRL(v *Value) bool { // match: (SBCshiftRL (MOVWconst [c]) x [d] flags) // result: (RSCconst [c] (SRLconst <x.Type> x [d]) flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 flags := v_2 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg2(v0, flags) return true } // match: (SBCshiftRL x (MOVWconst [c]) [d] flags) - // result: (SBCconst x [int64(int32(uint32(c)>>uint64(d)))] flags) + // result: (SBCconst x [int32(uint32(c)>>uint64(d))] flags) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) flags := v_2 v.reset(OpARMSBCconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg2(x, flags) return true } @@ -10328,12 +10294,12 @@ func rewriteValueARM_OpARMSBCshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 flags := v_3 v.reset(OpARMRSCconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg2(v0, flags) @@ -10347,10 +10313,10 @@ func rewriteValueARM_OpARMSBCshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) flags := v_3 v.reset(OpARMSBCshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg3(x, y, flags) return true } @@ -10366,9 +10332,9 @@ func rewriteValueARM_OpARMSLL(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSLLconst) - v.AuxInt = c & 31 + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -10377,15 +10343,15 @@ func rewriteValueARM_OpARMSLL(v *Value) bool { func rewriteValueARM_OpARMSLLconst(v *Value) bool { v_0 := v.Args[0] // match: (SLLconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(uint32(d)<<uint64(c)))]) + // result: (MOVWconst [d<<uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(uint32(d) << uint64(c))) + v.AuxInt = int32ToAuxInt(d << uint64(c)) return true } return false @@ -10400,9 +10366,9 @@ func rewriteValueARM_OpARMSRA(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSRAconst) - v.AuxInt = c & 31 + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -10451,32 +10417,32 @@ func rewriteValueARM_OpARMSRAcond(v *Value) bool { func rewriteValueARM_OpARMSRAconst(v *Value) bool { v_0 := v.Args[0] // match: (SRAconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(d)>>uint64(c))]) + // result: (MOVWconst [d>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(d) >> uint64(c)) + v.AuxInt = int32ToAuxInt(d >> uint64(c)) return true } // match: (SRAconst (SLLconst x [c]) [d]) // cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 // result: (BFX [(d-c)|(32-d)<<8] x) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) { break } v.reset(OpARMBFX) - v.AuxInt = (d - c) | (32-d)<<8 + v.AuxInt = int32ToAuxInt((d - c) | (32-d)<<8) v.AddArg(x) return true } @@ -10492,9 +10458,9 @@ func rewriteValueARM_OpARMSRL(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSRLconst) - v.AuxInt = c & 31 + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -10503,32 +10469,32 @@ func rewriteValueARM_OpARMSRL(v *Value) bool { func rewriteValueARM_OpARMSRLconst(v *Value) bool { v_0 := v.Args[0] // match: (SRLconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(uint32(d)>>uint64(c)))]) + // result: (MOVWconst [int32(uint32(d)>>uint64(c))]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(uint32(d) >> uint64(c))) + v.AuxInt = int32ToAuxInt(int32(uint32(d) >> uint64(c))) return true } // match: (SRLconst (SLLconst x [c]) [d]) // cond: objabi.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 // result: (BFXU [(d-c)|(32-d)<<8] x) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] if !(objabi.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) { break } v.reset(OpARMBFXU) - v.AuxInt = (d - c) | (32-d)<<8 + v.AuxInt = int32ToAuxInt((d - c) | (32-d)<<8) v.AddArg(x) return true } @@ -10543,10 +10509,10 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -10557,9 +10523,9 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -10570,10 +10536,10 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10583,11 +10549,11 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10598,10 +10564,10 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10611,11 +10577,11 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10626,10 +10592,10 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10639,11 +10605,11 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10733,7 +10699,7 @@ func rewriteValueARM_OpARMSUB(v *Value) bool { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (SUB a (MUL x y)) @@ -10843,9 +10809,9 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -10856,10 +10822,10 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10869,11 +10835,11 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_0.Op != OpARMSLLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10884,10 +10850,10 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10897,11 +10863,11 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_0.Op != OpARMSRLconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10912,10 +10878,10 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMSUBSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -10925,11 +10891,11 @@ func rewriteValueARM_OpARMSUBS(v *Value) bool { if v_0.Op != OpARMSRAconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) y := v_0.Args[0] x := v_1 v.reset(OpARMRSBSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11020,31 +10986,31 @@ func rewriteValueARM_OpARMSUBSshiftLL(v *Value) bool { // match: (SUBSshiftLL (MOVWconst [c]) x [d]) // result: (RSBSconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBSshiftLL x (MOVWconst [c]) [d]) - // result: (SUBSconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (SUBSconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBSconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -11061,11 +11027,11 @@ func rewriteValueARM_OpARMSUBSshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11079,9 +11045,9 @@ func rewriteValueARM_OpARMSUBSshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBSshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11094,31 +11060,31 @@ func rewriteValueARM_OpARMSUBSshiftRA(v *Value) bool { // match: (SUBSshiftRA (MOVWconst [c]) x [d]) // result: (RSBSconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBSshiftRA x (MOVWconst [c]) [d]) - // result: (SUBSconst x [int64(int32(c)>>uint64(d))]) + // result: (SUBSconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBSconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -11135,11 +11101,11 @@ func rewriteValueARM_OpARMSUBSshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11153,9 +11119,9 @@ func rewriteValueARM_OpARMSUBSshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBSshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11168,31 +11134,31 @@ func rewriteValueARM_OpARMSUBSshiftRL(v *Value) bool { // match: (SUBSshiftRL (MOVWconst [c]) x [d]) // result: (RSBSconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBSshiftRL x (MOVWconst [c]) [d]) - // result: (SUBSconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (SUBSconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBSconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -11209,11 +11175,11 @@ func rewriteValueARM_OpARMSUBSshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBSconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11227,9 +11193,9 @@ func rewriteValueARM_OpARMSUBSshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBSshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11240,23 +11206,23 @@ func rewriteValueARM_OpARMSUBconst(v *Value) bool { // match: (SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) // result: (MOVWaddr [off2-off1] {sym} ptr) for { - off1 := v.AuxInt + off1 := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWaddr { break } - off2 := v_0.AuxInt - sym := v_0.Aux + off2 := auxIntToInt32(v_0.AuxInt) + sym := auxToSym(v_0.Aux) ptr := v_0.Args[0] v.reset(OpARMMOVWaddr) - v.AuxInt = off2 - off1 - v.Aux = sym + v.AuxInt = int32ToAuxInt(off2 - off1) + v.Aux = symToAux(sym) v.AddArg(ptr) return true } // match: (SUBconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -11265,83 +11231,83 @@ func rewriteValueARM_OpARMSUBconst(v *Value) bool { } // match: (SUBconst [c] x) // cond: !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) - // result: (ADDconst [int64(int32(-c))] x) + // result: (ADDconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(!isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c))) { break } v.reset(OpARMADDconst) - v.AuxInt = int64(int32(-c)) + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } // match: (SUBconst [c] x) // cond: objabi.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff - // result: (ANDconst [int64(int32(-c))] x) + // result: (ADDconst [-c] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) x := v_0 if !(objabi.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) { break } - v.reset(OpARMANDconst) - v.AuxInt = int64(int32(-c)) + v.reset(OpARMADDconst) + v.AuxInt = int32ToAuxInt(-c) v.AddArg(x) return true } // match: (SUBconst [c] (MOVWconst [d])) - // result: (MOVWconst [int64(int32(d-c))]) + // result: (MOVWconst [d-c]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(d - c)) + v.AuxInt = int32ToAuxInt(d - c) return true } // match: (SUBconst [c] (SUBconst [d] x)) - // result: (ADDconst [int64(int32(-c-d))] x) + // result: (ADDconst [-c-d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMSUBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMADDconst) - v.AuxInt = int64(int32(-c - d)) + v.AuxInt = int32ToAuxInt(-c - d) v.AddArg(x) return true } // match: (SUBconst [c] (ADDconst [d] x)) - // result: (ADDconst [int64(int32(-c+d))] x) + // result: (ADDconst [-c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMADDconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMADDconst) - v.AuxInt = int64(int32(-c + d)) + v.AuxInt = int32ToAuxInt(-c + d) v.AddArg(x) return true } // match: (SUBconst [c] (RSBconst [d] x)) - // result: (RSBconst [int64(int32(-c+d))] x) + // result: (RSBconst [-c+d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMRSBconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMRSBconst) - v.AuxInt = int64(int32(-c + d)) + v.AuxInt = int32ToAuxInt(-c + d) v.AddArg(x) return true } @@ -11354,31 +11320,31 @@ func rewriteValueARM_OpARMSUBshiftLL(v *Value) bool { // match: (SUBshiftLL (MOVWconst [c]) x [d]) // result: (RSBconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBshiftLL x (MOVWconst [c]) [d]) - // result: (SUBconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (SUBconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -11386,17 +11352,17 @@ func rewriteValueARM_OpARMSUBshiftLL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -11412,11 +11378,11 @@ func rewriteValueARM_OpARMSUBshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11430,9 +11396,9 @@ func rewriteValueARM_OpARMSUBshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11445,31 +11411,31 @@ func rewriteValueARM_OpARMSUBshiftRA(v *Value) bool { // match: (SUBshiftRA (MOVWconst [c]) x [d]) // result: (RSBconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBshiftRA x (MOVWconst [c]) [d]) - // result: (SUBconst x [int64(int32(c)>>uint64(d))]) + // result: (SUBconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -11477,17 +11443,17 @@ func rewriteValueARM_OpARMSUBshiftRA(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -11503,11 +11469,11 @@ func rewriteValueARM_OpARMSUBshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11521,9 +11487,9 @@ func rewriteValueARM_OpARMSUBshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11536,31 +11502,31 @@ func rewriteValueARM_OpARMSUBshiftRL(v *Value) bool { // match: (SUBshiftRL (MOVWconst [c]) x [d]) // result: (RSBconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (SUBshiftRL x (MOVWconst [c]) [d]) - // result: (SUBconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (SUBconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSUBconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -11568,17 +11534,17 @@ func rewriteValueARM_OpARMSUBshiftRL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -11594,11 +11560,11 @@ func rewriteValueARM_OpARMSUBshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMRSBconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11612,9 +11578,9 @@ func rewriteValueARM_OpARMSUBshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMSUBshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11631,9 +11597,9 @@ func rewriteValueARM_OpARMTEQ(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -11647,10 +11613,10 @@ func rewriteValueARM_OpARMTEQ(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTEQshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11664,10 +11630,10 @@ func rewriteValueARM_OpARMTEQ(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTEQshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11681,10 +11647,10 @@ func rewriteValueARM_OpARMTEQ(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTEQshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11763,31 +11729,31 @@ func rewriteValueARM_OpARMTEQshiftLL(v *Value) bool { // match: (TEQshiftLL (MOVWconst [c]) x [d]) // result: (TEQconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TEQshiftLL x (MOVWconst [c]) [d]) - // result: (TEQconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (TEQconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTEQconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -11804,11 +11770,11 @@ func rewriteValueARM_OpARMTEQshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11822,9 +11788,9 @@ func rewriteValueARM_OpARMTEQshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTEQshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11837,31 +11803,31 @@ func rewriteValueARM_OpARMTEQshiftRA(v *Value) bool { // match: (TEQshiftRA (MOVWconst [c]) x [d]) // result: (TEQconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TEQshiftRA x (MOVWconst [c]) [d]) - // result: (TEQconst x [int64(int32(c)>>uint64(d))]) + // result: (TEQconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTEQconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -11878,11 +11844,11 @@ func rewriteValueARM_OpARMTEQshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11896,9 +11862,9 @@ func rewriteValueARM_OpARMTEQshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTEQshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11911,31 +11877,31 @@ func rewriteValueARM_OpARMTEQshiftRL(v *Value) bool { // match: (TEQshiftRL (MOVWconst [c]) x [d]) // result: (TEQconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TEQshiftRL x (MOVWconst [c]) [d]) - // result: (TEQconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (TEQconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTEQconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -11952,11 +11918,11 @@ func rewriteValueARM_OpARMTEQshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTEQconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -11970,9 +11936,9 @@ func rewriteValueARM_OpARMTEQshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTEQshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -11989,9 +11955,9 @@ func rewriteValueARM_OpARMTST(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -12005,10 +11971,10 @@ func rewriteValueARM_OpARMTST(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTSTshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12022,10 +11988,10 @@ func rewriteValueARM_OpARMTST(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTSTshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12039,10 +12005,10 @@ func rewriteValueARM_OpARMTST(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMTSTshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12121,31 +12087,31 @@ func rewriteValueARM_OpARMTSTshiftLL(v *Value) bool { // match: (TSTshiftLL (MOVWconst [c]) x [d]) // result: (TSTconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TSTshiftLL x (MOVWconst [c]) [d]) - // result: (TSTconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (TSTconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTSTconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } @@ -12162,11 +12128,11 @@ func rewriteValueARM_OpARMTSTshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12180,9 +12146,9 @@ func rewriteValueARM_OpARMTSTshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTSTshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12195,31 +12161,31 @@ func rewriteValueARM_OpARMTSTshiftRA(v *Value) bool { // match: (TSTshiftRA (MOVWconst [c]) x [d]) // result: (TSTconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TSTshiftRA x (MOVWconst [c]) [d]) - // result: (TSTconst x [int64(int32(c)>>uint64(d))]) + // result: (TSTconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTSTconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -12236,11 +12202,11 @@ func rewriteValueARM_OpARMTSTshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12254,9 +12220,9 @@ func rewriteValueARM_OpARMTSTshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTSTshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12269,31 +12235,31 @@ func rewriteValueARM_OpARMTSTshiftRL(v *Value) bool { // match: (TSTshiftRL (MOVWconst [c]) x [d]) // result: (TSTconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (TSTshiftRL x (MOVWconst [c]) [d]) - // result: (TSTconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (TSTconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMTSTconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } @@ -12310,11 +12276,11 @@ func rewriteValueARM_OpARMTSTshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMTSTconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12328,9 +12294,9 @@ func rewriteValueARM_OpARMTSTshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMTSTshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12347,9 +12313,9 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { if v_1.Op != OpARMMOVWconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -12363,10 +12329,10 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { if v_1.Op != OpARMSLLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMXORshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12380,10 +12346,10 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { if v_1.Op != OpARMSRLconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMXORshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12397,10 +12363,10 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { if v_1.Op != OpARMSRAconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMXORshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12414,10 +12380,10 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { if v_1.Op != OpARMSRRconst { continue } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) y := v_1.Args[0] v.reset(OpARMXORshiftRR) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12479,7 +12445,7 @@ func rewriteValueARM_OpARMXOR(v *Value) bool { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -12489,7 +12455,7 @@ func rewriteValueARM_OpARMXORconst(v *Value) bool { // match: (XORconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt32(v.AuxInt) != 0 { break } x := v_0 @@ -12499,26 +12465,26 @@ func rewriteValueARM_OpARMXORconst(v *Value) bool { // match: (XORconst [c] (MOVWconst [d])) // result: (MOVWconst [c^d]) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) v.reset(OpARMMOVWconst) - v.AuxInt = c ^ d + v.AuxInt = int32ToAuxInt(c ^ d) return true } // match: (XORconst [c] (XORconst [d] x)) // result: (XORconst [c^d] x) for { - c := v.AuxInt + c := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMXORconst { break } - d := v_0.AuxInt + d := auxIntToInt32(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARMXORconst) - v.AuxInt = c ^ d + v.AuxInt = int32ToAuxInt(c ^ d) v.AddArg(x) return true } @@ -12532,39 +12498,39 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value) bool { // match: (XORshiftLL (MOVWconst [c]) x [d]) // result: (XORconst [c] (SLLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (XORshiftLL x (MOVWconst [c]) [d]) - // result: (XORconst x [int64(int32(uint32(c)<<uint64(d)))]) + // result: (XORconst x [c<<uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMXORconst) - v.AuxInt = int64(int32(uint32(c) << uint64(d))) + v.AuxInt = int32ToAuxInt(c << uint64(d)) v.AddArg(x) return true } // match: (XORshiftLL [c] (SRLconst x [32-c]) x) // result: (SRRconst [32-c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSRLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -12572,7 +12538,7 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = 32 - c + v.AuxInt = int32ToAuxInt(32 - c) v.AddArg(x) return true } @@ -12594,11 +12560,11 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value) bool { // cond: objabi.GOARM>=6 // result: (REV16 x) for { - if v.Type != typ.UInt16 || v.AuxInt != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || v_0.AuxInt != 24 { + if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 { break } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpARMSLLconst || v_0_0.AuxInt != 16 { + if v_0_0.Op != OpARMSLLconst || auxIntToInt32(v_0_0.AuxInt) != 16 { break } x := v_0_0.Args[0] @@ -12613,17 +12579,17 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSLLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -12639,11 +12605,11 @@ func rewriteValueARM_OpARMXORshiftLLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12657,9 +12623,9 @@ func rewriteValueARM_OpARMXORshiftLLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMXORshiftLL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12672,31 +12638,31 @@ func rewriteValueARM_OpARMXORshiftRA(v *Value) bool { // match: (XORshiftRA (MOVWconst [c]) x [d]) // result: (XORconst [c] (SRAconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRAconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (XORshiftRA x (MOVWconst [c]) [d]) - // result: (XORconst x [int64(int32(c)>>uint64(d))]) + // result: (XORconst x [c>>uint64(d)]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMXORconst) - v.AuxInt = int64(int32(c) >> uint64(d)) + v.AuxInt = int32ToAuxInt(c >> uint64(d)) v.AddArg(x) return true } @@ -12704,17 +12670,17 @@ func rewriteValueARM_OpARMXORshiftRA(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRAconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -12730,11 +12696,11 @@ func rewriteValueARM_OpARMXORshiftRAreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRA, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12748,9 +12714,9 @@ func rewriteValueARM_OpARMXORshiftRAreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMXORshiftRA) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12763,39 +12729,39 @@ func rewriteValueARM_OpARMXORshiftRL(v *Value) bool { // match: (XORshiftRL (MOVWconst [c]) x [d]) // result: (XORconst [c] (SRLconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRLconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (XORshiftRL x (MOVWconst [c]) [d]) - // result: (XORconst x [int64(int32(uint32(c)>>uint64(d)))]) + // result: (XORconst x [int32(uint32(c)>>uint64(d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMXORconst) - v.AuxInt = int64(int32(uint32(c) >> uint64(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) >> uint64(d))) v.AddArg(x) return true } // match: (XORshiftRL [c] (SLLconst x [32-c]) x) // result: (SRRconst [ c] x) for { - c := v.AuxInt - if v_0.Op != OpARMSLLconst || v_0.AuxInt != 32-c { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c { break } x := v_0.Args[0] @@ -12803,7 +12769,7 @@ func rewriteValueARM_OpARMXORshiftRL(v *Value) bool { break } v.reset(OpARMSRRconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg(x) return true } @@ -12811,17 +12777,17 @@ func rewriteValueARM_OpARMXORshiftRL(v *Value) bool { // cond: c==d // result: (MOVWconst [0]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMSRLconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) if x != v_1.Args[0] || !(c == d) { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -12837,11 +12803,11 @@ func rewriteValueARM_OpARMXORshiftRLreg(v *Value) bool { if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -12855,9 +12821,9 @@ func rewriteValueARM_OpARMXORshiftRLreg(v *Value) bool { if v_2.Op != OpARMMOVWconst { break } - c := v_2.AuxInt + c := auxIntToInt32(v_2.AuxInt) v.reset(OpARMXORshiftRL) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v.AddArg2(x, y) return true } @@ -12870,36 +12836,49 @@ func rewriteValueARM_OpARMXORshiftRR(v *Value) bool { // match: (XORshiftRR (MOVWconst [c]) x [d]) // result: (XORconst [c] (SRRconst <x.Type> x [d])) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) if v_0.Op != OpARMMOVWconst { break } - c := v_0.AuxInt + c := auxIntToInt32(v_0.AuxInt) x := v_1 v.reset(OpARMXORconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARMSRRconst, x.Type) - v0.AuxInt = d + v0.AuxInt = int32ToAuxInt(d) v0.AddArg(x) v.AddArg(v0) return true } // match: (XORshiftRR x (MOVWconst [c]) [d]) - // result: (XORconst x [int64(int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d)))]) + // result: (XORconst x [int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))]) for { - d := v.AuxInt + d := auxIntToInt32(v.AuxInt) x := v_0 if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMXORconst) - v.AuxInt = int64(int32(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c)>>uint64(d) | uint32(c)<<uint64(32-d))) v.AddArg(x) return true } return false } +func rewriteValueARM_OpAddr(v *Value) bool { + v_0 := v.Args[0] + // match: (Addr {sym} base) + // result: (MOVWaddr {sym} base) + for { + sym := auxToSym(v.Aux) + base := v_0 + v.reset(OpARMMOVWaddr) + v.Aux = symToAux(sym) + v.AddArg(base) + return true + } +} func rewriteValueARM_OpAvg32u(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -12912,7 +12891,7 @@ func rewriteValueARM_OpAvg32u(v *Value) bool { y := v_1 v.reset(OpARMADD) v0 := b.NewValue0(v.Pos, OpARMSRLconst, t) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v1 := b.NewValue0(v.Pos, OpARMSUB, t) v1.AddArg2(x, y) v0.AddArg(v1) @@ -12929,7 +12908,7 @@ func rewriteValueARM_OpBitLen32(v *Value) bool { t := v.Type x := v_0 v.reset(OpARMRSBconst) - v.AuxInt = 32 + v.AuxInt = int32ToAuxInt(32) v0 := b.NewValue0(v.Pos, OpARMCLZ, t) v0.AddArg(x) v.AddArg(v0) @@ -12951,18 +12930,18 @@ func rewriteValueARM_OpBswap32(v *Value) bool { v.reset(OpARMXOR) v.Type = t v0 := b.NewValue0(v.Pos, OpARMSRLconst, t) - v0.AuxInt = 8 + v0.AuxInt = int32ToAuxInt(8) v1 := b.NewValue0(v.Pos, OpARMBICconst, t) - v1.AuxInt = 0xff0000 + v1.AuxInt = int32ToAuxInt(0xff0000) v2 := b.NewValue0(v.Pos, OpARMXOR, t) v3 := b.NewValue0(v.Pos, OpARMSRRconst, t) - v3.AuxInt = 16 + v3.AuxInt = int32ToAuxInt(16) v3.AddArg(x) v2.AddArg2(x, v3) v1.AddArg(v2) v0.AddArg(v1) v4 := b.NewValue0(v.Pos, OpARMSRRconst, t) - v4.AuxInt = 8 + v4.AuxInt = int32ToAuxInt(8) v4.AddArg(x) v.AddArg2(v0, v4) return true @@ -12981,12 +12960,72 @@ func rewriteValueARM_OpBswap32(v *Value) bool { } return false } +func rewriteValueARM_OpConst16(v *Value) bool { + // match: (Const16 [val]) + // result: (MOVWconst [int32(val)]) + for { + val := auxIntToInt16(v.AuxInt) + v.reset(OpARMMOVWconst) + v.AuxInt = int32ToAuxInt(int32(val)) + return true + } +} +func rewriteValueARM_OpConst32(v *Value) bool { + // match: (Const32 [val]) + // result: (MOVWconst [int32(val)]) + for { + val := auxIntToInt32(v.AuxInt) + v.reset(OpARMMOVWconst) + v.AuxInt = int32ToAuxInt(int32(val)) + return true + } +} +func rewriteValueARM_OpConst32F(v *Value) bool { + // match: (Const32F [val]) + // result: (MOVFconst [float64(val)]) + for { + val := auxIntToFloat32(v.AuxInt) + v.reset(OpARMMOVFconst) + v.AuxInt = float64ToAuxInt(float64(val)) + return true + } +} +func rewriteValueARM_OpConst64F(v *Value) bool { + // match: (Const64F [val]) + // result: (MOVDconst [float64(val)]) + for { + val := auxIntToFloat64(v.AuxInt) + v.reset(OpARMMOVDconst) + v.AuxInt = float64ToAuxInt(float64(val)) + return true + } +} +func rewriteValueARM_OpConst8(v *Value) bool { + // match: (Const8 [val]) + // result: (MOVWconst [int32(val)]) + for { + val := auxIntToInt8(v.AuxInt) + v.reset(OpARMMOVWconst) + v.AuxInt = int32ToAuxInt(int32(val)) + return true + } +} +func rewriteValueARM_OpConstBool(v *Value) bool { + // match: (ConstBool [b]) + // result: (MOVWconst [b2i32(b)]) + for { + b := auxIntToBool(v.AuxInt) + v.reset(OpARMMOVWconst) + v.AuxInt = int32ToAuxInt(b2i32(b)) + return true + } +} func rewriteValueARM_OpConstNil(v *Value) bool { // match: (ConstNil) // result: (MOVWconst [0]) for { v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } } @@ -13004,16 +13043,16 @@ func rewriteValueARM_OpCtz16(v *Value) bool { break } v.reset(OpARMRSBconst) - v.AuxInt = 32 + v.AuxInt = int32ToAuxInt(32) v0 := b.NewValue0(v.Pos, OpARMCLZ, t) v1 := b.NewValue0(v.Pos, OpARMSUBconst, typ.UInt32) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v2 := b.NewValue0(v.Pos, OpARMAND, typ.UInt32) v3 := b.NewValue0(v.Pos, OpARMORconst, typ.UInt32) - v3.AuxInt = 0x10000 + v3.AuxInt = int32ToAuxInt(0x10000) v3.AddArg(x) v4 := b.NewValue0(v.Pos, OpARMRSBconst, typ.UInt32) - v4.AuxInt = 0 + v4.AuxInt = int32ToAuxInt(0) v4.AddArg(v3) v2.AddArg2(v3, v4) v1.AddArg(v2) @@ -13034,7 +13073,7 @@ func rewriteValueARM_OpCtz16(v *Value) bool { v.Type = t v0 := b.NewValue0(v.Pos, OpARMRBIT, typ.UInt32) v1 := b.NewValue0(v.Pos, OpARMORconst, typ.UInt32) - v1.AuxInt = 0x10000 + v1.AuxInt = int32ToAuxInt(0x10000) v1.AddArg(x) v0.AddArg(v1) v.AddArg(v0) @@ -13055,13 +13094,13 @@ func rewriteValueARM_OpCtz32(v *Value) bool { break } v.reset(OpARMRSBconst) - v.AuxInt = 32 + v.AuxInt = int32ToAuxInt(32) v0 := b.NewValue0(v.Pos, OpARMCLZ, t) v1 := b.NewValue0(v.Pos, OpARMSUBconst, t) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v2 := b.NewValue0(v.Pos, OpARMAND, t) v3 := b.NewValue0(v.Pos, OpARMRSBconst, t) - v3.AuxInt = 0 + v3.AuxInt = int32ToAuxInt(0) v3.AddArg(x) v2.AddArg2(x, v3) v1.AddArg(v2) @@ -13101,16 +13140,16 @@ func rewriteValueARM_OpCtz8(v *Value) bool { break } v.reset(OpARMRSBconst) - v.AuxInt = 32 + v.AuxInt = int32ToAuxInt(32) v0 := b.NewValue0(v.Pos, OpARMCLZ, t) v1 := b.NewValue0(v.Pos, OpARMSUBconst, typ.UInt32) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v2 := b.NewValue0(v.Pos, OpARMAND, typ.UInt32) v3 := b.NewValue0(v.Pos, OpARMORconst, typ.UInt32) - v3.AuxInt = 0x100 + v3.AuxInt = int32ToAuxInt(0x100) v3.AddArg(x) v4 := b.NewValue0(v.Pos, OpARMRSBconst, typ.UInt32) - v4.AuxInt = 0 + v4.AuxInt = int32ToAuxInt(0) v4.AddArg(v3) v2.AddArg2(v3, v4) v1.AddArg(v2) @@ -13131,7 +13170,7 @@ func rewriteValueARM_OpCtz8(v *Value) bool { v.Type = t v0 := b.NewValue0(v.Pos, OpARMRBIT, typ.UInt32) v1 := b.NewValue0(v.Pos, OpARMORconst, typ.UInt32) - v1.AuxInt = 0x100 + v1.AuxInt = int32ToAuxInt(0x100) v1.AddArg(x) v0.AddArg(v1) v.AddArg(v0) @@ -13371,7 +13410,7 @@ func rewriteValueARM_OpEqB(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMXORconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) v0 := b.NewValue0(v.Pos, OpARMXOR, typ.Bool) v0.AddArg2(x, y) v.AddArg(v0) @@ -13434,7 +13473,7 @@ func rewriteValueARM_OpIsNonNil(v *Value) bool { ptr := v_0 v.reset(OpARMNotEqual) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(ptr) v.AddArg(v0) return true @@ -13874,10 +13913,10 @@ func rewriteValueARM_OpLocalAddr(v *Value) bool { // match: (LocalAddr {sym} base _) // result: (MOVWaddr {sym} base) for { - sym := v.Aux + sym := auxToSym(v.Aux) base := v_0 v.reset(OpARMMOVWaddr) - v.Aux = sym + v.Aux = symToAux(sym) v.AddArg(base) return true } @@ -13893,13 +13932,13 @@ func rewriteValueARM_OpLsh16x16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg2(v0, v2) return true @@ -13915,11 +13954,11 @@ func rewriteValueARM_OpLsh16x32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg2(v0, v1) return true @@ -13930,18 +13969,18 @@ func rewriteValueARM_OpLsh16x64(v *Value) bool { v_0 := v.Args[0] // match: (Lsh16x64 x (Const64 [c])) // cond: uint64(c) < 16 - // result: (SLLconst x [c]) + // result: (SLLconst x [int32(c)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 16) { break } v.reset(OpARMSLLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -13952,12 +13991,12 @@ func rewriteValueARM_OpLsh16x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 16) { break } v.reset(OpConst16) - v.AuxInt = 0 + v.AuxInt = int16ToAuxInt(0) return true } return false @@ -13990,13 +14029,13 @@ func rewriteValueARM_OpLsh32x16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg2(v0, v2) return true @@ -14012,11 +14051,11 @@ func rewriteValueARM_OpLsh32x32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg2(v0, v1) return true @@ -14027,18 +14066,18 @@ func rewriteValueARM_OpLsh32x64(v *Value) bool { v_0 := v.Args[0] // match: (Lsh32x64 x (Const64 [c])) // cond: uint64(c) < 32 - // result: (SLLconst x [c]) + // result: (SLLconst x [int32(c)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 32) { break } v.reset(OpARMSLLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -14049,12 +14088,12 @@ func rewriteValueARM_OpLsh32x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 32) { break } v.reset(OpConst32) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -14087,13 +14126,13 @@ func rewriteValueARM_OpLsh8x16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg2(v0, v2) return true @@ -14109,11 +14148,11 @@ func rewriteValueARM_OpLsh8x32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSLL, x.Type) v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg2(v0, v1) return true @@ -14124,18 +14163,18 @@ func rewriteValueARM_OpLsh8x64(v *Value) bool { v_0 := v.Args[0] // match: (Lsh8x64 x (Const64 [c])) // cond: uint64(c) < 8 - // result: (SLLconst x [c]) + // result: (SLLconst x [int32(c)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 8) { break } v.reset(OpARMSLLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -14146,12 +14185,12 @@ func rewriteValueARM_OpLsh8x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 8) { break } v.reset(OpConst8) - v.AuxInt = 0 + v.AuxInt = int8ToAuxInt(0) return true } return false @@ -14310,7 +14349,7 @@ func rewriteValueARM_OpMove(v *Value) bool { // match: (Move [0] _ _ mem) // result: mem for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } mem := v_2 @@ -14320,7 +14359,7 @@ func rewriteValueARM_OpMove(v *Value) bool { // match: (Move [1] dst src mem) // result: (MOVBstore dst (MOVBUload src mem) mem) for { - if v.AuxInt != 1 { + if auxIntToInt64(v.AuxInt) != 1 { break } dst := v_0 @@ -14333,17 +14372,17 @@ func rewriteValueARM_OpMove(v *Value) bool { return true } // match: (Move [2] {t} dst src mem) - // cond: t.(*types.Type).Alignment()%2 == 0 + // cond: t.Alignment()%2 == 0 // result: (MOVHstore dst (MOVHUload src mem) mem) for { - if v.AuxInt != 2 { + if auxIntToInt64(v.AuxInt) != 2 { break } - t := v.Aux + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 - if !(t.(*types.Type).Alignment()%2 == 0) { + if !(t.Alignment()%2 == 0) { break } v.reset(OpARMMOVHstore) @@ -14355,16 +14394,16 @@ func rewriteValueARM_OpMove(v *Value) bool { // match: (Move [2] dst src mem) // result: (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem)) for { - if v.AuxInt != 2 { + if auxIntToInt64(v.AuxInt) != 2 { break } dst := v_0 src := v_1 mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v0.AddArg2(src, mem) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) @@ -14374,17 +14413,17 @@ func rewriteValueARM_OpMove(v *Value) bool { return true } // match: (Move [4] {t} dst src mem) - // cond: t.(*types.Type).Alignment()%4 == 0 + // cond: t.Alignment()%4 == 0 // result: (MOVWstore dst (MOVWload src mem) mem) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } - t := v.Aux + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 - if !(t.(*types.Type).Alignment()%4 == 0) { + if !(t.Alignment()%4 == 0) { break } v.reset(OpARMMOVWstore) @@ -14394,23 +14433,23 @@ func rewriteValueARM_OpMove(v *Value) bool { return true } // match: (Move [4] {t} dst src mem) - // cond: t.(*types.Type).Alignment()%2 == 0 + // cond: t.Alignment()%2 == 0 // result: (MOVHstore [2] dst (MOVHUload [2] src mem) (MOVHstore dst (MOVHUload src mem) mem)) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } - t := v.Aux + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 - if !(t.(*types.Type).Alignment()%2 == 0) { + if !(t.Alignment()%2 == 0) { break } v.reset(OpARMMOVHstore) - v.AuxInt = 2 + v.AuxInt = int32ToAuxInt(2) v0 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16) - v0.AuxInt = 2 + v0.AuxInt = int32ToAuxInt(2) v0.AddArg2(src, mem) v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem) v2 := b.NewValue0(v.Pos, OpARMMOVHUload, typ.UInt16) @@ -14422,26 +14461,26 @@ func rewriteValueARM_OpMove(v *Value) bool { // match: (Move [4] dst src mem) // result: (MOVBstore [3] dst (MOVBUload [3] src mem) (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem)))) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } dst := v_0 src := v_1 mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = 3 + v.AuxInt = int32ToAuxInt(3) v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v0.AuxInt = 3 + v0.AuxInt = int32ToAuxInt(3) v0.AddArg2(src, mem) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v2.AuxInt = 2 + v2.AuxInt = int32ToAuxInt(2) v2.AddArg2(src, mem) v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v3.AuxInt = 1 + v3.AuxInt = int32ToAuxInt(1) v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v4.AuxInt = 1 + v4.AuxInt = int32ToAuxInt(1) v4.AddArg2(src, mem) v5 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) v6 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) @@ -14455,21 +14494,21 @@ func rewriteValueARM_OpMove(v *Value) bool { // match: (Move [3] dst src mem) // result: (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVBstore [1] dst (MOVBUload [1] src mem) (MOVBstore dst (MOVBUload src mem) mem))) for { - if v.AuxInt != 3 { + if auxIntToInt64(v.AuxInt) != 3 { break } dst := v_0 src := v_1 mem := v_2 v.reset(OpARMMOVBstore) - v.AuxInt = 2 + v.AuxInt = int32ToAuxInt(2) v0 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v0.AuxInt = 2 + v0.AuxInt = int32ToAuxInt(2) v0.AddArg2(src, mem) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v2 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) - v2.AuxInt = 1 + v2.AuxInt = int32ToAuxInt(1) v2.AddArg2(src, mem) v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) v4 := b.NewValue0(v.Pos, OpARMMOVBUload, typ.UInt8) @@ -14480,38 +14519,38 @@ func rewriteValueARM_OpMove(v *Value) bool { return true } // match: (Move [s] {t} dst src mem) - // cond: s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) + // cond: s%4 == 0 && s > 4 && s <= 512 && t.Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) // result: (DUFFCOPY [8 * (128 - s/4)] dst src mem) for { - s := v.AuxInt - t := v.Aux + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 - if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) { + if !(s%4 == 0 && s > 4 && s <= 512 && t.Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) { break } v.reset(OpARMDUFFCOPY) - v.AuxInt = 8 * (128 - s/4) + v.AuxInt = int64ToAuxInt(8 * (128 - s/4)) v.AddArg3(dst, src, mem) return true } // match: (Move [s] {t} dst src mem) - // cond: ((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) && logLargeCopy(v, s) - // result: (LoweredMove [t.(*types.Type).Alignment()] dst src (ADDconst <src.Type> src [s-moveSize(t.(*types.Type).Alignment(), config)]) mem) + // cond: ((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) && logLargeCopy(v, s) + // result: (LoweredMove [t.Alignment()] dst src (ADDconst <src.Type> src [int32(s-moveSize(t.Alignment(), config))]) mem) for { - s := v.AuxInt - t := v.Aux + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 - if !(((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) && logLargeCopy(v, s)) { + if !(((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) && logLargeCopy(v, s)) { break } v.reset(OpARMLoweredMove) - v.AuxInt = t.(*types.Type).Alignment() + v.AuxInt = int64ToAuxInt(t.Alignment()) v0 := b.NewValue0(v.Pos, OpARMADDconst, src.Type) - v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config) + v0.AuxInt = int32ToAuxInt(int32(s - moveSize(t.Alignment(), config))) v0.AddArg(src) v.AddArg4(dst, src, v0, mem) return true @@ -14525,7 +14564,7 @@ func rewriteValueARM_OpNeg16(v *Value) bool { for { x := v_0 v.reset(OpARMRSBconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v.AddArg(x) return true } @@ -14537,7 +14576,7 @@ func rewriteValueARM_OpNeg32(v *Value) bool { for { x := v_0 v.reset(OpARMRSBconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v.AddArg(x) return true } @@ -14549,7 +14588,7 @@ func rewriteValueARM_OpNeg8(v *Value) bool { for { x := v_0 v.reset(OpARMRSBconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v.AddArg(x) return true } @@ -14667,7 +14706,7 @@ func rewriteValueARM_OpNot(v *Value) bool { for { x := v_0 v.reset(OpARMXORconst) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) v.AddArg(x) return true } @@ -14675,25 +14714,25 @@ func rewriteValueARM_OpNot(v *Value) bool { func rewriteValueARM_OpOffPtr(v *Value) bool { v_0 := v.Args[0] // match: (OffPtr [off] ptr:(SP)) - // result: (MOVWaddr [off] ptr) + // result: (MOVWaddr [int32(off)] ptr) for { - off := v.AuxInt + off := auxIntToInt64(v.AuxInt) ptr := v_0 if ptr.Op != OpSP { break } v.reset(OpARMMOVWaddr) - v.AuxInt = off + v.AuxInt = int32ToAuxInt(int32(off)) v.AddArg(ptr) return true } // match: (OffPtr [off] ptr) - // result: (ADDconst [off] ptr) + // result: (ADDconst [int32(off)] ptr) for { - off := v.AuxInt + off := auxIntToInt64(v.AuxInt) ptr := v_0 v.reset(OpARMADDconst) - v.AuxInt = off + v.AuxInt = int32ToAuxInt(int32(off)) v.AddArg(ptr) return true } @@ -14706,7 +14745,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { // cond: boundsABI(kind) == 0 // result: (LoweredPanicBoundsA [kind] x y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) x := v_0 y := v_1 mem := v_2 @@ -14714,7 +14753,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { break } v.reset(OpARMLoweredPanicBoundsA) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg3(x, y, mem) return true } @@ -14722,7 +14761,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { // cond: boundsABI(kind) == 1 // result: (LoweredPanicBoundsB [kind] x y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) x := v_0 y := v_1 mem := v_2 @@ -14730,7 +14769,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { break } v.reset(OpARMLoweredPanicBoundsB) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg3(x, y, mem) return true } @@ -14738,7 +14777,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { // cond: boundsABI(kind) == 2 // result: (LoweredPanicBoundsC [kind] x y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) x := v_0 y := v_1 mem := v_2 @@ -14746,7 +14785,7 @@ func rewriteValueARM_OpPanicBounds(v *Value) bool { break } v.reset(OpARMLoweredPanicBoundsC) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg3(x, y, mem) return true } @@ -14761,7 +14800,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { // cond: boundsABI(kind) == 0 // result: (LoweredPanicExtendA [kind] hi lo y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) hi := v_0 lo := v_1 y := v_2 @@ -14770,7 +14809,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { break } v.reset(OpARMLoweredPanicExtendA) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg4(hi, lo, y, mem) return true } @@ -14778,7 +14817,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { // cond: boundsABI(kind) == 1 // result: (LoweredPanicExtendB [kind] hi lo y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) hi := v_0 lo := v_1 y := v_2 @@ -14787,7 +14826,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { break } v.reset(OpARMLoweredPanicExtendB) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg4(hi, lo, y, mem) return true } @@ -14795,7 +14834,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { // cond: boundsABI(kind) == 2 // result: (LoweredPanicExtendC [kind] hi lo y mem) for { - kind := v.AuxInt + kind := auxIntToInt64(v.AuxInt) hi := v_0 lo := v_1 y := v_2 @@ -14804,7 +14843,7 @@ func rewriteValueARM_OpPanicExtend(v *Value) bool { break } v.reset(OpARMLoweredPanicExtendC) - v.AuxInt = kind + v.AuxInt = int64ToAuxInt(kind) v.AddArg4(hi, lo, y, mem) return true } @@ -14823,15 +14862,15 @@ func rewriteValueARM_OpRotateLeft16(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpOr16) v0 := b.NewValue0(v.Pos, OpLsh16x32, t) v1 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v1.AuxInt = c & 15 + v1.AuxInt = int32ToAuxInt(c & 15) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpRsh16Ux32, t) v3 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v3.AuxInt = -c & 15 + v3.AuxInt = int32ToAuxInt(-c & 15) v2.AddArg2(x, v3) v.AddArg2(v0, v2) return true @@ -14849,9 +14888,9 @@ func rewriteValueARM_OpRotateLeft32(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpARMSRRconst) - v.AuxInt = -c & 31 + v.AuxInt = int32ToAuxInt(-c & 31) v.AddArg(x) return true } @@ -14862,7 +14901,7 @@ func rewriteValueARM_OpRotateLeft32(v *Value) bool { y := v_1 v.reset(OpARMSRR) v0 := b.NewValue0(v.Pos, OpARMRSBconst, y.Type) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(y) v.AddArg2(x, v0) return true @@ -14881,15 +14920,15 @@ func rewriteValueARM_OpRotateLeft8(v *Value) bool { if v_1.Op != OpARMMOVWconst { break } - c := v_1.AuxInt + c := auxIntToInt32(v_1.AuxInt) v.reset(OpOr8) v0 := b.NewValue0(v.Pos, OpLsh8x32, t) v1 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v1.AuxInt = c & 7 + v1.AuxInt = int32ToAuxInt(c & 7) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpRsh8Ux32, t) v3 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v3.AuxInt = -c & 7 + v3.AuxInt = int32ToAuxInt(-c & 7) v2.AddArg2(x, v3) v.AddArg2(v0, v2) return true @@ -14907,7 +14946,7 @@ func rewriteValueARM_OpRsh16Ux16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(x) @@ -14915,7 +14954,7 @@ func rewriteValueARM_OpRsh16Ux16(v *Value) bool { v2.AddArg(y) v0.AddArg2(v1, v2) v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v3.AuxInt = 256 + v3.AuxInt = int32ToAuxInt(256) v3.AddArg(v2) v.AddArg2(v0, v3) return true @@ -14932,13 +14971,13 @@ func rewriteValueARM_OpRsh16Ux32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(x) v0.AddArg2(v1, y) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(y) v.AddArg2(v0, v2) return true @@ -14951,20 +14990,20 @@ func rewriteValueARM_OpRsh16Ux64(v *Value) bool { typ := &b.Func.Config.Types // match: (Rsh16Ux64 x (Const64 [c])) // cond: uint64(c) < 16 - // result: (SRLconst (SLLconst <typ.UInt32> x [16]) [c+16]) + // result: (SRLconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 16) { break } v.reset(OpARMSRLconst) - v.AuxInt = c + 16 + v.AuxInt = int32ToAuxInt(int32(c + 16)) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 16 + v0.AuxInt = int32ToAuxInt(16) v0.AddArg(x) v.AddArg(v0) return true @@ -14976,12 +15015,12 @@ func rewriteValueARM_OpRsh16Ux64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 16) { break } v.reset(OpConst16) - v.AuxInt = 0 + v.AuxInt = int16ToAuxInt(0) return true } return false @@ -15021,7 +15060,7 @@ func rewriteValueARM_OpRsh16x16(v *Value) bool { v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg3(v0, v1, v2) return true @@ -15041,7 +15080,7 @@ func rewriteValueARM_OpRsh16x32(v *Value) bool { v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg3(v0, y, v1) return true @@ -15054,20 +15093,20 @@ func rewriteValueARM_OpRsh16x64(v *Value) bool { typ := &b.Func.Config.Types // match: (Rsh16x64 x (Const64 [c])) // cond: uint64(c) < 16 - // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [c+16]) + // result: (SRAconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 16) { break } v.reset(OpARMSRAconst) - v.AuxInt = c + 16 + v.AuxInt = int32ToAuxInt(int32(c + 16)) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 16 + v0.AuxInt = int32ToAuxInt(16) v0.AddArg(x) v.AddArg(v0) return true @@ -15080,14 +15119,14 @@ func rewriteValueARM_OpRsh16x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 16) { break } v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 16 + v0.AuxInt = int32ToAuxInt(16) v0.AddArg(x) v.AddArg(v0) return true @@ -15124,13 +15163,13 @@ func rewriteValueARM_OpRsh32Ux16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v0.AddArg2(x, v1) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg2(v0, v2) return true @@ -15146,11 +15185,11 @@ func rewriteValueARM_OpRsh32Ux32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg2(v0, v1) return true @@ -15161,18 +15200,18 @@ func rewriteValueARM_OpRsh32Ux64(v *Value) bool { v_0 := v.Args[0] // match: (Rsh32Ux64 x (Const64 [c])) // cond: uint64(c) < 32 - // result: (SRLconst x [c]) + // result: (SRLconst x [int32(c)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 32) { break } v.reset(OpARMSRLconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -15183,12 +15222,12 @@ func rewriteValueARM_OpRsh32Ux64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 32) { break } v.reset(OpConst32) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } return false @@ -15224,7 +15263,7 @@ func rewriteValueARM_OpRsh32x16(v *Value) bool { v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v0.AddArg(y) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(v0) v.AddArg3(x, v0, v1) return true @@ -15241,7 +15280,7 @@ func rewriteValueARM_OpRsh32x32(v *Value) bool { y := v_1 v.reset(OpARMSRAcond) v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = 256 + v0.AuxInt = int32ToAuxInt(256) v0.AddArg(y) v.AddArg3(x, y, v0) return true @@ -15252,18 +15291,18 @@ func rewriteValueARM_OpRsh32x64(v *Value) bool { v_0 := v.Args[0] // match: (Rsh32x64 x (Const64 [c])) // cond: uint64(c) < 32 - // result: (SRAconst x [c]) + // result: (SRAconst x [int32(c)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 32) { break } v.reset(OpARMSRAconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -15275,12 +15314,12 @@ func rewriteValueARM_OpRsh32x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 32) { break } v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v.AddArg(x) return true } @@ -15314,7 +15353,7 @@ func rewriteValueARM_OpRsh8Ux16(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) v1.AddArg(x) @@ -15322,7 +15361,7 @@ func rewriteValueARM_OpRsh8Ux16(v *Value) bool { v2.AddArg(y) v0.AddArg2(v1, v2) v3 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v3.AuxInt = 256 + v3.AuxInt = int32ToAuxInt(256) v3.AddArg(v2) v.AddArg2(v0, v3) return true @@ -15339,13 +15378,13 @@ func rewriteValueARM_OpRsh8Ux32(v *Value) bool { x := v_0 y := v_1 v.reset(OpARMCMOVWHSconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) v0 := b.NewValue0(v.Pos, OpARMSRL, x.Type) v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) v1.AddArg(x) v0.AddArg2(v1, y) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(y) v.AddArg2(v0, v2) return true @@ -15358,20 +15397,20 @@ func rewriteValueARM_OpRsh8Ux64(v *Value) bool { typ := &b.Func.Config.Types // match: (Rsh8Ux64 x (Const64 [c])) // cond: uint64(c) < 8 - // result: (SRLconst (SLLconst <typ.UInt32> x [24]) [c+24]) + // result: (SRLconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 8) { break } v.reset(OpARMSRLconst) - v.AuxInt = c + 24 + v.AuxInt = int32ToAuxInt(int32(c + 24)) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 24 + v0.AuxInt = int32ToAuxInt(24) v0.AddArg(x) v.AddArg(v0) return true @@ -15383,12 +15422,12 @@ func rewriteValueARM_OpRsh8Ux64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 8) { break } v.reset(OpConst8) - v.AuxInt = 0 + v.AuxInt = int8ToAuxInt(0) return true } return false @@ -15428,7 +15467,7 @@ func rewriteValueARM_OpRsh8x16(v *Value) bool { v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v2 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v2.AuxInt = 256 + v2.AuxInt = int32ToAuxInt(256) v2.AddArg(v1) v.AddArg3(v0, v1, v2) return true @@ -15448,7 +15487,7 @@ func rewriteValueARM_OpRsh8x32(v *Value) bool { v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags) - v1.AuxInt = 256 + v1.AuxInt = int32ToAuxInt(256) v1.AddArg(y) v.AddArg3(v0, y, v1) return true @@ -15461,20 +15500,20 @@ func rewriteValueARM_OpRsh8x64(v *Value) bool { typ := &b.Func.Config.Types // match: (Rsh8x64 x (Const64 [c])) // cond: uint64(c) < 8 - // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [c+24]) + // result: (SRAconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)]) for { x := v_0 if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) < 8) { break } v.reset(OpARMSRAconst) - v.AuxInt = c + 24 + v.AuxInt = int32ToAuxInt(int32(c + 24)) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 24 + v0.AuxInt = int32ToAuxInt(24) v0.AddArg(x) v.AddArg(v0) return true @@ -15487,14 +15526,14 @@ func rewriteValueARM_OpRsh8x64(v *Value) bool { if v_1.Op != OpConst64 { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint64(c) >= 8) { break } v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v0 := b.NewValue0(v.Pos, OpARMSLLconst, typ.UInt32) - v0.AuxInt = 24 + v0.AuxInt = int32ToAuxInt(24) v0.AddArg(x) v.AddArg(v0) return true @@ -15531,15 +15570,15 @@ func rewriteValueARM_OpSelect0(v *Value) bool { _ = v_0.Args[1] x := v_0.Args[0] v_0_1 := v_0.Args[1] - if v_0_1.Op != OpARMMOVWconst || v_0_1.AuxInt != 1 { + if v_0_1.Op != OpARMMOVWconst || auxIntToInt32(v_0_1.AuxInt) != 1 { break } v.copyOf(x) return true } // match: (Select0 (CALLudiv x (MOVWconst [c]))) - // cond: isPowerOfTwo(c) - // result: (SRLconst [log2(c)] x) + // cond: isPowerOfTwo32(c) + // result: (SRLconst [int32(log32(c))] x) for { if v_0.Op != OpARMCALLudiv { break @@ -15550,17 +15589,18 @@ func rewriteValueARM_OpSelect0(v *Value) bool { if v_0_1.Op != OpARMMOVWconst { break } - c := v_0_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt32(v_0_1.AuxInt) + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMSRLconst) - v.AuxInt = log2(c) + v.AuxInt = int32ToAuxInt(int32(log32(c))) v.AddArg(x) return true } // match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) - // result: (MOVWconst [int64(int32(uint32(c)/uint32(d)))]) + // cond: d != 0 + // result: (MOVWconst [int32(uint32(c)/uint32(d))]) for { if v_0.Op != OpARMCALLudiv { break @@ -15570,14 +15610,17 @@ func rewriteValueARM_OpSelect0(v *Value) bool { if v_0_0.Op != OpARMMOVWconst { break } - c := v_0_0.AuxInt + c := auxIntToInt32(v_0_0.AuxInt) v_0_1 := v_0.Args[1] if v_0_1.Op != OpARMMOVWconst { break } - d := v_0_1.AuxInt + d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(uint32(c) / uint32(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) / uint32(d))) return true } return false @@ -15592,15 +15635,15 @@ func rewriteValueARM_OpSelect1(v *Value) bool { } _ = v_0.Args[1] v_0_1 := v_0.Args[1] - if v_0_1.Op != OpARMMOVWconst || v_0_1.AuxInt != 1 { + if v_0_1.Op != OpARMMOVWconst || auxIntToInt32(v_0_1.AuxInt) != 1 { break } v.reset(OpARMMOVWconst) - v.AuxInt = 0 + v.AuxInt = int32ToAuxInt(0) return true } // match: (Select1 (CALLudiv x (MOVWconst [c]))) - // cond: isPowerOfTwo(c) + // cond: isPowerOfTwo32(c) // result: (ANDconst [c-1] x) for { if v_0.Op != OpARMCALLudiv { @@ -15612,17 +15655,18 @@ func rewriteValueARM_OpSelect1(v *Value) bool { if v_0_1.Op != OpARMMOVWconst { break } - c := v_0_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt32(v_0_1.AuxInt) + if !(isPowerOfTwo32(c)) { break } v.reset(OpARMANDconst) - v.AuxInt = c - 1 + v.AuxInt = int32ToAuxInt(c - 1) v.AddArg(x) return true } // match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) - // result: (MOVWconst [int64(int32(uint32(c)%uint32(d)))]) + // cond: d != 0 + // result: (MOVWconst [int32(uint32(c)%uint32(d))]) for { if v_0.Op != OpARMCALLudiv { break @@ -15632,14 +15676,17 @@ func rewriteValueARM_OpSelect1(v *Value) bool { if v_0_0.Op != OpARMMOVWconst { break } - c := v_0_0.AuxInt + c := auxIntToInt32(v_0_0.AuxInt) v_0_1 := v_0.Args[1] if v_0_1.Op != OpARMMOVWconst { break } - d := v_0_1.AuxInt + d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARMMOVWconst) - v.AuxInt = int64(int32(uint32(c) % uint32(d))) + v.AuxInt = int32ToAuxInt(int32(uint32(c) % uint32(d))) return true } return false @@ -15651,7 +15698,7 @@ func rewriteValueARM_OpSignmask(v *Value) bool { for { x := v_0 v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v.AddArg(x) return true } @@ -15665,9 +15712,9 @@ func rewriteValueARM_OpSlicemask(v *Value) bool { t := v.Type x := v_0 v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v0 := b.NewValue0(v.Pos, OpARMRSBconst, t) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(x) v.AddArg(v0) return true @@ -15678,14 +15725,14 @@ func rewriteValueARM_OpStore(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (Store {t} ptr val mem) - // cond: t.(*types.Type).Size() == 1 + // cond: t.Size() == 1 // result: (MOVBstore ptr val mem) for { - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 val := v_1 mem := v_2 - if !(t.(*types.Type).Size() == 1) { + if !(t.Size() == 1) { break } v.reset(OpARMMOVBstore) @@ -15693,14 +15740,14 @@ func rewriteValueARM_OpStore(v *Value) bool { return true } // match: (Store {t} ptr val mem) - // cond: t.(*types.Type).Size() == 2 + // cond: t.Size() == 2 // result: (MOVHstore ptr val mem) for { - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 val := v_1 mem := v_2 - if !(t.(*types.Type).Size() == 2) { + if !(t.Size() == 2) { break } v.reset(OpARMMOVHstore) @@ -15708,14 +15755,14 @@ func rewriteValueARM_OpStore(v *Value) bool { return true } // match: (Store {t} ptr val mem) - // cond: t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type) + // cond: t.Size() == 4 && !is32BitFloat(val.Type) // result: (MOVWstore ptr val mem) for { - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 val := v_1 mem := v_2 - if !(t.(*types.Type).Size() == 4 && !is32BitFloat(val.Type)) { + if !(t.Size() == 4 && !is32BitFloat(val.Type)) { break } v.reset(OpARMMOVWstore) @@ -15723,14 +15770,14 @@ func rewriteValueARM_OpStore(v *Value) bool { return true } // match: (Store {t} ptr val mem) - // cond: t.(*types.Type).Size() == 4 && is32BitFloat(val.Type) + // cond: t.Size() == 4 && is32BitFloat(val.Type) // result: (MOVFstore ptr val mem) for { - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 val := v_1 mem := v_2 - if !(t.(*types.Type).Size() == 4 && is32BitFloat(val.Type)) { + if !(t.Size() == 4 && is32BitFloat(val.Type)) { break } v.reset(OpARMMOVFstore) @@ -15738,14 +15785,14 @@ func rewriteValueARM_OpStore(v *Value) bool { return true } // match: (Store {t} ptr val mem) - // cond: t.(*types.Type).Size() == 8 && is64BitFloat(val.Type) + // cond: t.Size() == 8 && is64BitFloat(val.Type) // result: (MOVDstore ptr val mem) for { - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 val := v_1 mem := v_2 - if !(t.(*types.Type).Size() == 8 && is64BitFloat(val.Type)) { + if !(t.Size() == 8 && is64BitFloat(val.Type)) { break } v.reset(OpARMMOVDstore) @@ -15763,7 +15810,7 @@ func rewriteValueARM_OpZero(v *Value) bool { // match: (Zero [0] _ mem) // result: mem for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } mem := v_1 @@ -15773,92 +15820,92 @@ func rewriteValueARM_OpZero(v *Value) bool { // match: (Zero [1] ptr mem) // result: (MOVBstore ptr (MOVWconst [0]) mem) for { - if v.AuxInt != 1 { + if auxIntToInt64(v.AuxInt) != 1 { break } ptr := v_0 mem := v_1 v.reset(OpARMMOVBstore) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (Zero [2] {t} ptr mem) - // cond: t.(*types.Type).Alignment()%2 == 0 + // cond: t.Alignment()%2 == 0 // result: (MOVHstore ptr (MOVWconst [0]) mem) for { - if v.AuxInt != 2 { + if auxIntToInt64(v.AuxInt) != 2 { break } - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 mem := v_1 - if !(t.(*types.Type).Alignment()%2 == 0) { + if !(t.Alignment()%2 == 0) { break } v.reset(OpARMMOVHstore) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (Zero [2] ptr mem) // result: (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem)) for { - if v.AuxInt != 2 { + if auxIntToInt64(v.AuxInt) != 2 { break } ptr := v_0 mem := v_1 v.reset(OpARMMOVBstore) - v.AuxInt = 1 + v.AuxInt = int32ToAuxInt(1) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v1.AuxInt = 0 + v1.AuxInt = int32ToAuxInt(0) v1.AddArg3(ptr, v0, mem) v.AddArg3(ptr, v0, v1) return true } // match: (Zero [4] {t} ptr mem) - // cond: t.(*types.Type).Alignment()%4 == 0 + // cond: t.Alignment()%4 == 0 // result: (MOVWstore ptr (MOVWconst [0]) mem) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 mem := v_1 - if !(t.(*types.Type).Alignment()%4 == 0) { + if !(t.Alignment()%4 == 0) { break } v.reset(OpARMMOVWstore) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (Zero [4] {t} ptr mem) - // cond: t.(*types.Type).Alignment()%2 == 0 + // cond: t.Alignment()%2 == 0 // result: (MOVHstore [2] ptr (MOVWconst [0]) (MOVHstore [0] ptr (MOVWconst [0]) mem)) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } - t := v.Aux + t := auxToType(v.Aux) ptr := v_0 mem := v_1 - if !(t.(*types.Type).Alignment()%2 == 0) { + if !(t.Alignment()%2 == 0) { break } v.reset(OpARMMOVHstore) - v.AuxInt = 2 + v.AuxInt = int32ToAuxInt(2) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v1 := b.NewValue0(v.Pos, OpARMMOVHstore, types.TypeMem) - v1.AuxInt = 0 + v1.AuxInt = int32ToAuxInt(0) v1.AddArg3(ptr, v0, mem) v.AddArg3(ptr, v0, v1) return true @@ -15866,21 +15913,21 @@ func rewriteValueARM_OpZero(v *Value) bool { // match: (Zero [4] ptr mem) // result: (MOVBstore [3] ptr (MOVWconst [0]) (MOVBstore [2] ptr (MOVWconst [0]) (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem)))) for { - if v.AuxInt != 4 { + if auxIntToInt64(v.AuxInt) != 4 { break } ptr := v_0 mem := v_1 v.reset(OpARMMOVBstore) - v.AuxInt = 3 + v.AuxInt = int32ToAuxInt(3) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v1.AuxInt = 2 + v1.AuxInt = int32ToAuxInt(2) v2 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v2.AuxInt = 1 + v2.AuxInt = int32ToAuxInt(1) v3 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v3.AuxInt = 0 + v3.AuxInt = int32ToAuxInt(0) v3.AddArg3(ptr, v0, mem) v2.AddArg3(ptr, v0, v3) v1.AddArg3(ptr, v0, v2) @@ -15890,60 +15937,60 @@ func rewriteValueARM_OpZero(v *Value) bool { // match: (Zero [3] ptr mem) // result: (MOVBstore [2] ptr (MOVWconst [0]) (MOVBstore [1] ptr (MOVWconst [0]) (MOVBstore [0] ptr (MOVWconst [0]) mem))) for { - if v.AuxInt != 3 { + if auxIntToInt64(v.AuxInt) != 3 { break } ptr := v_0 mem := v_1 v.reset(OpARMMOVBstore) - v.AuxInt = 2 + v.AuxInt = int32ToAuxInt(2) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v1 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v1.AuxInt = 1 + v1.AuxInt = int32ToAuxInt(1) v2 := b.NewValue0(v.Pos, OpARMMOVBstore, types.TypeMem) - v2.AuxInt = 0 + v2.AuxInt = int32ToAuxInt(0) v2.AddArg3(ptr, v0, mem) v1.AddArg3(ptr, v0, v2) v.AddArg3(ptr, v0, v1) return true } // match: (Zero [s] {t} ptr mem) - // cond: s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice + // cond: s%4 == 0 && s > 4 && s <= 512 && t.Alignment()%4 == 0 && !config.noDuffDevice // result: (DUFFZERO [4 * (128 - s/4)] ptr (MOVWconst [0]) mem) for { - s := v.AuxInt - t := v.Aux + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) ptr := v_0 mem := v_1 - if !(s%4 == 0 && s > 4 && s <= 512 && t.(*types.Type).Alignment()%4 == 0 && !config.noDuffDevice) { + if !(s%4 == 0 && s > 4 && s <= 512 && t.Alignment()%4 == 0 && !config.noDuffDevice) { break } v.reset(OpARMDUFFZERO) - v.AuxInt = 4 * (128 - s/4) + v.AuxInt = int64ToAuxInt(4 * (128 - s/4)) v0 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } // match: (Zero [s] {t} ptr mem) - // cond: (s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0 - // result: (LoweredZero [t.(*types.Type).Alignment()] ptr (ADDconst <ptr.Type> ptr [s-moveSize(t.(*types.Type).Alignment(), config)]) (MOVWconst [0]) mem) + // cond: (s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0 + // result: (LoweredZero [t.Alignment()] ptr (ADDconst <ptr.Type> ptr [int32(s-moveSize(t.Alignment(), config))]) (MOVWconst [0]) mem) for { - s := v.AuxInt - t := v.Aux + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) ptr := v_0 mem := v_1 - if !((s > 512 || config.noDuffDevice) || t.(*types.Type).Alignment()%4 != 0) { + if !((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) { break } v.reset(OpARMLoweredZero) - v.AuxInt = t.(*types.Type).Alignment() + v.AuxInt = int64ToAuxInt(t.Alignment()) v0 := b.NewValue0(v.Pos, OpARMADDconst, ptr.Type) - v0.AuxInt = s - moveSize(t.(*types.Type).Alignment(), config) + v0.AuxInt = int32ToAuxInt(int32(s - moveSize(t.Alignment(), config))) v0.AddArg(ptr) v1 := b.NewValue0(v.Pos, OpARMMOVWconst, typ.UInt32) - v1.AuxInt = 0 + v1.AuxInt = int32ToAuxInt(0) v.AddArg4(ptr, v0, v1, mem) return true } @@ -15958,9 +16005,9 @@ func rewriteValueARM_OpZeromask(v *Value) bool { for { x := v_0 v.reset(OpARMSRAconst) - v.AuxInt = 31 + v.AuxInt = int32ToAuxInt(31) v0 := b.NewValue0(v.Pos, OpARMRSBshiftRL, typ.Int32) - v0.AuxInt = 1 + v0.AuxInt = int32ToAuxInt(1) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -16002,12 +16049,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMEQ, cmp) return true } + // match: (EQ (CMP x (RSBconst [0] y))) + // result: (EQ (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMEQ, v0) + return true + } + // match: (EQ (CMN x (RSBconst [0] y))) + // result: (EQ (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMEQ, v0) + return true + } + break + } // match: (EQ (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (EQ (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16029,7 +16112,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16054,20 +16137,20 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMEQ, v0) return true @@ -16077,21 +16160,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16101,21 +16184,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16125,21 +16208,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16149,7 +16232,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16172,7 +16255,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16195,7 +16278,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16218,7 +16301,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16246,7 +16329,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMN a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16271,20 +16354,20 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMEQ, v0) return true @@ -16294,21 +16377,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16318,21 +16401,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16342,21 +16425,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16366,7 +16449,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16389,7 +16472,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16412,7 +16495,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16435,7 +16518,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16463,20 +16546,20 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMEQ, v0) return true @@ -16486,21 +16569,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16510,21 +16593,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16534,21 +16617,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16558,7 +16641,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16581,7 +16664,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16604,7 +16687,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16627,7 +16710,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16655,20 +16738,20 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMEQ, v0) return true @@ -16678,21 +16761,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16702,21 +16785,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16726,21 +16809,21 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMEQ, v0) return true @@ -16750,7 +16833,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16773,7 +16856,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16796,7 +16879,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16848,12 +16931,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMLE, cmp) return true } + // match: (GE (CMP x (RSBconst [0] y))) + // result: (GE (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMGE, v0) + return true + } + // match: (GE (CMN x (RSBconst [0] y))) + // result: (GE (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMGE, v0) + return true + } + break + } // match: (GE (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (GEnoov (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16875,7 +16994,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -16900,20 +17019,20 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -16923,21 +17042,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -16947,21 +17066,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -16971,21 +17090,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -16995,7 +17114,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17018,7 +17137,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17041,7 +17160,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17064,7 +17183,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17092,7 +17211,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMN a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17117,20 +17236,20 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -17140,21 +17259,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -17164,21 +17283,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -17188,21 +17307,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGEnoov, v0) return true @@ -17212,7 +17331,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17235,7 +17354,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17258,7 +17377,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GEnoov (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17278,10 +17397,10 @@ func rewriteBlockARM(b *Block) bool { } // match: (GE (CMPconst [0] l:(AND x y)) yes no) // cond: l.Uses==1 - // result: (GE (TST x y) yes no) + // result: (GEnoov (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17299,112 +17418,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } break } // match: (GE (CMPconst [0] l:(ANDconst [c] x)) yes no) // cond: l.Uses==1 - // result: (GE (TSTconst [c] x) yes no) + // result: (GEnoov (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftLL x y [c]) yes no) + // result: (GEnoov (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftRL x y [c]) yes no) + // result: (GEnoov (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftRA x y [c]) yes no) + // result: (GEnoov (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftLLreg x y z) yes no) + // result: (GEnoov (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17419,15 +17538,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftRLreg x y z) yes no) + // result: (GEnoov (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17442,15 +17561,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TSTshiftRAreg x y z) yes no) + // result: (GEnoov (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17465,15 +17584,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XOR x y)) yes no) // cond: l.Uses==1 - // result: (GE (TEQ x y) yes no) + // result: (GEnoov (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17491,112 +17610,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } break } // match: (GE (CMPconst [0] l:(XORconst [c] x)) yes no) // cond: l.Uses==1 - // result: (GE (TEQconst [c] x) yes no) + // result: (GEnoov (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftLL x y [c]) yes no) + // result: (GEnoov (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftRL x y [c]) yes no) + // result: (GEnoov (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftRA x y [c]) yes no) + // result: (GEnoov (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftLLreg x y z) yes no) + // result: (GEnoov (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17611,15 +17730,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftRLreg x y z) yes no) + // result: (GEnoov (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17634,15 +17753,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } // match: (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (GE (TEQshiftRAreg x y z) yes no) + // result: (GEnoov (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17657,7 +17776,7 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGE, v0) + b.resetWithControl(BlockARMGEnoov, v0) return true } case BlockARMGEnoov: @@ -17728,12 +17847,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMLT, cmp) return true } + // match: (GT (CMP x (RSBconst [0] y))) + // result: (GT (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMGT, v0) + return true + } + // match: (GT (CMN x (RSBconst [0] y))) + // result: (GT (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMGT, v0) + return true + } + break + } // match: (GT (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (GTnoov (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17755,7 +17910,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17780,20 +17935,20 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -17803,21 +17958,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -17827,21 +17982,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -17851,21 +18006,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -17875,7 +18030,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17898,7 +18053,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17921,7 +18076,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17944,7 +18099,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -17972,20 +18127,20 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -17995,21 +18150,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -18019,21 +18174,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -18043,21 +18198,21 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMGTnoov, v0) return true @@ -18067,7 +18222,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18090,7 +18245,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18113,7 +18268,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GTnoov (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18131,12 +18286,37 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMGTnoov, v0) return true } + // match: (GT (CMPconst [0] l:(MULA x y a)) yes no) + // cond: l.Uses==1 + // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if auxIntToInt32(v_0.AuxInt) != 0 { + break + } + l := v_0.Args[0] + if l.Op != OpARMMULA { + break + } + a := l.Args[2] + x := l.Args[0] + y := l.Args[1] + if !(l.Uses == 1) { + break + } + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type) + v1.AddArg2(x, y) + v0.AddArg2(a, v1) + b.resetWithControl(BlockARMGTnoov, v0) + return true + } // match: (GT (CMPconst [0] l:(AND x y)) yes no) // cond: l.Uses==1 - // result: (GT (TST x y) yes no) + // result: (GTnoov (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18154,137 +18334,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } break } - // match: (GT (CMPconst [0] l:(MULA x y a)) yes no) - // cond: l.Uses==1 - // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no) - for b.Controls[0].Op == OpARMCMPconst { - v_0 := b.Controls[0] - if v_0.AuxInt != 0 { - break - } - l := v_0.Args[0] - if l.Op != OpARMMULA { - break - } - a := l.Args[2] - x := l.Args[0] - y := l.Args[1] - if !(l.Uses == 1) { - break - } - v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) - v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type) - v1.AddArg2(x, y) - v0.AddArg2(a, v1) - b.resetWithControl(BlockARMGTnoov, v0) - return true - } // match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no) // cond: l.Uses==1 - // result: (GT (TSTconst [c] x) yes no) + // result: (GTnoov (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftLL x y [c]) yes no) + // result: (GTnoov (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftRL x y [c]) yes no) + // result: (GTnoov (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftRA x y [c]) yes no) + // result: (GTnoov (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftLLreg x y z) yes no) + // result: (GTnoov (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18299,15 +18454,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftRLreg x y z) yes no) + // result: (GTnoov (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18322,15 +18477,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TSTshiftRAreg x y z) yes no) + // result: (GTnoov (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18345,15 +18500,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XOR x y)) yes no) // cond: l.Uses==1 - // result: (GT (TEQ x y) yes no) + // result: (GTnoov (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18371,112 +18526,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } break } // match: (GT (CMPconst [0] l:(XORconst [c] x)) yes no) // cond: l.Uses==1 - // result: (GT (TEQconst [c] x) yes no) + // result: (GTnoov (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftLL x y [c]) yes no) + // result: (GTnoov (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftRL x y [c]) yes no) + // result: (GTnoov (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftRA x y [c]) yes no) + // result: (GTnoov (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftLLreg x y z) yes no) + // result: (GTnoov (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18491,15 +18646,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftRLreg x y z) yes no) + // result: (GTnoov (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18514,15 +18669,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } // match: (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (GT (TEQshiftRAreg x y z) yes no) + // result: (GTnoov (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18537,7 +18692,7 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMGT, v0) + b.resetWithControl(BlockARMGTnoov, v0) return true } case BlockARMGTnoov: @@ -18660,7 +18815,7 @@ func rewriteBlockARM(b *Block) bool { for { cond := b.Controls[0] v0 := b.NewValue0(cond.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = 0 + v0.AuxInt = int32ToAuxInt(0) v0.AddArg(cond) b.resetWithControl(BlockARMNE, v0) return true @@ -18699,12 +18854,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMGE, cmp) return true } + // match: (LE (CMP x (RSBconst [0] y))) + // result: (LE (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMLE, v0) + return true + } + // match: (LE (CMN x (RSBconst [0] y))) + // result: (LE (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMLE, v0) + return true + } + break + } // match: (LE (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (LEnoov (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18726,7 +18917,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18751,20 +18942,20 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -18774,21 +18965,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -18798,21 +18989,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -18822,21 +19013,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -18846,7 +19037,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18869,7 +19060,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18892,7 +19083,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18915,7 +19106,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18943,7 +19134,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMN a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -18968,20 +19159,20 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -18991,21 +19182,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -19015,21 +19206,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -19039,21 +19230,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLEnoov, v0) return true @@ -19063,7 +19254,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19086,7 +19277,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19109,7 +19300,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LEnoov (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19129,10 +19320,10 @@ func rewriteBlockARM(b *Block) bool { } // match: (LE (CMPconst [0] l:(AND x y)) yes no) // cond: l.Uses==1 - // result: (LE (TST x y) yes no) + // result: (LEnoov (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19150,112 +19341,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } break } // match: (LE (CMPconst [0] l:(ANDconst [c] x)) yes no) // cond: l.Uses==1 - // result: (LE (TSTconst [c] x) yes no) + // result: (LEnoov (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftLL x y [c]) yes no) + // result: (LEnoov (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftRL x y [c]) yes no) + // result: (LEnoov (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftRA x y [c]) yes no) + // result: (LEnoov (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftLLreg x y z) yes no) + // result: (LEnoov (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19270,15 +19461,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftRLreg x y z) yes no) + // result: (LEnoov (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19293,15 +19484,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TSTshiftRAreg x y z) yes no) + // result: (LEnoov (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19316,15 +19507,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XOR x y)) yes no) // cond: l.Uses==1 - // result: (LE (TEQ x y) yes no) + // result: (LEnoov (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19342,112 +19533,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } break } // match: (LE (CMPconst [0] l:(XORconst [c] x)) yes no) // cond: l.Uses==1 - // result: (LE (TEQconst [c] x) yes no) + // result: (LEnoov (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftLL x y [c]) yes no) + // result: (LEnoov (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftRL x y [c]) yes no) + // result: (LEnoov (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftRA x y [c]) yes no) + // result: (LEnoov (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftLLreg x y z) yes no) + // result: (LEnoov (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19462,15 +19653,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftRLreg x y z) yes no) + // result: (LEnoov (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19485,15 +19676,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } // match: (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (LE (TEQshiftRAreg x y z) yes no) + // result: (LEnoov (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19508,7 +19699,7 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLE, v0) + b.resetWithControl(BlockARMLEnoov, v0) return true } case BlockARMLEnoov: @@ -19579,12 +19770,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMGT, cmp) return true } + // match: (LT (CMP x (RSBconst [0] y))) + // result: (LT (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMLT, v0) + return true + } + // match: (LT (CMN x (RSBconst [0] y))) + // result: (LT (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMLT, v0) + return true + } + break + } // match: (LT (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (LTnoov (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19606,7 +19833,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19631,20 +19858,20 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19654,21 +19881,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19678,21 +19905,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19702,21 +19929,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19726,7 +19953,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19749,7 +19976,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19772,7 +19999,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19795,7 +20022,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19823,7 +20050,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMN a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19848,20 +20075,20 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19871,21 +20098,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19895,21 +20122,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19919,21 +20146,21 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMLTnoov, v0) return true @@ -19943,7 +20170,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19966,7 +20193,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -19989,7 +20216,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LTnoov (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20009,10 +20236,10 @@ func rewriteBlockARM(b *Block) bool { } // match: (LT (CMPconst [0] l:(AND x y)) yes no) // cond: l.Uses==1 - // result: (LT (TST x y) yes no) + // result: (LTnoov (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20030,112 +20257,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } break } // match: (LT (CMPconst [0] l:(ANDconst [c] x)) yes no) // cond: l.Uses==1 - // result: (LT (TSTconst [c] x) yes no) + // result: (LTnoov (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftLL x y [c]) yes no) + // result: (LTnoov (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftRL x y [c]) yes no) + // result: (LTnoov (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftRA x y [c]) yes no) + // result: (LTnoov (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftLLreg x y z) yes no) + // result: (LTnoov (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20150,15 +20377,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftRLreg x y z) yes no) + // result: (LTnoov (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20173,15 +20400,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TSTshiftRAreg x y z) yes no) + // result: (LTnoov (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20196,15 +20423,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XOR x y)) yes no) // cond: l.Uses==1 - // result: (LT (TEQ x y) yes no) + // result: (LTnoov (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20222,112 +20449,112 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } break } // match: (LT (CMPconst [0] l:(XORconst [c] x)) yes no) // cond: l.Uses==1 - // result: (LT (TEQconst [c] x) yes no) + // result: (LTnoov (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftLL x y [c]) yes no) + // result: (LTnoov (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftRL x y [c]) yes no) + // result: (LTnoov (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftRA x y [c]) yes no) + // result: (LTnoov (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftLLreg x y z) yes no) + // result: (LTnoov (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20342,15 +20569,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftRLreg x y z) yes no) + // result: (LTnoov (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20365,15 +20592,15 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } // match: (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) // cond: l.Uses==1 - // result: (LT (TEQshiftRAreg x y z) yes no) + // result: (LTnoov (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20388,7 +20615,7 @@ func rewriteBlockARM(b *Block) bool { } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) v0.AddArg3(x, y, z) - b.resetWithControl(BlockARMLT, v0) + b.resetWithControl(BlockARMLTnoov, v0) return true } case BlockARMLTnoov: @@ -20430,7 +20657,7 @@ func rewriteBlockARM(b *Block) bool { // result: (EQ cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20445,7 +20672,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20460,7 +20687,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LT cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20475,7 +20702,7 @@ func rewriteBlockARM(b *Block) bool { // result: (ULT cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20490,7 +20717,7 @@ func rewriteBlockARM(b *Block) bool { // result: (LE cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20505,7 +20732,7 @@ func rewriteBlockARM(b *Block) bool { // result: (ULE cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20520,7 +20747,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GT cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20535,7 +20762,7 @@ func rewriteBlockARM(b *Block) bool { // result: (UGT cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20550,7 +20777,7 @@ func rewriteBlockARM(b *Block) bool { // result: (GE cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20565,7 +20792,7 @@ func rewriteBlockARM(b *Block) bool { // result: (UGE cc yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } v_0_0 := v_0.Args[0] @@ -20609,12 +20836,48 @@ func rewriteBlockARM(b *Block) bool { b.resetWithControl(BlockARMNE, cmp) return true } + // match: (NE (CMP x (RSBconst [0] y))) + // result: (NE (CMN x y)) + for b.Controls[0].Op == OpARMCMP { + v_0 := b.Controls[0] + _ = v_0.Args[1] + x := v_0.Args[0] + v_0_1 := v_0.Args[1] + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + break + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMNE, v0) + return true + } + // match: (NE (CMN x (RSBconst [0] y))) + // result: (NE (CMP x y)) + for b.Controls[0].Op == OpARMCMN { + v_0 := b.Controls[0] + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpARMRSBconst || auxIntToInt32(v_0_1.AuxInt) != 0 { + continue + } + y := v_0_1.Args[0] + v0 := b.NewValue0(v_0.Pos, OpARMCMP, types.TypeFlags) + v0.AddArg2(x, y) + b.resetWithControl(BlockARMNE, v0) + return true + } + break + } // match: (NE (CMPconst [0] l:(SUB x y)) yes no) // cond: l.Uses==1 // result: (NE (CMP x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20636,7 +20899,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMP a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20661,20 +20924,20 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMNE, v0) return true @@ -20684,21 +20947,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20708,21 +20971,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20732,21 +20995,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMSUBshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMPshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20756,7 +21019,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20779,7 +21042,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20802,7 +21065,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMPshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20825,7 +21088,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMN x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20853,7 +21116,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMN a (MUL <x.Type> x y)) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20878,20 +21141,20 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMNE, v0) return true @@ -20901,21 +21164,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20925,21 +21188,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20949,21 +21212,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMADDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMCMNshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -20973,7 +21236,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -20996,7 +21259,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21019,7 +21282,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (CMNshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21042,7 +21305,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TST x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21070,20 +21333,20 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMNE, v0) return true @@ -21093,21 +21356,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21117,21 +21380,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21141,21 +21404,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMANDshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21165,7 +21428,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21188,7 +21451,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21211,7 +21474,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TSTshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21234,7 +21497,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQ x y) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21262,20 +21525,20 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQconst [c] x) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORconst { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg(x) b.resetWithControl(BlockARMNE, v0) return true @@ -21285,21 +21548,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftLL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftLL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21309,21 +21572,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftRL x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRL { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21333,21 +21596,21 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftRA x y [c]) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] if l.Op != OpARMXORshiftRA { break } - c := l.AuxInt + c := auxIntToInt32(l.AuxInt) y := l.Args[1] x := l.Args[0] if !(l.Uses == 1) { break } v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int32ToAuxInt(c) v0.AddArg2(x, y) b.resetWithControl(BlockARMNE, v0) return true @@ -21357,7 +21620,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftLLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21380,7 +21643,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftRLreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] @@ -21403,7 +21666,7 @@ func rewriteBlockARM(b *Block) bool { // result: (NE (TEQshiftRAreg x y z) yes no) for b.Controls[0].Op == OpARMCMPconst { v_0 := b.Controls[0] - if v_0.AuxInt != 0 { + if auxIntToInt32(v_0.AuxInt) != 0 { break } l := v_0.Args[0] diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index 0fb86b6bdd..5d5e526add 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -424,20 +424,38 @@ func rewriteValueARM64(v *Value) bool { case OpAtomicAdd64Variant: v.Op = OpARM64LoweredAtomicAdd64Variant return true + case OpAtomicAnd32: + return rewriteValueARM64_OpAtomicAnd32(v) + case OpAtomicAnd32Variant: + return rewriteValueARM64_OpAtomicAnd32Variant(v) case OpAtomicAnd8: return rewriteValueARM64_OpAtomicAnd8(v) + case OpAtomicAnd8Variant: + return rewriteValueARM64_OpAtomicAnd8Variant(v) case OpAtomicCompareAndSwap32: v.Op = OpARM64LoweredAtomicCas32 return true + case OpAtomicCompareAndSwap32Variant: + v.Op = OpARM64LoweredAtomicCas32Variant + return true case OpAtomicCompareAndSwap64: v.Op = OpARM64LoweredAtomicCas64 return true + case OpAtomicCompareAndSwap64Variant: + v.Op = OpARM64LoweredAtomicCas64Variant + return true case OpAtomicExchange32: v.Op = OpARM64LoweredAtomicExchange32 return true + case OpAtomicExchange32Variant: + v.Op = OpARM64LoweredAtomicExchange32Variant + return true case OpAtomicExchange64: v.Op = OpARM64LoweredAtomicExchange64 return true + case OpAtomicExchange64Variant: + v.Op = OpARM64LoweredAtomicExchange64Variant + return true case OpAtomicLoad32: v.Op = OpARM64LDARW return true @@ -450,8 +468,14 @@ func rewriteValueARM64(v *Value) bool { case OpAtomicLoadPtr: v.Op = OpARM64LDAR return true + case OpAtomicOr32: + return rewriteValueARM64_OpAtomicOr32(v) + case OpAtomicOr32Variant: + return rewriteValueARM64_OpAtomicOr32Variant(v) case OpAtomicOr8: return rewriteValueARM64_OpAtomicOr8(v) + case OpAtomicOr8Variant: + return rewriteValueARM64_OpAtomicOr8Variant(v) case OpAtomicStore32: v.Op = OpARM64STLRW return true @@ -1065,7 +1089,7 @@ func rewriteValueARM64_OpARM64ADCSflags(v *Value) bool { break } v_2_0 := v_2.Args[0] - if v_2_0.Op != OpARM64ADDSconstflags || v_2_0.AuxInt != -1 { + if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 { break } v_2_0_0 := v_2_0.Args[0] @@ -1086,11 +1110,11 @@ func rewriteValueARM64_OpARM64ADCSflags(v *Value) bool { break } v_2_0 := v_2.Args[0] - if v_2_0.Op != OpARM64ADDSconstflags || v_2_0.AuxInt != -1 { + if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 { break } v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpARM64MOVDconst || v_2_0_0.AuxInt != 0 { + if v_2_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 { break } v.reset(OpARM64ADDSflags) @@ -1112,9 +1136,9 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64ADDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -1593,7 +1617,7 @@ func rewriteValueARM64_OpARM64ADDconst(v *Value) bool { // match: (ADDconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } x := v_0 @@ -1603,40 +1627,40 @@ func rewriteValueARM64_OpARM64ADDconst(v *Value) bool { // match: (ADDconst [c] (MOVDconst [d])) // result: (MOVDconst [c+d]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c + d + v.AuxInt = int64ToAuxInt(c + d) return true } // match: (ADDconst [c] (ADDconst [d] x)) // result: (ADDconst [c+d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64ADDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ADDconst) - v.AuxInt = c + d + v.AuxInt = int64ToAuxInt(c + d) v.AddArg(x) return true } // match: (ADDconst [c] (SUBconst [d] x)) // result: (ADDconst [c-d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64SUBconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ADDconst) - v.AuxInt = c - d + v.AuxInt = int64ToAuxInt(c - d) v.AddArg(x) return true } @@ -1882,9 +1906,9 @@ func rewriteValueARM64_OpARM64AND(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64ANDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -1988,17 +2012,17 @@ func rewriteValueARM64_OpARM64ANDconst(v *Value) bool { // match: (ANDconst [0] _) // result: (MOVDconst [0]) for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (ANDconst [-1] x) // result: x for { - if v.AuxInt != -1 { + if auxIntToInt64(v.AuxInt) != -1 { break } x := v_0 @@ -2008,65 +2032,65 @@ func rewriteValueARM64_OpARM64ANDconst(v *Value) bool { // match: (ANDconst [c] (MOVDconst [d])) // result: (MOVDconst [c&d]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c & d + v.AuxInt = int64ToAuxInt(c & d) return true } // match: (ANDconst [c] (ANDconst [d] x)) // result: (ANDconst [c&d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64ANDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & d + v.AuxInt = int64ToAuxInt(c & d) v.AddArg(x) return true } // match: (ANDconst [c] (MOVWUreg x)) // result: (ANDconst [c&(1<<32-1)] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVWUreg { break } x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<32 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<32 - 1)) v.AddArg(x) return true } // match: (ANDconst [c] (MOVHUreg x)) // result: (ANDconst [c&(1<<16-1)] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVHUreg { break } x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<16 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<16 - 1)) v.AddArg(x) return true } // match: (ANDconst [c] (MOVBUreg x)) // result: (ANDconst [c&(1<<8-1)] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVBUreg { break } x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<8 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<8 - 1)) v.AddArg(x) return true } @@ -2280,9 +2304,9 @@ func rewriteValueARM64_OpARM64BIC(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64ANDconst) - v.AuxInt = ^c + v.AuxInt = int64ToAuxInt(^c) v.AddArg(x) return true } @@ -2294,7 +2318,7 @@ func rewriteValueARM64_OpARM64BIC(v *Value) bool { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (BIC x0 x1:(SLLconst [c] y)) @@ -2475,9 +2499,9 @@ func rewriteValueARM64_OpARM64CMN(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64CMNconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -2555,16 +2579,16 @@ func rewriteValueARM64_OpARM64CMNW(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (CMNW x (MOVDconst [c])) - // result: (CMNWconst [c] x) + // result: (CMNWconst [int32(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64CMNWconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -2726,9 +2750,9 @@ func rewriteValueARM64_OpARM64CMP(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64CMPconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -2738,11 +2762,11 @@ func rewriteValueARM64_OpARM64CMP(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 v.reset(OpARM64InvertFlags) v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v0.AuxInt = c + v0.AuxInt = int64ToAuxInt(c) v0.AddArg(x) v.AddArg(v0) return true @@ -3372,18 +3396,22 @@ func rewriteValueARM64_OpARM64DIV(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (DIV (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [c/d]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = c / d + v.AuxInt = int64ToAuxInt(c / d) return true } return false @@ -3392,18 +3420,22 @@ func rewriteValueARM64_OpARM64DIVW(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (DIVW (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(int32(c)/int32(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int32(c) / int32(d)) + v.AuxInt = int64ToAuxInt(int64(int32(c) / int32(d))) return true } return false @@ -3418,9 +3450,9 @@ func rewriteValueARM64_OpARM64EON(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64XORconst) - v.AuxInt = ^c + v.AuxInt = int64ToAuxInt(^c) v.AddArg(x) return true } @@ -3432,7 +3464,7 @@ func rewriteValueARM64_OpARM64EON(v *Value) bool { break } v.reset(OpARM64MOVDconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (EON x0 x1:(SLLconst [c] y)) @@ -3868,7 +3900,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool { } // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3884,7 +3916,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool { } v.reset(OpARM64FMOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3999,7 +4031,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool { } // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4016,7 +4048,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool { } v.reset(OpARM64FMOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -4131,7 +4163,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool { } // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4147,7 +4179,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool { } v.reset(OpARM64FMOVSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4262,7 +4294,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool { } // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4279,7 +4311,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool { } v.reset(OpARM64FMOVSstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -4858,7 +4890,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { for { a := v_0 x := v_1 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != -1 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 { break } v.reset(OpARM64SUB) @@ -4869,7 +4901,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { // result: a for { a := v_0 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != 0 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 { break } v.copyOf(a) @@ -4880,7 +4912,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { for { a := v_0 x := v_1 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != 1 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 { break } v.reset(OpARM64ADD) @@ -4888,143 +4920,143 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { return true } // match: (MADD a x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (ADDshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (ADDshiftLL a x [log64(c)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MADD a x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && c>=3 - // result: (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && c>=3 + // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c-1) && c >= 3) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c-1) && c >= 3) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && c>=7 - // result: (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && c>=7 + // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c+1) && c >= 7) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c+1) && c >= 7) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -5033,7 +5065,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { // result: (SUB a x) for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != -1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 { break } x := v_2 @@ -5045,7 +5077,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { // result: a for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 0 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 { break } v.copyOf(a) @@ -5055,7 +5087,7 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { // result: (ADD a x) for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { break } x := v_2 @@ -5064,143 +5096,143 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { return true } // match: (MADD a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c) - // result: (ADDshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (ADDshiftLL a x [log64(c)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c-1) && c>=3 - // result: (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && c>=3 + // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c-1) && c >= 3) { + if !(isPowerOfTwo64(c-1) && c >= 3) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c+1) && c>=7 - // result: (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && c>=7 + // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c+1) && c >= 7) { + if !(isPowerOfTwo64(c+1) && c >= 7) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADD a (MOVDconst [c]) x) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -5211,11 +5243,11 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARM64ADDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARM64MUL, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -5228,13 +5260,13 @@ func rewriteValueARM64_OpARM64MADD(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if v_2.Op != OpARM64MOVDconst { break } - d := v_2.AuxInt + d := auxIntToInt64(v_2.AuxInt) v.reset(OpARM64ADDconst) - v.AuxInt = c * d + v.AuxInt = int64ToAuxInt(c * d) v.AddArg(a) return true } @@ -5254,7 +5286,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == -1) { break } @@ -5270,7 +5302,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == 0) { break } @@ -5286,7 +5318,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == 1) { break } @@ -5295,143 +5327,143 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { return true } // match: (MADDW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (ADDshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (ADDshiftLL a x [log64(c)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && int32(c)>=3 - // result: (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && int32(c)>=3 + // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && int32(c)>=7 - // result: (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && int32(c)>=7 + // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -5444,7 +5476,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 if !(int32(c) == -1) { break @@ -5461,7 +5493,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 0) { break } @@ -5476,7 +5508,7 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 if !(int32(c) == 1) { break @@ -5486,143 +5518,143 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c) - // result: (ADDshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (ADDshiftLL a x [log64(c)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c-1) && int32(c)>=3 - // result: (ADD a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && int32(c)>=3 + // result: (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c+1) && int32(c)>=7 - // result: (SUB a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && int32(c)>=7 + // result: (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MADDW a (MOVDconst [c]) x) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -5633,11 +5665,11 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARM64ADDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARM64MULW, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -5650,13 +5682,13 @@ func rewriteValueARM64_OpARM64MADDW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if v_2.Op != OpARM64MOVDconst { break } - d := v_2.AuxInt + d := auxIntToInt64(v_2.AuxInt) v.reset(OpARM64ADDconst) - v.AuxInt = int64(int32(c) * int32(d)) + v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d))) v.AddArg(a) return true } @@ -5671,7 +5703,7 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != -1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 { continue } v.copyOf(x) @@ -5683,11 +5715,11 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { // result: (MOVDconst [0]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 0 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 { continue } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } break @@ -5697,7 +5729,7 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { continue } v.reset(OpARM64NEG) @@ -5707,21 +5739,21 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (NEG (SLLconst <x.Type> [log2(c)] x)) + // cond: isPowerOfTwo64(c) + // result: (NEG (SLLconst <x.Type> [log64(c)] x)) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int64ToAuxInt(log64(c)) v0.AddArg(x) v.AddArg(v0) return true @@ -5729,21 +5761,21 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && c >= 3 - // result: (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && c >= 3 + // result: (NEG (ADDshiftLL <x.Type> x x [log64(c-1)])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c-1) && c >= 3) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c-1) && c >= 3) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -5751,21 +5783,21 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && c >= 7 - // result: (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && c >= 7 + // result: (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c+1) && c >= 7) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c+1) && c >= 7) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v1.AddArg(x) v0.AddArg2(v1, x) @@ -5775,23 +5807,23 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2])) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { continue } v.reset(OpARM64SLLconst) v.Type = x.Type - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -5799,23 +5831,23 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int64ToAuxInt(log64(c / 5)) v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int64ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg(v0) @@ -5824,23 +5856,23 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3])) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { continue } v.reset(OpARM64SLLconst) v.Type = x.Type - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -5848,23 +5880,23 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { break } // match: (MNEG x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int64ToAuxInt(log64(c / 9)) v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int64ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg(v0) @@ -5879,13 +5911,13 @@ func rewriteValueARM64_OpARM64MNEG(v *Value) bool { if v_0.Op != OpARM64MOVDconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { continue } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = -c * d + v.AuxInt = int64ToAuxInt(-c * d) return true } break @@ -5905,7 +5937,7 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == -1) { continue } @@ -5922,12 +5954,12 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 0) { continue } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } break @@ -5941,7 +5973,7 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 1) { continue } @@ -5952,21 +5984,21 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (NEG (SLLconst <x.Type> [log2(c)] x)) + // cond: isPowerOfTwo64(c) + // result: (NEG (SLLconst <x.Type> [log64(c)] x)) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c) + v0.AuxInt = int64ToAuxInt(log64(c)) v0.AddArg(x) v.AddArg(v0) return true @@ -5974,21 +6006,21 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (NEG (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && int32(c) >= 3 + // result: (NEG (ADDshiftLL <x.Type> x x [log64(c-1)])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -5996,21 +6028,21 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && int32(c) >= 7 + // result: (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v1.AddArg(x) v0.AddArg2(v1, x) @@ -6020,23 +6052,23 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (SLLconst <x.Type> [log2(c/3)] (SUBshiftLL <x.Type> x x [2])) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) v.Type = x.Type - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -6044,23 +6076,23 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (NEG (SLLconst <x.Type> [log2(c/5)] (ADDshiftLL <x.Type> x x [2]))) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c / 5) + v0.AuxInt = int64ToAuxInt(log64(c / 5)) v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v1.AuxInt = 2 + v1.AuxInt = int64ToAuxInt(2) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg(v0) @@ -6069,23 +6101,23 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (SLLconst <x.Type> [log2(c/7)] (SUBshiftLL <x.Type> x x [3])) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) v.Type = x.Type - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -6093,23 +6125,23 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { break } // match: (MNEGW x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (NEG (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3]))) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { continue } v.reset(OpARM64NEG) v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type) - v0.AuxInt = log2(c / 9) + v0.AuxInt = int64ToAuxInt(log64(c / 9)) v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v1.AuxInt = 3 + v1.AuxInt = int64ToAuxInt(3) v1.AddArg2(x, x) v0.AddArg(v1) v.AddArg(v0) @@ -6124,13 +6156,13 @@ func rewriteValueARM64_OpARM64MNEGW(v *Value) bool { if v_0.Op != OpARM64MOVDconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { continue } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = -int64(int32(c) * int32(d)) + v.AuxInt = int64ToAuxInt(-int64(int32(c) * int32(d))) return true } break @@ -6141,18 +6173,22 @@ func rewriteValueARM64_OpARM64MOD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOD (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [c%d]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = c % d + v.AuxInt = int64ToAuxInt(c % d) return true } return false @@ -6161,18 +6197,22 @@ func rewriteValueARM64_OpARM64MODW(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MODW (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(int32(c)%int32(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int32(c) % int32(d)) + v.AuxInt = int64ToAuxInt(int64(int32(c) % int32(d))) return true } return false @@ -6224,7 +6264,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool { } // match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6240,7 +6280,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool { } v.reset(OpARM64MOVBUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -6380,10 +6420,10 @@ func rewriteValueARM64_OpARM64MOVBUreg(v *Value) bool { if v_0.Op != OpARM64ANDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<8 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<8 - 1)) v.AddArg(x) return true } @@ -6393,9 +6433,9 @@ func rewriteValueARM64_OpARM64MOVBUreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint8(c)) + v.AuxInt = int64ToAuxInt(int64(uint8(c))) return true } // match: (MOVBUreg x) @@ -6493,7 +6533,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool { } // match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6509,7 +6549,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool { } v.reset(OpARM64MOVBload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -6636,9 +6676,9 @@ func rewriteValueARM64_OpARM64MOVBreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int8(c)) + v.AuxInt = int64ToAuxInt(int64(int8(c))) return true } // match: (MOVBreg (SLLconst [lc] x)) @@ -6710,7 +6750,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6727,7 +6767,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool { } v.reset(OpARM64MOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -8542,7 +8582,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool { } // match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8558,7 +8598,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool { } v.reset(OpARM64MOVBstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -8788,7 +8828,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool { } // match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8804,7 +8844,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool { } v.reset(OpARM64MOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -8991,9 +9031,9 @@ func rewriteValueARM64_OpARM64MOVDreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) return true } return false @@ -9085,7 +9125,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool { } // match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9102,7 +9142,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool { } v.reset(OpARM64MOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -9277,7 +9317,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool { } // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9293,7 +9333,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool { } v.reset(OpARM64MOVDstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -9587,7 +9627,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool { } // match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9603,7 +9643,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool { } v.reset(OpARM64MOVHUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -9874,10 +9914,10 @@ func rewriteValueARM64_OpARM64MOVHUreg(v *Value) bool { if v_0.Op != OpARM64ANDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<16 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<16 - 1)) v.AddArg(x) return true } @@ -9887,9 +9927,9 @@ func rewriteValueARM64_OpARM64MOVHUreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint16(c)) + v.AuxInt = int64ToAuxInt(int64(uint16(c))) return true } // match: (MOVHUreg (SLLconst [sc] x)) @@ -9994,7 +10034,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool { } // match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10010,7 +10050,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool { } v.reset(OpARM64MOVHload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -10301,9 +10341,9 @@ func rewriteValueARM64_OpARM64MOVHreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int16(c)) + v.AuxInt = int64ToAuxInt(int64(int16(c))) return true } // match: (MOVHreg (SLLconst [lc] x)) @@ -10395,7 +10435,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool { } // match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10412,7 +10452,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool { } v.reset(OpARM64MOVHstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -11232,7 +11272,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool { } // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -11248,7 +11288,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool { } v.reset(OpARM64MOVHstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -11554,7 +11594,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool { } // match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVQstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -11570,7 +11610,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool { } v.reset(OpARM64MOVQstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -11659,7 +11699,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool { } // match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -11675,7 +11715,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool { } v.reset(OpARM64MOVWUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -11971,10 +12011,10 @@ func rewriteValueARM64_OpARM64MOVWUreg(v *Value) bool { if v_0.Op != OpARM64ANDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ANDconst) - v.AuxInt = c & (1<<32 - 1) + v.AuxInt = int64ToAuxInt(c & (1<<32 - 1)) v.AddArg(x) return true } @@ -11984,9 +12024,9 @@ func rewriteValueARM64_OpARM64MOVWUreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint32(c)) + v.AuxInt = int64ToAuxInt(int64(uint32(c))) return true } // match: (MOVWUreg (SLLconst [sc] x)) @@ -12091,7 +12131,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool { } // match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -12107,7 +12147,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool { } v.reset(OpARM64MOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -12456,9 +12496,9 @@ func rewriteValueARM64_OpARM64MOVWreg(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int32(c)) + v.AuxInt = int64ToAuxInt(int64(int32(c))) return true } // match: (MOVWreg (SLLconst [lc] x)) @@ -12567,7 +12607,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -12584,7 +12624,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool { } v.reset(OpARM64MOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -13074,7 +13114,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool { } // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -13090,7 +13130,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool { } v.reset(OpARM64MOVWstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -13346,7 +13386,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { for { a := v_0 x := v_1 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != -1 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 { break } v.reset(OpARM64ADD) @@ -13357,7 +13397,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { // result: a for { a := v_0 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != 0 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 { break } v.copyOf(a) @@ -13368,7 +13408,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { for { a := v_0 x := v_1 - if v_2.Op != OpARM64MOVDconst || v_2.AuxInt != 1 { + if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 { break } v.reset(OpARM64SUB) @@ -13376,143 +13416,143 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { return true } // match: (MSUB a x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (SUBshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (SUBshiftLL a x [log64(c)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && c>=3 - // result: (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && c>=3 + // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c-1) && c >= 3) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c-1) && c >= 3) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && c>=7 - // result: (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && c>=7 + // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c+1) && c >= 7) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c+1) && c >= 7) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -13521,7 +13561,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { // result: (ADD a x) for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != -1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 { break } x := v_2 @@ -13533,7 +13573,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { // result: a for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 0 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 { break } v.copyOf(a) @@ -13543,7 +13583,7 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { // result: (SUB a x) for { a := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { break } x := v_2 @@ -13552,143 +13592,143 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c) - // result: (SUBshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (SUBshiftLL a x [log64(c)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c-1) && c>=3 - // result: (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && c>=3 + // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c-1) && c >= 3) { + if !(isPowerOfTwo64(c-1) && c >= 3) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c+1) && c>=7 - // result: (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && c>=7 + // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c+1) && c >= 7) { + if !(isPowerOfTwo64(c+1) && c >= 7) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUB a (MOVDconst [c]) x) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -13699,11 +13739,11 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARM64ADDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARM64MNEG, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -13716,13 +13756,13 @@ func rewriteValueARM64_OpARM64MSUB(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if v_2.Op != OpARM64MOVDconst { break } - d := v_2.AuxInt + d := auxIntToInt64(v_2.AuxInt) v.reset(OpARM64SUBconst) - v.AuxInt = c * d + v.AuxInt = int64ToAuxInt(c * d) v.AddArg(a) return true } @@ -13742,7 +13782,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == -1) { break } @@ -13758,7 +13798,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == 0) { break } @@ -13774,7 +13814,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt + c := auxIntToInt64(v_2.AuxInt) if !(int32(c) == 1) { break } @@ -13783,143 +13823,143 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (SUBshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (SUBshiftLL a x [log64(c)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && int32(c)>=3 - // result: (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && int32(c)>=3 + // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && int32(c)>=7 - // result: (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && int32(c)>=7 + // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + c := auxIntToInt64(v_2.AuxInt) + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 x := v_1 if v_2.Op != OpARM64MOVDconst { break } - c := v_2.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + c := auxIntToInt64(v_2.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -13932,7 +13972,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 if !(int32(c) == -1) { break @@ -13949,7 +13989,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 0) { break } @@ -13964,7 +14004,7 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 if !(int32(c) == 1) { break @@ -13974,143 +14014,143 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c) - // result: (SUBshiftLL a x [log2(c)]) + // cond: isPowerOfTwo64(c) + // result: (SUBshiftLL a x [log64(c)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg2(a, x) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c-1) && int32(c)>=3 - // result: (SUB a (ADDshiftLL <x.Type> x x [log2(c-1)])) + // cond: isPowerOfTwo64(c-1) && int32(c)>=3 + // result: (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { break } v.reset(OpARM64SUB) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = log2(c - 1) + v0.AuxInt = int64ToAuxInt(log64(c - 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: isPowerOfTwo(c+1) && int32(c)>=7 - // result: (ADD a (SUBshiftLL <x.Type> x x [log2(c+1)])) + // cond: isPowerOfTwo64(c+1) && int32(c)>=7 + // result: (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)])) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { break } v.reset(OpARM64ADD) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = log2(c + 1) + v0.AuxInt = int64ToAuxInt(log64(c + 1)) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log2(c/3)]) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log2(c/5)]) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log2(c/7)]) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { break } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true } // match: (MSUBW a (MOVDconst [c]) x) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log2(c/9)]) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)]) for { a := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) x := v_2 - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { break } v.reset(OpARM64SUBshiftLL) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg2(a, v0) return true @@ -14121,11 +14161,11 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) x := v_1 y := v_2 v.reset(OpARM64ADDconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v0 := b.NewValue0(v.Pos, OpARM64MNEGW, x.Type) v0.AddArg2(x, y) v.AddArg(v0) @@ -14138,13 +14178,13 @@ func rewriteValueARM64_OpARM64MSUBW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if v_2.Op != OpARM64MOVDconst { break } - d := v_2.AuxInt + d := auxIntToInt64(v_2.AuxInt) v.reset(OpARM64SUBconst) - v.AuxInt = int64(int32(c) * int32(d)) + v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d))) v.AddArg(a) return true } @@ -14174,7 +14214,7 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != -1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 { continue } v.reset(OpARM64NEG) @@ -14187,11 +14227,11 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { // result: (MOVDconst [0]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 0 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 { continue } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } break @@ -14201,7 +14241,7 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { continue } v.copyOf(x) @@ -14210,60 +14250,60 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { break } // match: (MUL x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (SLLconst [log2(c)] x) + // cond: isPowerOfTwo64(c) + // result: (SLLconst [log64(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } break } // match: (MUL x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && c >= 3 - // result: (ADDshiftLL x x [log2(c-1)]) + // cond: isPowerOfTwo64(c-1) && c >= 3 + // result: (ADDshiftLL x x [log64(c-1)]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c-1) && c >= 3) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c-1) && c >= 3) { continue } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c - 1) + v.AuxInt = int64ToAuxInt(log64(c - 1)) v.AddArg2(x, x) return true } break } // match: (MUL x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && c >= 7 - // result: (ADDshiftLL (NEG <x.Type> x) x [log2(c+1)]) + // cond: isPowerOfTwo64(c+1) && c >= 7 + // result: (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c+1) && c >= 7) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c+1) && c >= 7) { continue } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c + 1) + v.AuxInt = int64ToAuxInt(log64(c + 1)) v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x) v.AddArg2(v0, x) @@ -14272,22 +14312,22 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { break } // match: (MUL x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) - // result: (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) + // result: (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 1 + v0.AuxInt = int64ToAuxInt(1) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14295,22 +14335,22 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { break } // match: (MUL x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) - // result: (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) + // result: (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14318,22 +14358,22 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { break } // match: (MUL x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) - // result: (SLLconst [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) + // result: (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v1.AddArg(x) v0.AddArg2(v1, x) @@ -14343,22 +14383,22 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { break } // match: (MUL x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) - // result: (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) + // result: (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14372,13 +14412,13 @@ func rewriteValueARM64_OpARM64MUL(v *Value) bool { if v_0.Op != OpARM64MOVDconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { continue } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c * d + v.AuxInt = int64ToAuxInt(c * d) return true } break @@ -14413,7 +14453,7 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == -1) { continue } @@ -14431,12 +14471,12 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 0) { continue } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } break @@ -14450,7 +14490,7 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(int32(c) == 1) { continue } @@ -14460,60 +14500,60 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { break } // match: (MULW x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (SLLconst [log2(c)] x) + // cond: isPowerOfTwo64(c) + // result: (SLLconst [log64(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } break } // match: (MULW x (MOVDconst [c])) - // cond: isPowerOfTwo(c-1) && int32(c) >= 3 - // result: (ADDshiftLL x x [log2(c-1)]) + // cond: isPowerOfTwo64(c-1) && int32(c) >= 3 + // result: (ADDshiftLL x x [log64(c-1)]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c-1) && int32(c) >= 3) { continue } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c - 1) + v.AuxInt = int64ToAuxInt(log64(c - 1)) v.AddArg2(x, x) return true } break } // match: (MULW x (MOVDconst [c])) - // cond: isPowerOfTwo(c+1) && int32(c) >= 7 - // result: (ADDshiftLL (NEG <x.Type> x) x [log2(c+1)]) + // cond: isPowerOfTwo64(c+1) && int32(c) >= 7 + // result: (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c+1) && int32(c) >= 7) { continue } v.reset(OpARM64ADDshiftLL) - v.AuxInt = log2(c + 1) + v.AuxInt = int64ToAuxInt(log64(c + 1)) v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v0.AddArg(x) v.AddArg2(v0, x) @@ -14522,22 +14562,22 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { break } // match: (MULW x (MOVDconst [c])) - // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) - // result: (SLLconst [log2(c/3)] (ADDshiftLL <x.Type> x x [1])) + // cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) + // result: (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 3) + v.AuxInt = int64ToAuxInt(log64(c / 3)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 1 + v0.AuxInt = int64ToAuxInt(1) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14545,22 +14585,22 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { break } // match: (MULW x (MOVDconst [c])) - // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) - // result: (SLLconst [log2(c/5)] (ADDshiftLL <x.Type> x x [2])) + // cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) + // result: (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 5) + v.AuxInt = int64ToAuxInt(log64(c / 5)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 2 + v0.AuxInt = int64ToAuxInt(2) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14568,22 +14608,22 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { break } // match: (MULW x (MOVDconst [c])) - // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) - // result: (SLLconst [log2(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) + // cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) + // result: (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 7) + v.AuxInt = int64ToAuxInt(log64(c / 7)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type) v1.AddArg(x) v0.AddArg2(v1, x) @@ -14593,22 +14633,22 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { break } // match: (MULW x (MOVDconst [c])) - // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) - // result: (SLLconst [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) + // cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) + // result: (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3])) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt - if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) { continue } v.reset(OpARM64SLLconst) - v.AuxInt = log2(c / 9) + v.AuxInt = int64ToAuxInt(log64(c / 9)) v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type) - v0.AuxInt = 3 + v0.AuxInt = int64ToAuxInt(3) v0.AddArg2(x, x) v.AddArg(v0) return true @@ -14622,13 +14662,13 @@ func rewriteValueARM64_OpARM64MULW(v *Value) bool { if v_0.Op != OpARM64MOVDconst { continue } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { continue } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(int32(c) * int32(d)) + v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d))) return true } break @@ -14655,9 +14695,9 @@ func rewriteValueARM64_OpARM64MVN(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = ^c + v.AuxInt = int64ToAuxInt(^c) return true } // match: (MVN x:(SLLconst [c] y)) @@ -14796,9 +14836,9 @@ func rewriteValueARM64_OpARM64NEG(v *Value) bool { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = -c + v.AuxInt = int64ToAuxInt(-c) return true } // match: (NEG x:(SLLconst [c] y)) @@ -14944,9 +14984,9 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64ORconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -16938,9 +16978,9 @@ func rewriteValueARM64_OpARM64ORN(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64ORconst) - v.AuxInt = ^c + v.AuxInt = int64ToAuxInt(^c) v.AddArg(x) return true } @@ -16952,7 +16992,7 @@ func rewriteValueARM64_OpARM64ORN(v *Value) bool { break } v.reset(OpARM64MOVDconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (ORN x0 x1:(SLLconst [c] y)) @@ -17127,7 +17167,7 @@ func rewriteValueARM64_OpARM64ORconst(v *Value) bool { // match: (ORconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } x := v_0 @@ -17137,36 +17177,36 @@ func rewriteValueARM64_OpARM64ORconst(v *Value) bool { // match: (ORconst [-1] _) // result: (MOVDconst [-1]) for { - if v.AuxInt != -1 { + if auxIntToInt64(v.AuxInt) != -1 { break } v.reset(OpARM64MOVDconst) - v.AuxInt = -1 + v.AuxInt = int64ToAuxInt(-1) return true } // match: (ORconst [c] (MOVDconst [d])) // result: (MOVDconst [c|d]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c | d + v.AuxInt = int64ToAuxInt(c | d) return true } // match: (ORconst [c] (ORconst [d] x)) // result: (ORconst [c|d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64ORconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ORconst) - v.AuxInt = c | d + v.AuxInt = int64ToAuxInt(c | d) v.AddArg(x) return true } @@ -19064,7 +19104,7 @@ func rewriteValueARM64_OpARM64SBCSflags(v *Value) bool { break } v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpARM64MOVDconst || v_2_0_0.AuxInt != 0 { + if v_2_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 { break } v.reset(OpARM64SUBSflags) @@ -19083,9 +19123,9 @@ func rewriteValueARM64_OpARM64SLL(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64SLLconst) - v.AuxInt = c & 63 + v.AuxInt = int64ToAuxInt(c & 63) v.AddArg(x) return true } @@ -19096,13 +19136,13 @@ func rewriteValueARM64_OpARM64SLLconst(v *Value) bool { // match: (SLLconst [c] (MOVDconst [d])) // result: (MOVDconst [d<<uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = d << uint64(c) + v.AuxInt = int64ToAuxInt(d << uint64(c)) return true } // match: (SLLconst [c] (SRLconst [c] x)) @@ -19221,9 +19261,9 @@ func rewriteValueARM64_OpARM64SRA(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64SRAconst) - v.AuxInt = c & 63 + v.AuxInt = int64ToAuxInt(c & 63) v.AddArg(x) return true } @@ -19234,13 +19274,13 @@ func rewriteValueARM64_OpARM64SRAconst(v *Value) bool { // match: (SRAconst [c] (MOVDconst [d])) // result: (MOVDconst [d>>uint64(c)]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = d >> uint64(c) + v.AuxInt = int64ToAuxInt(d >> uint64(c)) return true } // match: (SRAconst [rc] (SLLconst [lc] x)) @@ -19378,9 +19418,9 @@ func rewriteValueARM64_OpARM64SRL(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64SRLconst) - v.AuxInt = c & 63 + v.AuxInt = int64ToAuxInt(c & 63) v.AddArg(x) return true } @@ -19391,13 +19431,13 @@ func rewriteValueARM64_OpARM64SRLconst(v *Value) bool { // match: (SRLconst [c] (MOVDconst [d])) // result: (MOVDconst [int64(uint64(d)>>uint64(c))]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint64(d) >> uint64(c)) + v.AuxInt = int64ToAuxInt(int64(uint64(d) >> uint64(c))) return true } // match: (SRLconst [c] (SLLconst [c] x)) @@ -19628,7 +19668,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool { } // match: (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) - // result: (STP [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val1 val2 mem) + // result: (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -19646,7 +19686,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool { } v.reset(OpARM64STP) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg4(ptr, val1, val2, mem) return true } @@ -19679,9 +19719,9 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64SUBconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -19765,7 +19805,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (SUB x (SUB y z)) @@ -19862,7 +19902,7 @@ func rewriteValueARM64_OpARM64SUBconst(v *Value) bool { // match: (SUBconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } x := v_0 @@ -19872,40 +19912,40 @@ func rewriteValueARM64_OpARM64SUBconst(v *Value) bool { // match: (SUBconst [c] (MOVDconst [d])) // result: (MOVDconst [d-c]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = d - c + v.AuxInt = int64ToAuxInt(d - c) return true } // match: (SUBconst [c] (SUBconst [d] x)) // result: (ADDconst [-c-d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64SUBconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ADDconst) - v.AuxInt = -c - d + v.AuxInt = int64ToAuxInt(-c - d) v.AddArg(x) return true } // match: (SUBconst [c] (ADDconst [d] x)) // result: (ADDconst [-c+d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64ADDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64ADDconst) - v.AuxInt = -c + d + v.AuxInt = int64ToAuxInt(-c + d) v.AddArg(x) return true } @@ -20030,9 +20070,9 @@ func rewriteValueARM64_OpARM64TST(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64TSTconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -20110,16 +20150,16 @@ func rewriteValueARM64_OpARM64TSTW(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (TSTW x (MOVDconst [c])) - // result: (TSTWconst [c] x) + // result: (TSTWconst [int32(c)] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64TSTWconst) - v.AuxInt = c + v.AuxInt = int32ToAuxInt(int32(c)) v.AddArg(x) return true } @@ -20375,42 +20415,46 @@ func rewriteValueARM64_OpARM64UDIV(v *Value) bool { // result: x for { x := v_0 - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { break } v.copyOf(x) return true } // match: (UDIV x (MOVDconst [c])) - // cond: isPowerOfTwo(c) - // result: (SRLconst [log2(c)] x) + // cond: isPowerOfTwo64(c) + // result: (SRLconst [log64(c)] x) for { x := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64SRLconst) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } // match: (UDIV (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(uint64(c)/uint64(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint64(c) / uint64(d)) + v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) return true } return false @@ -20426,7 +20470,7 @@ func rewriteValueARM64_OpARM64UDIVW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint32(c) == 1) { break } @@ -20434,35 +20478,39 @@ func rewriteValueARM64_OpARM64UDIVW(v *Value) bool { return true } // match: (UDIVW x (MOVDconst [c])) - // cond: isPowerOfTwo(c) && is32Bit(c) - // result: (SRLconst [log2(c)] x) + // cond: isPowerOfTwo64(c) && is32Bit(c) + // result: (SRLconst [log64(c)] x) for { x := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt - if !(isPowerOfTwo(c) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c) && is32Bit(c)) { break } v.reset(OpARM64SRLconst) - v.AuxInt = log2(c) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } // match: (UDIVW (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(uint32(c)/uint32(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint32(c) / uint32(d)) + v.AuxInt = int64ToAuxInt(int64(uint32(c) / uint32(d))) return true } return false @@ -20490,43 +20538,47 @@ func rewriteValueARM64_OpARM64UMOD(v *Value) bool { // match: (UMOD _ (MOVDconst [1])) // result: (MOVDconst [0]) for { - if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 1 { + if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (UMOD x (MOVDconst [c])) - // cond: isPowerOfTwo(c) + // cond: isPowerOfTwo64(c) // result: (ANDconst [c-1] x) for { x := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt - if !(isPowerOfTwo(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { break } v.reset(OpARM64ANDconst) - v.AuxInt = c - 1 + v.AuxInt = int64ToAuxInt(c - 1) v.AddArg(x) return true } // match: (UMOD (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(uint64(c)%uint64(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint64(c) % uint64(d)) + v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) return true } return false @@ -20558,44 +20610,48 @@ func rewriteValueARM64_OpARM64UMODW(v *Value) bool { if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) if !(uint32(c) == 1) { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (UMODW x (MOVDconst [c])) - // cond: isPowerOfTwo(c) && is32Bit(c) + // cond: isPowerOfTwo64(c) && is32Bit(c) // result: (ANDconst [c-1] x) for { x := v_0 if v_1.Op != OpARM64MOVDconst { break } - c := v_1.AuxInt - if !(isPowerOfTwo(c) && is32Bit(c)) { + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c) && is32Bit(c)) { break } v.reset(OpARM64ANDconst) - v.AuxInt = c - 1 + v.AuxInt = int64ToAuxInt(c - 1) v.AddArg(x) return true } // match: (UMODW (MOVDconst [c]) (MOVDconst [d])) + // cond: d != 0 // result: (MOVDconst [int64(uint32(c)%uint32(d))]) for { if v_0.Op != OpARM64MOVDconst { break } - c := v_0.AuxInt + c := auxIntToInt64(v_0.AuxInt) if v_1.Op != OpARM64MOVDconst { break } - d := v_1.AuxInt + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpARM64MOVDconst) - v.AuxInt = int64(uint32(c) % uint32(d)) + v.AuxInt = int64ToAuxInt(int64(uint32(c) % uint32(d))) return true } return false @@ -20613,9 +20669,9 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool { if v_1.Op != OpARM64MOVDconst { continue } - c := v_1.AuxInt + c := auxIntToInt64(v_1.AuxInt) v.reset(OpARM64XORconst) - v.AuxInt = c + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } @@ -20629,7 +20685,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool { break } v.reset(OpARM64MOVDconst) - v.AuxInt = 0 + v.AuxInt = int64ToAuxInt(0) return true } // match: (XOR x (MVN y)) @@ -21001,7 +21057,7 @@ func rewriteValueARM64_OpARM64XORconst(v *Value) bool { // match: (XORconst [0] x) // result: x for { - if v.AuxInt != 0 { + if auxIntToInt64(v.AuxInt) != 0 { break } x := v_0 @@ -21011,7 +21067,7 @@ func rewriteValueARM64_OpARM64XORconst(v *Value) bool { // match: (XORconst [-1] x) // result: (MVN x) for { - if v.AuxInt != -1 { + if auxIntToInt64(v.AuxInt) != -1 { break } x := v_0 @@ -21022,26 +21078,26 @@ func rewriteValueARM64_OpARM64XORconst(v *Value) bool { // match: (XORconst [c] (MOVDconst [d])) // result: (MOVDconst [c^d]) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64MOVDconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) v.reset(OpARM64MOVDconst) - v.AuxInt = c ^ d + v.AuxInt = int64ToAuxInt(c ^ d) return true } // match: (XORconst [c] (XORconst [d] x)) // result: (XORconst [c^d] x) for { - c := v.AuxInt + c := auxIntToInt64(v.AuxInt) if v_0.Op != OpARM64XORconst { break } - d := v_0.AuxInt + d := auxIntToInt64(v_0.AuxInt) x := v_0.Args[0] v.reset(OpARM64XORconst) - v.AuxInt = c ^ d + v.AuxInt = int64ToAuxInt(c ^ d) v.AddArg(x) return true } @@ -21340,6 +21396,44 @@ func rewriteValueARM64_OpAddr(v *Value) bool { return true } } +func rewriteValueARM64_OpAtomicAnd32(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicAnd32 ptr val mem) + // result: (Select1 (LoweredAtomicAnd32 ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd32, types.NewTuple(typ.UInt32, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} +func rewriteValueARM64_OpAtomicAnd32Variant(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicAnd32Variant ptr val mem) + // result: (Select1 (LoweredAtomicAnd32Variant ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd32Variant, types.NewTuple(typ.UInt32, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} func rewriteValueARM64_OpAtomicAnd8(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -21359,6 +21453,63 @@ func rewriteValueARM64_OpAtomicAnd8(v *Value) bool { return true } } +func rewriteValueARM64_OpAtomicAnd8Variant(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicAnd8Variant ptr val mem) + // result: (Select1 (LoweredAtomicAnd8Variant ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd8Variant, types.NewTuple(typ.UInt8, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} +func rewriteValueARM64_OpAtomicOr32(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicOr32 ptr val mem) + // result: (Select1 (LoweredAtomicOr32 ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr32, types.NewTuple(typ.UInt32, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} +func rewriteValueARM64_OpAtomicOr32Variant(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicOr32Variant ptr val mem) + // result: (Select1 (LoweredAtomicOr32Variant ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr32Variant, types.NewTuple(typ.UInt32, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} func rewriteValueARM64_OpAtomicOr8(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -21378,6 +21529,25 @@ func rewriteValueARM64_OpAtomicOr8(v *Value) bool { return true } } +func rewriteValueARM64_OpAtomicOr8Variant(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (AtomicOr8Variant ptr val mem) + // result: (Select1 (LoweredAtomicOr8Variant ptr val mem)) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpSelect1) + v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr8Variant, types.NewTuple(typ.UInt8, types.TypeMem)) + v0.AddArg3(ptr, val, mem) + v.AddArg(v0) + return true + } +} func rewriteValueARM64_OpAvg64u(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go index bdafa9a957..3fc5527955 100644 --- a/src/cmd/compile/internal/ssa/rewriteMIPS.go +++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go @@ -44,6 +44,9 @@ func rewriteValueMIPS(v *Value) bool { case OpAtomicAdd32: v.Op = OpMIPSLoweredAtomicAdd return true + case OpAtomicAnd32: + v.Op = OpMIPSLoweredAtomicAnd + return true case OpAtomicAnd8: return rewriteValueMIPS_OpAtomicAnd8(v) case OpAtomicCompareAndSwap32: @@ -61,6 +64,9 @@ func rewriteValueMIPS(v *Value) bool { case OpAtomicLoadPtr: v.Op = OpMIPSLoweredAtomicLoad32 return true + case OpAtomicOr32: + v.Op = OpMIPSLoweredAtomicOr + return true case OpAtomicOr8: return rewriteValueMIPS_OpAtomicOr8(v) case OpAtomicStore32: @@ -862,11 +868,11 @@ func rewriteValueMIPS_OpConst8(v *Value) bool { } func rewriteValueMIPS_OpConstBool(v *Value) bool { // match: (ConstBool [b]) - // result: (MOVWconst [int32(b2i(b))]) + // result: (MOVWconst [b2i32(b)]) for { b := auxIntToBool(v.AuxInt) v.reset(OpMIPSMOVWconst) - v.AuxInt = int32ToAuxInt(int32(b2i(b))) + v.AuxInt = int32ToAuxInt(b2i32(b)) return true } } @@ -2333,7 +2339,7 @@ func rewriteValueMIPS_OpMIPSMOVBUload(v *Value) bool { } // match: (MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2349,7 +2355,7 @@ func rewriteValueMIPS_OpMIPSMOVBUload(v *Value) bool { } v.reset(OpMIPSMOVBUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2478,7 +2484,7 @@ func rewriteValueMIPS_OpMIPSMOVBload(v *Value) bool { } // match: (MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2494,7 +2500,7 @@ func rewriteValueMIPS_OpMIPSMOVBload(v *Value) bool { } v.reset(OpMIPSMOVBload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2629,7 +2635,7 @@ func rewriteValueMIPS_OpMIPSMOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2646,7 +2652,7 @@ func rewriteValueMIPS_OpMIPSMOVBstore(v *Value) bool { } v.reset(OpMIPSMOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -2780,7 +2786,7 @@ func rewriteValueMIPS_OpMIPSMOVBstorezero(v *Value) bool { } // match: (MOVBstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2796,7 +2802,7 @@ func rewriteValueMIPS_OpMIPSMOVBstorezero(v *Value) bool { } v.reset(OpMIPSMOVBstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2829,7 +2835,7 @@ func rewriteValueMIPS_OpMIPSMOVDload(v *Value) bool { } // match: (MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2845,7 +2851,7 @@ func rewriteValueMIPS_OpMIPSMOVDload(v *Value) bool { } v.reset(OpMIPSMOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2900,7 +2906,7 @@ func rewriteValueMIPS_OpMIPSMOVDstore(v *Value) bool { } // match: (MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2917,7 +2923,7 @@ func rewriteValueMIPS_OpMIPSMOVDstore(v *Value) bool { } v.reset(OpMIPSMOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -2950,7 +2956,7 @@ func rewriteValueMIPS_OpMIPSMOVFload(v *Value) bool { } // match: (MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVFload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2966,7 +2972,7 @@ func rewriteValueMIPS_OpMIPSMOVFload(v *Value) bool { } v.reset(OpMIPSMOVFload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3021,7 +3027,7 @@ func rewriteValueMIPS_OpMIPSMOVFstore(v *Value) bool { } // match: (MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVFstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3038,7 +3044,7 @@ func rewriteValueMIPS_OpMIPSMOVFstore(v *Value) bool { } v.reset(OpMIPSMOVFstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3071,7 +3077,7 @@ func rewriteValueMIPS_OpMIPSMOVHUload(v *Value) bool { } // match: (MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3087,7 +3093,7 @@ func rewriteValueMIPS_OpMIPSMOVHUload(v *Value) bool { } v.reset(OpMIPSMOVHUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3238,7 +3244,7 @@ func rewriteValueMIPS_OpMIPSMOVHload(v *Value) bool { } // match: (MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3254,7 +3260,7 @@ func rewriteValueMIPS_OpMIPSMOVHload(v *Value) bool { } v.reset(OpMIPSMOVHload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3433,7 +3439,7 @@ func rewriteValueMIPS_OpMIPSMOVHstore(v *Value) bool { } // match: (MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3450,7 +3456,7 @@ func rewriteValueMIPS_OpMIPSMOVHstore(v *Value) bool { } v.reset(OpMIPSMOVHstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3550,7 +3556,7 @@ func rewriteValueMIPS_OpMIPSMOVHstorezero(v *Value) bool { } // match: (MOVHstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3566,7 +3572,7 @@ func rewriteValueMIPS_OpMIPSMOVHstorezero(v *Value) bool { } v.reset(OpMIPSMOVHstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3599,7 +3605,7 @@ func rewriteValueMIPS_OpMIPSMOVWload(v *Value) bool { } // match: (MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3615,7 +3621,7 @@ func rewriteValueMIPS_OpMIPSMOVWload(v *Value) bool { } v.reset(OpMIPSMOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3697,7 +3703,7 @@ func rewriteValueMIPS_OpMIPSMOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3714,7 +3720,7 @@ func rewriteValueMIPS_OpMIPSMOVWstore(v *Value) bool { } v.reset(OpMIPSMOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3780,7 +3786,7 @@ func rewriteValueMIPS_OpMIPSMOVWstorezero(v *Value) bool { } // match: (MOVWstorezero [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) - // result: (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3796,7 +3802,7 @@ func rewriteValueMIPS_OpMIPSMOVWstorezero(v *Value) bool { } v.reset(OpMIPSMOVWstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3846,7 +3852,7 @@ func rewriteValueMIPS_OpMIPSMUL(v *Value) bool { break } // match: (MUL (MOVWconst [c]) x ) - // cond: isPowerOfTwo(int64(uint32(c))) + // cond: isPowerOfTwo64(int64(uint32(c))) // result: (SLLconst [int32(log2uint32(int64(c)))] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { @@ -3855,7 +3861,7 @@ func rewriteValueMIPS_OpMIPSMUL(v *Value) bool { } c := auxIntToInt32(v_0.AuxInt) x := v_1 - if !(isPowerOfTwo(int64(uint32(c)))) { + if !(isPowerOfTwo64(int64(uint32(c)))) { continue } v.reset(OpMIPSSLLconst) @@ -4425,7 +4431,7 @@ func rewriteValueMIPS_OpMIPSSLL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (SLL x (MOVWconst [c])) - // result: (SLLconst x [c]) + // result: (SLLconst x [c&31]) for { x := v_0 if v_1.Op != OpMIPSMOVWconst { @@ -4433,7 +4439,7 @@ func rewriteValueMIPS_OpMIPSSLL(v *Value) bool { } c := auxIntToInt32(v_1.AuxInt) v.reset(OpMIPSSLLconst) - v.AuxInt = int32ToAuxInt(c) + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -4459,24 +4465,7 @@ func rewriteValueMIPS_OpMIPSSRA(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (SRA x (MOVWconst [c])) - // cond: c >= 32 - // result: (SRAconst x [31]) - for { - x := v_0 - if v_1.Op != OpMIPSMOVWconst { - break - } - c := auxIntToInt32(v_1.AuxInt) - if !(c >= 32) { - break - } - v.reset(OpMIPSSRAconst) - v.AuxInt = int32ToAuxInt(31) - v.AddArg(x) - return true - } - // match: (SRA x (MOVWconst [c])) - // result: (SRAconst x [c]) + // result: (SRAconst x [c&31]) for { x := v_0 if v_1.Op != OpMIPSMOVWconst { @@ -4484,7 +4473,7 @@ func rewriteValueMIPS_OpMIPSSRA(v *Value) bool { } c := auxIntToInt32(v_1.AuxInt) v.reset(OpMIPSSRAconst) - v.AuxInt = int32ToAuxInt(c) + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -4510,7 +4499,7 @@ func rewriteValueMIPS_OpMIPSSRL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (SRL x (MOVWconst [c])) - // result: (SRLconst x [c]) + // result: (SRLconst x [c&31]) for { x := v_0 if v_1.Op != OpMIPSMOVWconst { @@ -4518,7 +4507,7 @@ func rewriteValueMIPS_OpMIPSSRL(v *Value) bool { } c := auxIntToInt32(v_1.AuxInt) v.reset(OpMIPSSRLconst) - v.AuxInt = int32ToAuxInt(c) + v.AuxInt = int32ToAuxInt(c & 31) v.AddArg(x) return true } @@ -5708,7 +5697,7 @@ func rewriteValueMIPS_OpRsh16x16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh16x16 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) for { x := v_0 y := v_1 @@ -5719,7 +5708,7 @@ func rewriteValueMIPS_OpRsh16x16(v *Value) bool { v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v2.AddArg(y) v3 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v3.AuxInt = int32ToAuxInt(-1) + v3.AuxInt = int32ToAuxInt(31) v4 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v4.AuxInt = int32ToAuxInt(32) v4.AddArg(v2) @@ -5734,7 +5723,7 @@ func rewriteValueMIPS_OpRsh16x32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh16x32 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) for { x := v_0 y := v_1 @@ -5743,7 +5732,7 @@ func rewriteValueMIPS_OpRsh16x32(v *Value) bool { v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpMIPSCMOVZ, typ.UInt32) v2 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v2.AuxInt = int32ToAuxInt(-1) + v2.AuxInt = int32ToAuxInt(31) v3 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v3.AuxInt = int32ToAuxInt(32) v3.AddArg(y) @@ -5805,7 +5794,7 @@ func rewriteValueMIPS_OpRsh16x8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh16x8 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) for { x := v_0 y := v_1 @@ -5816,7 +5805,7 @@ func rewriteValueMIPS_OpRsh16x8(v *Value) bool { v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) v2.AddArg(y) v3 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v3.AuxInt = int32ToAuxInt(-1) + v3.AuxInt = int32ToAuxInt(31) v4 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v4.AuxInt = int32ToAuxInt(32) v4.AddArg(v2) @@ -5941,7 +5930,7 @@ func rewriteValueMIPS_OpRsh32x16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh32x16 x y) - // result: (SRA x ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) + // result: (SRA x ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) for { x := v_0 y := v_1 @@ -5950,7 +5939,7 @@ func rewriteValueMIPS_OpRsh32x16(v *Value) bool { v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v1.AddArg(y) v2 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v2.AuxInt = int32ToAuxInt(-1) + v2.AuxInt = int32ToAuxInt(31) v3 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v3.AuxInt = int32ToAuxInt(32) v3.AddArg(v1) @@ -5965,14 +5954,14 @@ func rewriteValueMIPS_OpRsh32x32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh32x32 x y) - // result: (SRA x ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) + // result: (SRA x ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) for { x := v_0 y := v_1 v.reset(OpMIPSSRA) v0 := b.NewValue0(v.Pos, OpMIPSCMOVZ, typ.UInt32) v1 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v1.AuxInt = int32ToAuxInt(-1) + v1.AuxInt = int32ToAuxInt(31) v2 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v2.AuxInt = int32ToAuxInt(32) v2.AddArg(y) @@ -6026,7 +6015,7 @@ func rewriteValueMIPS_OpRsh32x8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh32x8 x y) - // result: (SRA x ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) + // result: (SRA x ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) for { x := v_0 y := v_1 @@ -6035,7 +6024,7 @@ func rewriteValueMIPS_OpRsh32x8(v *Value) bool { v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) v1.AddArg(y) v2 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v2.AuxInt = int32ToAuxInt(-1) + v2.AuxInt = int32ToAuxInt(31) v3 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v3.AuxInt = int32ToAuxInt(32) v3.AddArg(v1) @@ -6171,7 +6160,7 @@ func rewriteValueMIPS_OpRsh8x16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh8x16 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt16to32 y)))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt16to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt16to32 y)))) for { x := v_0 y := v_1 @@ -6182,7 +6171,7 @@ func rewriteValueMIPS_OpRsh8x16(v *Value) bool { v2 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) v2.AddArg(y) v3 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v3.AuxInt = int32ToAuxInt(-1) + v3.AuxInt = int32ToAuxInt(31) v4 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v4.AuxInt = int32ToAuxInt(32) v4.AddArg(v2) @@ -6197,7 +6186,7 @@ func rewriteValueMIPS_OpRsh8x32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh8x32 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [-1]) (SGTUconst [32] y))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> y (MOVWconst [31]) (SGTUconst [32] y))) for { x := v_0 y := v_1 @@ -6206,7 +6195,7 @@ func rewriteValueMIPS_OpRsh8x32(v *Value) bool { v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpMIPSCMOVZ, typ.UInt32) v2 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v2.AuxInt = int32ToAuxInt(-1) + v2.AuxInt = int32ToAuxInt(31) v3 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v3.AuxInt = int32ToAuxInt(32) v3.AddArg(y) @@ -6268,7 +6257,7 @@ func rewriteValueMIPS_OpRsh8x8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Rsh8x8 x y) - // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [-1]) (SGTUconst [32] (ZeroExt8to32 y)))) + // result: (SRA (SignExt16to32 x) ( CMOVZ <typ.UInt32> (ZeroExt8to32 y) (MOVWconst [31]) (SGTUconst [32] (ZeroExt8to32 y)))) for { x := v_0 y := v_1 @@ -6279,7 +6268,7 @@ func rewriteValueMIPS_OpRsh8x8(v *Value) bool { v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) v2.AddArg(y) v3 := b.NewValue0(v.Pos, OpMIPSMOVWconst, typ.UInt32) - v3.AuxInt = int32ToAuxInt(-1) + v3.AuxInt = int32ToAuxInt(31) v4 := b.NewValue0(v.Pos, OpMIPSSGTUconst, typ.Bool) v4.AuxInt = int32ToAuxInt(32) v4.AddArg(v2) @@ -6382,7 +6371,7 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool { break } // match: (Select0 (MULTU (MOVWconst [c]) x )) - // cond: isPowerOfTwo(int64(uint32(c))) + // cond: isPowerOfTwo64(int64(uint32(c))) // result: (SRLconst [int32(32-log2uint32(int64(c)))] x) for { if v_0.Op != OpMIPSMULTU { @@ -6397,7 +6386,7 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool { } c := auxIntToInt32(v_0_0.AuxInt) x := v_0_1 - if !(isPowerOfTwo(int64(uint32(c)))) { + if !(isPowerOfTwo64(int64(uint32(c)))) { continue } v.reset(OpMIPSSRLconst) @@ -6432,6 +6421,7 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool { break } // match: (Select0 (DIV (MOVWconst [c]) (MOVWconst [d]))) + // cond: d != 0 // result: (MOVWconst [c%d]) for { if v_0.Op != OpMIPSDIV { @@ -6448,11 +6438,15 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool { break } d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPSMOVWconst) v.AuxInt = int32ToAuxInt(c % d) return true } // match: (Select0 (DIVU (MOVWconst [c]) (MOVWconst [d]))) + // cond: d != 0 // result: (MOVWconst [int32(uint32(c)%uint32(d))]) for { if v_0.Op != OpMIPSDIVU { @@ -6469,6 +6463,9 @@ func rewriteValueMIPS_OpSelect0(v *Value) bool { break } d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPSMOVWconst) v.AuxInt = int32ToAuxInt(int32(uint32(c) % uint32(d))) return true @@ -6570,7 +6567,7 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool { break } // match: (Select1 (MULTU (MOVWconst [c]) x )) - // cond: isPowerOfTwo(int64(uint32(c))) + // cond: isPowerOfTwo64(int64(uint32(c))) // result: (SLLconst [int32(log2uint32(int64(c)))] x) for { if v_0.Op != OpMIPSMULTU { @@ -6585,7 +6582,7 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool { } c := auxIntToInt32(v_0_0.AuxInt) x := v_0_1 - if !(isPowerOfTwo(int64(uint32(c)))) { + if !(isPowerOfTwo64(int64(uint32(c)))) { continue } v.reset(OpMIPSSLLconst) @@ -6620,6 +6617,7 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool { break } // match: (Select1 (DIV (MOVWconst [c]) (MOVWconst [d]))) + // cond: d != 0 // result: (MOVWconst [c/d]) for { if v_0.Op != OpMIPSDIV { @@ -6636,11 +6634,15 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool { break } d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPSMOVWconst) v.AuxInt = int32ToAuxInt(c / d) return true } // match: (Select1 (DIVU (MOVWconst [c]) (MOVWconst [d]))) + // cond: d != 0 // result: (MOVWconst [int32(uint32(c)/uint32(d))]) for { if v_0.Op != OpMIPSDIVU { @@ -6657,6 +6659,9 @@ func rewriteValueMIPS_OpSelect1(v *Value) bool { break } d := auxIntToInt32(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPSMOVWconst) v.AuxInt = int32ToAuxInt(int32(uint32(c) / uint32(d))) return true diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go index dfff1c03b7..d78f6089af 100644 --- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go +++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go @@ -2558,7 +2558,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBUload(v *Value) bool { } // match: (MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVBUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2574,7 +2574,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBUload(v *Value) bool { } v.reset(OpMIPS64MOVBUload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2643,7 +2643,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBload(v *Value) bool { } // match: (MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVBload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2659,7 +2659,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBload(v *Value) bool { } v.reset(OpMIPS64MOVBload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2730,7 +2730,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVBstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2747,7 +2747,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBstore(v *Value) bool { } v.reset(OpMIPS64MOVBstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -2897,7 +2897,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBstorezero(v *Value) bool { } // match: (MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVBstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2913,7 +2913,7 @@ func rewriteValueMIPS64_OpMIPS64MOVBstorezero(v *Value) bool { } v.reset(OpMIPS64MOVBstorezero) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2945,7 +2945,7 @@ func rewriteValueMIPS64_OpMIPS64MOVDload(v *Value) bool { } // match: (MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVDload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2961,7 +2961,7 @@ func rewriteValueMIPS64_OpMIPS64MOVDload(v *Value) bool { } v.reset(OpMIPS64MOVDload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2995,7 +2995,7 @@ func rewriteValueMIPS64_OpMIPS64MOVDstore(v *Value) bool { } // match: (MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVDstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3012,7 +3012,7 @@ func rewriteValueMIPS64_OpMIPS64MOVDstore(v *Value) bool { } v.reset(OpMIPS64MOVDstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3044,7 +3044,7 @@ func rewriteValueMIPS64_OpMIPS64MOVFload(v *Value) bool { } // match: (MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVFload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3060,7 +3060,7 @@ func rewriteValueMIPS64_OpMIPS64MOVFload(v *Value) bool { } v.reset(OpMIPS64MOVFload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3094,7 +3094,7 @@ func rewriteValueMIPS64_OpMIPS64MOVFstore(v *Value) bool { } // match: (MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVFstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3111,7 +3111,7 @@ func rewriteValueMIPS64_OpMIPS64MOVFstore(v *Value) bool { } v.reset(OpMIPS64MOVFstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3143,7 +3143,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHUload(v *Value) bool { } // match: (MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVHUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3159,7 +3159,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHUload(v *Value) bool { } v.reset(OpMIPS64MOVHUload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3250,7 +3250,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHload(v *Value) bool { } // match: (MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVHload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3266,7 +3266,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHload(v *Value) bool { } v.reset(OpMIPS64MOVHload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3381,7 +3381,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHstore(v *Value) bool { } // match: (MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVHstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3398,7 +3398,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHstore(v *Value) bool { } v.reset(OpMIPS64MOVHstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3514,7 +3514,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHstorezero(v *Value) bool { } // match: (MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVHstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3530,7 +3530,7 @@ func rewriteValueMIPS64_OpMIPS64MOVHstorezero(v *Value) bool { } v.reset(OpMIPS64MOVHstorezero) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3562,7 +3562,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool { } // match: (MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVVload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3578,7 +3578,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool { } v.reset(OpMIPS64MOVVload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3639,7 +3639,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVstore(v *Value) bool { } // match: (MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVVstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3656,7 +3656,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVstore(v *Value) bool { } v.reset(OpMIPS64MOVVstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -3704,7 +3704,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVstorezero(v *Value) bool { } // match: (MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVVstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3720,7 +3720,7 @@ func rewriteValueMIPS64_OpMIPS64MOVVstorezero(v *Value) bool { } v.reset(OpMIPS64MOVVstorezero) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3752,7 +3752,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWUload(v *Value) bool { } // match: (MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVWUload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3768,7 +3768,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWUload(v *Value) bool { } v.reset(OpMIPS64MOVWUload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3881,7 +3881,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWload(v *Value) bool { } // match: (MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVWload [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3897,7 +3897,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWload(v *Value) bool { } v.reset(OpMIPS64MOVWload) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4045,7 +4045,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVWstore [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4062,7 +4062,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWstore(v *Value) bool { } v.reset(OpMIPS64MOVWstore) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -4144,7 +4144,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWstorezero(v *Value) bool { } // match: (MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVWstorezero [off1+int32(off2)] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -4160,7 +4160,7 @@ func rewriteValueMIPS64_OpMIPS64MOVWstorezero(v *Value) bool { } v.reset(OpMIPS64MOVWstorezero) v.AuxInt = int32ToAuxInt(off1 + int32(off2)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -6865,7 +6865,7 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool { return true } // match: (Select0 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo(c) + // cond: isPowerOfTwo64(c) // result: (ANDconst [c-1] x) for { if v_0.Op != OpMIPS64DIVVU { @@ -6878,7 +6878,7 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool { break } c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpMIPS64ANDconst) @@ -6887,6 +6887,7 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool { return true } // match: (Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) + // cond: d != 0 // result: (MOVVconst [c%d]) for { if v_0.Op != OpMIPS64DIVV { @@ -6903,11 +6904,15 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool { break } d := auxIntToInt64(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPS64MOVVconst) v.AuxInt = int64ToAuxInt(c % d) return true } // match: (Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) + // cond: d != 0 // result: (MOVVconst [int64(uint64(c)%uint64(d))]) for { if v_0.Op != OpMIPS64DIVVU { @@ -6924,6 +6929,9 @@ func rewriteValueMIPS64_OpSelect0(v *Value) bool { break } d := auxIntToInt64(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPS64MOVVconst) v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) return true @@ -7012,8 +7020,8 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { break } // match: (Select1 (MULVU x (MOVVconst [c]))) - // cond: isPowerOfTwo(c) - // result: (SLLVconst [log2(c)] x) + // cond: isPowerOfTwo64(c) + // result: (SLLVconst [log64(c)] x) for { if v_0.Op != OpMIPS64MULVU { break @@ -7027,11 +7035,11 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { continue } c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { continue } v.reset(OpMIPS64SLLVconst) - v.AuxInt = int64ToAuxInt(log2(c)) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } @@ -7053,8 +7061,8 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { return true } // match: (Select1 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo(c) - // result: (SRLVconst [log2(c)] x) + // cond: isPowerOfTwo64(c) + // result: (SRLVconst [log64(c)] x) for { if v_0.Op != OpMIPS64DIVVU { break @@ -7066,11 +7074,11 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { break } c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo(c)) { + if !(isPowerOfTwo64(c)) { break } v.reset(OpMIPS64SRLVconst) - v.AuxInt = int64ToAuxInt(log2(c)) + v.AuxInt = int64ToAuxInt(log64(c)) v.AddArg(x) return true } @@ -7099,6 +7107,7 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { break } // match: (Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) + // cond: d != 0 // result: (MOVVconst [c/d]) for { if v_0.Op != OpMIPS64DIVV { @@ -7115,11 +7124,15 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { break } d := auxIntToInt64(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPS64MOVVconst) v.AuxInt = int64ToAuxInt(c / d) return true } // match: (Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) + // cond: d != 0 // result: (MOVVconst [int64(uint64(c)/uint64(d))]) for { if v_0.Op != OpMIPS64DIVVU { @@ -7136,6 +7149,9 @@ func rewriteValueMIPS64_OpSelect1(v *Value) bool { break } d := auxIntToInt64(v_0_1.AuxInt) + if !(d != 0) { + break + } v.reset(OpMIPS64MOVVconst) v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) return true diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 152cdfdf4d..455f9b1388 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -59,6 +59,9 @@ func rewriteValuePPC64(v *Value) bool { case OpAtomicAdd64: v.Op = OpPPC64LoweredAtomicAdd64 return true + case OpAtomicAnd32: + v.Op = OpPPC64LoweredAtomicAnd32 + return true case OpAtomicAnd8: v.Op = OpPPC64LoweredAtomicAnd8 return true @@ -82,8 +85,13 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpAtomicLoad8(v) case OpAtomicLoadAcq32: return rewriteValuePPC64_OpAtomicLoadAcq32(v) + case OpAtomicLoadAcq64: + return rewriteValuePPC64_OpAtomicLoadAcq64(v) case OpAtomicLoadPtr: return rewriteValuePPC64_OpAtomicLoadPtr(v) + case OpAtomicOr32: + v.Op = OpPPC64LoweredAtomicOr32 + return true case OpAtomicOr8: v.Op = OpPPC64LoweredAtomicOr8 return true @@ -95,6 +103,8 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpAtomicStore8(v) case OpAtomicStoreRel32: return rewriteValuePPC64_OpAtomicStoreRel32(v) + case OpAtomicStoreRel64: + return rewriteValuePPC64_OpAtomicStoreRel64(v) case OpAvg64u: return rewriteValuePPC64_OpAvg64u(v) case OpBitLen32: @@ -434,6 +444,8 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPPC64ANDN(v) case OpPPC64ANDconst: return rewriteValuePPC64_OpPPC64ANDconst(v) + case OpPPC64CLRLSLDI: + return rewriteValuePPC64_OpPPC64CLRLSLDI(v) case OpPPC64CMP: return rewriteValuePPC64_OpPPC64CMP(v) case OpPPC64CMPU: @@ -568,6 +580,10 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPPC64MOVWstorezero(v) case OpPPC64MTVSRD: return rewriteValuePPC64_OpPPC64MTVSRD(v) + case OpPPC64MULLD: + return rewriteValuePPC64_OpPPC64MULLD(v) + case OpPPC64MULLW: + return rewriteValuePPC64_OpPPC64MULLW(v) case OpPPC64NEG: return rewriteValuePPC64_OpPPC64NEG(v) case OpPPC64NOR: @@ -584,10 +600,16 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPPC64ROTL(v) case OpPPC64ROTLW: return rewriteValuePPC64_OpPPC64ROTLW(v) + case OpPPC64ROTLWconst: + return rewriteValuePPC64_OpPPC64ROTLWconst(v) case OpPPC64SLD: return rewriteValuePPC64_OpPPC64SLD(v) + case OpPPC64SLDconst: + return rewriteValuePPC64_OpPPC64SLDconst(v) case OpPPC64SLW: return rewriteValuePPC64_OpPPC64SLW(v) + case OpPPC64SLWconst: + return rewriteValuePPC64_OpPPC64SLWconst(v) case OpPPC64SRAD: return rewriteValuePPC64_OpPPC64SRAD(v) case OpPPC64SRAW: @@ -596,6 +618,8 @@ func rewriteValuePPC64(v *Value) bool { return rewriteValuePPC64_OpPPC64SRD(v) case OpPPC64SRW: return rewriteValuePPC64_OpPPC64SRW(v) + case OpPPC64SRWconst: + return rewriteValuePPC64_OpPPC64SRWconst(v) case OpPPC64SUB: return rewriteValuePPC64_OpPPC64SUB(v) case OpPPC64SUBFCconst: @@ -922,6 +946,20 @@ func rewriteValuePPC64_OpAtomicLoadAcq32(v *Value) bool { return true } } +func rewriteValuePPC64_OpAtomicLoadAcq64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicLoadAcq64 ptr mem) + // result: (LoweredAtomicLoad64 [0] ptr mem) + for { + ptr := v_0 + mem := v_1 + v.reset(OpPPC64LoweredAtomicLoad64) + v.AuxInt = int64ToAuxInt(0) + v.AddArg2(ptr, mem) + return true + } +} func rewriteValuePPC64_OpAtomicLoadPtr(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -1000,6 +1038,22 @@ func rewriteValuePPC64_OpAtomicStoreRel32(v *Value) bool { return true } } +func rewriteValuePPC64_OpAtomicStoreRel64(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (AtomicStoreRel64 ptr val mem) + // result: (LoweredAtomicStore64 [0] ptr val mem) + for { + ptr := v_0 + val := v_1 + mem := v_2 + v.reset(OpPPC64LoweredAtomicStore64) + v.AuxInt = int64ToAuxInt(0) + v.AddArg3(ptr, val, mem) + return true + } +} func rewriteValuePPC64_OpAvg64u(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -4141,6 +4195,20 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool { v.AddArg(x) return true } + // match: (ADDconst [c] x:(SP)) + // cond: is32Bit(c) + // result: (MOVDaddr [int32(c)] x) + for { + c := auxIntToInt64(v.AuxInt) + x := v_0 + if x.Op != OpSP || !(is32Bit(c)) { + break + } + v.reset(OpPPC64MOVDaddr) + v.AuxInt = int32ToAuxInt(int32(c)) + v.AddArg(x) + return true + } // match: (ADDconst [c] (SUBFCconst [d] x)) // cond: is32Bit(c+d) // result: (SUBFCconst [c+d] x) @@ -4164,6 +4232,100 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool { func rewriteValuePPC64_OpPPC64AND(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] + // match: (AND (MOVDconst [m]) (ROTLWconst [r] x)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWINM [encodePPC64RotateMask(r,m,32)] x) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpPPC64ROTLWconst { + continue + } + r := auxIntToInt64(v_1.AuxInt) + x := v_1.Args[0] + if !(isPPC64WordRotateMask(m)) { + continue + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, m, 32)) + v.AddArg(x) + return true + } + break + } + // match: (AND (MOVDconst [m]) (ROTLW x r)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWNM [encodePPC64RotateMask(0,m,32)] x r) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpPPC64ROTLW { + continue + } + r := v_1.Args[1] + x := v_1.Args[0] + if !(isPPC64WordRotateMask(m)) { + continue + } + v.reset(OpPPC64RLWNM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(0, m, 32)) + v.AddArg2(x, r) + return true + } + break + } + // match: (AND (MOVDconst [m]) (SRWconst x [s])) + // cond: mergePPC64RShiftMask(m,s,32) == 0 + // result: (MOVDconst [0]) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpPPC64SRWconst { + continue + } + s := auxIntToInt64(v_1.AuxInt) + if !(mergePPC64RShiftMask(m, s, 32) == 0) { + continue + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + break + } + // match: (AND (MOVDconst [m]) (SRWconst x [s])) + // cond: mergePPC64AndSrwi(m,s) != 0 + // result: (RLWINM [mergePPC64AndSrwi(m,s)] x) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpPPC64SRWconst { + continue + } + s := auxIntToInt64(v_1.AuxInt) + x := v_1.Args[0] + if !(mergePPC64AndSrwi(m, s) != 0) { + continue + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m, s)) + v.AddArg(x) + return true + } + break + } // match: (AND x (NOR y y)) // result: (ANDN x y) for { @@ -4299,6 +4461,76 @@ func rewriteValuePPC64_OpPPC64ANDN(v *Value) bool { } func rewriteValuePPC64_OpPPC64ANDconst(v *Value) bool { v_0 := v.Args[0] + // match: (ANDconst [m] (ROTLWconst [r] x)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWINM [encodePPC64RotateMask(r,m,32)] x) + for { + m := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64ROTLWconst { + break + } + r := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(isPPC64WordRotateMask(m)) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, m, 32)) + v.AddArg(x) + return true + } + // match: (ANDconst [m] (ROTLW x r)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWNM [encodePPC64RotateMask(0,m,32)] x r) + for { + m := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64ROTLW { + break + } + r := v_0.Args[1] + x := v_0.Args[0] + if !(isPPC64WordRotateMask(m)) { + break + } + v.reset(OpPPC64RLWNM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(0, m, 32)) + v.AddArg2(x, r) + return true + } + // match: (ANDconst [m] (SRWconst x [s])) + // cond: mergePPC64RShiftMask(m,s,32) == 0 + // result: (MOVDconst [0]) + for { + m := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64SRWconst { + break + } + s := auxIntToInt64(v_0.AuxInt) + if !(mergePPC64RShiftMask(m, s, 32) == 0) { + break + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (ANDconst [m] (SRWconst x [s])) + // cond: mergePPC64AndSrwi(m,s) != 0 + // result: (RLWINM [mergePPC64AndSrwi(m,s)] x) + for { + m := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64SRWconst { + break + } + s := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(mergePPC64AndSrwi(m, s) != 0) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m, s)) + v.AddArg(x) + return true + } // match: (ANDconst [c] (ANDconst [d] x)) // result: (ANDconst [c&d] x) for { @@ -4463,6 +4695,47 @@ func rewriteValuePPC64_OpPPC64ANDconst(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64CLRLSLDI(v *Value) bool { + v_0 := v.Args[0] + // match: (CLRLSLDI [c] (SRWconst [s] x)) + // cond: mergePPC64ClrlsldiSrw(int64(c),s) != 0 + // result: (RLWINM [mergePPC64ClrlsldiSrw(int64(c),s)] x) + for { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpPPC64SRWconst { + break + } + s := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(mergePPC64ClrlsldiSrw(int64(c), s) != 0) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64ClrlsldiSrw(int64(c), s)) + v.AddArg(x) + return true + } + // match: (CLRLSLDI [c] i:(RLWINM [s] x)) + // cond: mergePPC64ClrlsldiRlwinm(c,s) != 0 + // result: (RLWINM [mergePPC64ClrlsldiRlwinm(c,s)] x) + for { + c := auxIntToInt32(v.AuxInt) + i := v_0 + if i.Op != OpPPC64RLWINM { + break + } + s := auxIntToInt64(i.AuxInt) + x := i.Args[0] + if !(mergePPC64ClrlsldiRlwinm(c, s) != 0) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64ClrlsldiRlwinm(c, s)) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64CMP(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -5171,7 +5444,7 @@ func rewriteValuePPC64_OpPPC64FMOVDload(v *Value) bool { } // match: (FMOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5188,7 +5461,7 @@ func rewriteValuePPC64_OpPPC64FMOVDload(v *Value) bool { } v.reset(OpPPC64FMOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5260,7 +5533,7 @@ func rewriteValuePPC64_OpPPC64FMOVDstore(v *Value) bool { } // match: (FMOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5278,7 +5551,7 @@ func rewriteValuePPC64_OpPPC64FMOVDstore(v *Value) bool { } v.reset(OpPPC64FMOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -5289,7 +5562,7 @@ func rewriteValuePPC64_OpPPC64FMOVSload(v *Value) bool { v_0 := v.Args[0] // match: (FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5306,7 +5579,7 @@ func rewriteValuePPC64_OpPPC64FMOVSload(v *Value) bool { } v.reset(OpPPC64FMOVSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -5361,7 +5634,7 @@ func rewriteValuePPC64_OpPPC64FMOVSstore(v *Value) bool { } // match: (FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -5379,7 +5652,7 @@ func rewriteValuePPC64_OpPPC64FMOVSstore(v *Value) bool { } v.reset(OpPPC64FMOVSstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -6347,7 +6620,7 @@ func rewriteValuePPC64_OpPPC64MOVBZload(v *Value) bool { v_0 := v.Args[0] // match: (MOVBZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVBZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6364,7 +6637,7 @@ func rewriteValuePPC64_OpPPC64MOVBZload(v *Value) bool { } v.reset(OpPPC64MOVBZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -6565,6 +6838,255 @@ func rewriteValuePPC64_OpPPC64MOVBZreg(v *Value) bool { v.AddArg(x) return true } + // match: (MOVBZreg (OR <t> x (MOVWZreg y))) + // result: (MOVBZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (XOR <t> x (MOVWZreg y))) + // result: (MOVBZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (AND <t> x (MOVWZreg y))) + // result: (MOVBZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (OR <t> x (MOVHZreg y))) + // result: (MOVBZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (XOR <t> x (MOVHZreg y))) + // result: (MOVBZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (AND <t> x (MOVHZreg y))) + // result: (MOVBZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (OR <t> x (MOVBZreg y))) + // result: (MOVBZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVBZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (XOR <t> x (MOVBZreg y))) + // result: (MOVBZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVBZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg (AND <t> x (MOVBZreg y))) + // result: (MOVBZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVBZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVBZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVBZreg z:(ANDconst [c] (MOVBZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVBZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVBZreg z:(AND y (MOVBZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64AND { + break + } + _ = z.Args[1] + z_0 := z.Args[0] + z_1 := z.Args[1] + for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 { + if z_1.Op != OpPPC64MOVBZload { + continue + } + v.copyOf(z) + return true + } + break + } // match: (MOVBZreg x:(MOVBZload _ _)) // result: x for { @@ -6850,7 +7372,7 @@ func rewriteValuePPC64_OpPPC64MOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -6868,7 +7390,7 @@ func rewriteValuePPC64_OpPPC64MOVBstore(v *Value) bool { } v.reset(OpPPC64MOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -7823,7 +8345,7 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value) bool { } // match: (MOVBstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) // cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) - // result: (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7840,7 +8362,7 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value) bool { } v.reset(OpPPC64MOVBstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, mem) return true } @@ -7868,7 +8390,7 @@ func rewriteValuePPC64_OpPPC64MOVDload(v *Value) bool { } // match: (MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 - // result: (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7885,7 +8407,7 @@ func rewriteValuePPC64_OpPPC64MOVDload(v *Value) bool { } v.reset(OpPPC64MOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -8021,7 +8543,7 @@ func rewriteValuePPC64_OpPPC64MOVDstore(v *Value) bool { } // match: (MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 - // result: (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8039,7 +8561,7 @@ func rewriteValuePPC64_OpPPC64MOVDstore(v *Value) bool { } v.reset(OpPPC64MOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -8155,7 +8677,7 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value) bool { } // match: (MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) // cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 - // result: (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8172,7 +8694,7 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value) bool { } v.reset(OpPPC64MOVDstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, mem) return true } @@ -8249,7 +8771,7 @@ func rewriteValuePPC64_OpPPC64MOVHZload(v *Value) bool { v_0 := v.Args[0] // match: (MOVHZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVHZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8266,7 +8788,7 @@ func rewriteValuePPC64_OpPPC64MOVHZload(v *Value) bool { } v.reset(OpPPC64MOVHZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -8507,6 +9029,197 @@ func rewriteValuePPC64_OpPPC64MOVHZreg(v *Value) bool { v.AddArg(x) return true } + // match: (MOVHZreg (OR <t> x (MOVWZreg y))) + // result: (MOVHZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg (XOR <t> x (MOVWZreg y))) + // result: (MOVHZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg (AND <t> x (MOVWZreg y))) + // result: (MOVHZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg (OR <t> x (MOVHZreg y))) + // result: (MOVHZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg (XOR <t> x (MOVHZreg y))) + // result: (MOVHZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg (AND <t> x (MOVHZreg y))) + // result: (MOVHZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVHZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVHZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVHZreg z:(ANDconst [c] (MOVBZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVBZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVHZreg z:(ANDconst [c] (MOVHZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVHZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVHZreg z:(AND y (MOVHZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64AND { + break + } + _ = z.Args[1] + z_0 := z.Args[0] + z_1 := z.Args[1] + for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 { + if z_1.Op != OpPPC64MOVHZload { + continue + } + v.copyOf(z) + return true + } + break + } // match: (MOVHZreg x:(MOVBZload _ _)) // result: x for { @@ -8580,7 +9293,7 @@ func rewriteValuePPC64_OpPPC64MOVHload(v *Value) bool { v_0 := v.Args[0] // match: (MOVHload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8597,7 +9310,7 @@ func rewriteValuePPC64_OpPPC64MOVHload(v *Value) bool { } v.reset(OpPPC64MOVHload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -8974,7 +9687,7 @@ func rewriteValuePPC64_OpPPC64MOVHstore(v *Value) bool { } // match: (MOVHstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8992,7 +9705,7 @@ func rewriteValuePPC64_OpPPC64MOVHstore(v *Value) bool { } v.reset(OpPPC64MOVHstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -9290,7 +10003,7 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value) bool { } // match: (MOVHstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) // cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) - // result: (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9307,7 +10020,7 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value) bool { } v.reset(OpPPC64MOVHstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, mem) return true } @@ -9354,7 +10067,7 @@ func rewriteValuePPC64_OpPPC64MOVWZload(v *Value) bool { v_0 := v.Args[0] // match: (MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVWZload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9371,7 +10084,7 @@ func rewriteValuePPC64_OpPPC64MOVWZload(v *Value) bool { } v.reset(OpPPC64MOVWZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -9657,6 +10370,139 @@ func rewriteValuePPC64_OpPPC64MOVWZreg(v *Value) bool { v.AddArg(x) return true } + // match: (MOVWZreg (OR <t> x (MOVWZreg y))) + // result: (MOVWZreg (OR <t> x y)) + for { + if v_0.Op != OpPPC64OR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVWZreg) + v0 := b.NewValue0(v.Pos, OpPPC64OR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVWZreg (XOR <t> x (MOVWZreg y))) + // result: (MOVWZreg (XOR <t> x y)) + for { + if v_0.Op != OpPPC64XOR { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVWZreg) + v0 := b.NewValue0(v.Pos, OpPPC64XOR, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVWZreg (AND <t> x (MOVWZreg y))) + // result: (MOVWZreg (AND <t> x y)) + for { + if v_0.Op != OpPPC64AND { + break + } + t := v_0.Type + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + x := v_0_0 + if v_0_1.Op != OpPPC64MOVWZreg { + continue + } + y := v_0_1.Args[0] + v.reset(OpPPC64MOVWZreg) + v0 := b.NewValue0(v.Pos, OpPPC64AND, t) + v0.AddArg2(x, y) + v.AddArg(v0) + return true + } + break + } + // match: (MOVWZreg z:(ANDconst [c] (MOVBZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVBZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVWZreg z:(ANDconst [c] (MOVHZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVHZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVWZreg z:(ANDconst [c] (MOVWZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + z_0 := z.Args[0] + if z_0.Op != OpPPC64MOVWZload { + break + } + v.copyOf(z) + return true + } + // match: (MOVWZreg z:(AND y (MOVWZload ptr x))) + // result: z + for { + z := v_0 + if z.Op != OpPPC64AND { + break + } + _ = z.Args[1] + z_0 := z.Args[0] + z_1 := z.Args[1] + for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 { + if z_1.Op != OpPPC64MOVWZload { + continue + } + v.copyOf(z) + return true + } + break + } // match: (MOVWZreg x:(MOVBZload _ _)) // result: x for { @@ -9750,7 +10596,7 @@ func rewriteValuePPC64_OpPPC64MOVWload(v *Value) bool { v_0 := v.Args[0] // match: (MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) && (off1+off2)%4 == 0 - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9767,7 +10613,7 @@ func rewriteValuePPC64_OpPPC64MOVWload(v *Value) bool { } v.reset(OpPPC64MOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -10163,7 +11009,7 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) // cond: canMergeSym(sym1,sym2) && is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} ptr val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10181,7 +11027,7 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value) bool { } v.reset(OpPPC64MOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(ptr, val, mem) return true } @@ -10359,7 +11205,7 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value) bool { } // match: (MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) // cond: canMergeSym(sym1,sym2) && (x.Op != OpSB || p.Uses == 1) - // result: (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} x mem) + // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10376,7 +11222,7 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value) bool { } v.reset(OpPPC64MOVWstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, mem) return true } @@ -10426,6 +11272,56 @@ func rewriteValuePPC64_OpPPC64MTVSRD(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64MULLD(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (MULLD x (MOVDconst [c])) + // cond: is16Bit(c) + // result: (MULLDconst [int32(c)] x) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + x := v_0 + if v_1.Op != OpPPC64MOVDconst { + continue + } + c := auxIntToInt64(v_1.AuxInt) + if !(is16Bit(c)) { + continue + } + v.reset(OpPPC64MULLDconst) + v.AuxInt = int32ToAuxInt(int32(c)) + v.AddArg(x) + return true + } + break + } + return false +} +func rewriteValuePPC64_OpPPC64MULLW(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (MULLW x (MOVDconst [c])) + // cond: is16Bit(c) + // result: (MULLWconst [int32(c)] x) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + x := v_0 + if v_1.Op != OpPPC64MOVDconst { + continue + } + c := auxIntToInt64(v_1.AuxInt) + if !(is16Bit(c)) { + continue + } + v.reset(OpPPC64MULLWconst) + v.AuxInt = int32ToAuxInt(int32(c)) + v.AddArg(x) + return true + } + break + } + return false +} func rewriteValuePPC64_OpPPC64NEG(v *Value) bool { v_0 := v.Args[0] // match: (NEG (ADDconst [c] x)) @@ -12179,6 +13075,55 @@ func rewriteValuePPC64_OpPPC64ROTLW(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64ROTLWconst(v *Value) bool { + v_0 := v.Args[0] + // match: (ROTLWconst [r] (AND (MOVDconst [m]) x)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x) + for { + r := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64AND { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + if v_0_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0_0.AuxInt) + x := v_0_1 + if !(isPPC64WordRotateMask(m)) { + continue + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, rotateLeft32(m, r), 32)) + v.AddArg(x) + return true + } + break + } + // match: (ROTLWconst [r] (ANDconst [m] x)) + // cond: isPPC64WordRotateMask(m) + // result: (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x) + for { + r := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64ANDconst { + break + } + m := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(isPPC64WordRotateMask(m)) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, rotateLeft32(m, r), 32)) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64SLD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -12197,6 +13142,147 @@ func rewriteValuePPC64_OpPPC64SLD(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64SLDconst(v *Value) bool { + v_0 := v.Args[0] + // match: (SLDconst [l] (SRWconst [r] x)) + // cond: mergePPC64SldiSrw(l,r) != 0 + // result: (RLWINM [mergePPC64SldiSrw(l,r)] x) + for { + l := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64SRWconst { + break + } + r := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(mergePPC64SldiSrw(l, r) != 0) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64SldiSrw(l, r)) + v.AddArg(x) + return true + } + // match: (SLDconst [c] z:(MOVBZreg x)) + // cond: c < 8 && z.Uses == 1 + // result: (CLRLSLDI [newPPC64ShiftAuxInt(c,56,63,64)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVBZreg { + break + } + x := z.Args[0] + if !(c < 8 && z.Uses == 1) { + break + } + v.reset(OpPPC64CLRLSLDI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 56, 63, 64)) + v.AddArg(x) + return true + } + // match: (SLDconst [c] z:(MOVHZreg x)) + // cond: c < 16 && z.Uses == 1 + // result: (CLRLSLDI [newPPC64ShiftAuxInt(c,48,63,64)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVHZreg { + break + } + x := z.Args[0] + if !(c < 16 && z.Uses == 1) { + break + } + v.reset(OpPPC64CLRLSLDI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 48, 63, 64)) + v.AddArg(x) + return true + } + // match: (SLDconst [c] z:(MOVWZreg x)) + // cond: c < 32 && z.Uses == 1 + // result: (CLRLSLDI [newPPC64ShiftAuxInt(c,32,63,64)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVWZreg { + break + } + x := z.Args[0] + if !(c < 32 && z.Uses == 1) { + break + } + v.reset(OpPPC64CLRLSLDI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 32, 63, 64)) + v.AddArg(x) + return true + } + // match: (SLDconst [c] z:(ANDconst [d] x)) + // cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d)) + // result: (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + d := auxIntToInt64(z.AuxInt) + x := z.Args[0] + if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d))) { + break + } + v.reset(OpPPC64CLRLSLDI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 64-getPPC64ShiftMaskLength(d), 63, 64)) + v.AddArg(x) + return true + } + // match: (SLDconst [c] z:(AND (MOVDconst [d]) x)) + // cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(64-getPPC64ShiftMaskLength(d)) + // result: (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64AND { + break + } + _ = z.Args[1] + z_0 := z.Args[0] + z_1 := z.Args[1] + for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 { + if z_0.Op != OpPPC64MOVDconst { + continue + } + d := auxIntToInt64(z_0.AuxInt) + x := z_1 + if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d))) { + continue + } + v.reset(OpPPC64CLRLSLDI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 64-getPPC64ShiftMaskLength(d), 63, 64)) + v.AddArg(x) + return true + } + break + } + // match: (SLDconst [c] z:(MOVWreg x)) + // cond: c < 32 && objabi.GOPPC64 >= 9 + // result: (EXTSWSLconst [c] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVWreg { + break + } + x := z.Args[0] + if !(c < 32 && objabi.GOPPC64 >= 9) { + break + } + v.reset(OpPPC64EXTSWSLconst) + v.AuxInt = int64ToAuxInt(c) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64SLW(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -12215,6 +13301,111 @@ func rewriteValuePPC64_OpPPC64SLW(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64SLWconst(v *Value) bool { + v_0 := v.Args[0] + // match: (SLWconst [c] z:(MOVBZreg x)) + // cond: z.Uses == 1 && c < 8 + // result: (CLRLSLWI [newPPC64ShiftAuxInt(c,24,31,32)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVBZreg { + break + } + x := z.Args[0] + if !(z.Uses == 1 && c < 8) { + break + } + v.reset(OpPPC64CLRLSLWI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 24, 31, 32)) + v.AddArg(x) + return true + } + // match: (SLWconst [c] z:(MOVHZreg x)) + // cond: z.Uses == 1 && c < 16 + // result: (CLRLSLWI [newPPC64ShiftAuxInt(c,16,31,32)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVHZreg { + break + } + x := z.Args[0] + if !(z.Uses == 1 && c < 16) { + break + } + v.reset(OpPPC64CLRLSLWI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 16, 31, 32)) + v.AddArg(x) + return true + } + // match: (SLWconst [c] z:(ANDconst [d] x)) + // cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) + // result: (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64ANDconst { + break + } + d := auxIntToInt64(z.AuxInt) + x := z.Args[0] + if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (32-getPPC64ShiftMaskLength(d))) { + break + } + v.reset(OpPPC64CLRLSLWI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 32-getPPC64ShiftMaskLength(d), 31, 32)) + v.AddArg(x) + return true + } + // match: (SLWconst [c] z:(AND (MOVDconst [d]) x)) + // cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) + // result: (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64AND { + break + } + _ = z.Args[1] + z_0 := z.Args[0] + z_1 := z.Args[1] + for _i0 := 0; _i0 <= 1; _i0, z_0, z_1 = _i0+1, z_1, z_0 { + if z_0.Op != OpPPC64MOVDconst { + continue + } + d := auxIntToInt64(z_0.AuxInt) + x := z_1 + if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (32-getPPC64ShiftMaskLength(d))) { + continue + } + v.reset(OpPPC64CLRLSLWI) + v.AuxInt = int32ToAuxInt(newPPC64ShiftAuxInt(c, 32-getPPC64ShiftMaskLength(d), 31, 32)) + v.AddArg(x) + return true + } + break + } + // match: (SLWconst [c] z:(MOVWreg x)) + // cond: c < 32 && objabi.GOPPC64 >= 9 + // result: (EXTSWSLconst [c] x) + for { + c := auxIntToInt64(v.AuxInt) + z := v_0 + if z.Op != OpPPC64MOVWreg { + break + } + x := z.Args[0] + if !(c < 32 && objabi.GOPPC64 >= 9) { + break + } + v.reset(OpPPC64EXTSWSLconst) + v.AuxInt = int64ToAuxInt(c) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64SRAD(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -12287,6 +13478,96 @@ func rewriteValuePPC64_OpPPC64SRW(v *Value) bool { } return false } +func rewriteValuePPC64_OpPPC64SRWconst(v *Value) bool { + v_0 := v.Args[0] + // match: (SRWconst (ANDconst [m] x) [s]) + // cond: mergePPC64RShiftMask(m>>uint(s),s,32) == 0 + // result: (MOVDconst [0]) + for { + s := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64ANDconst { + break + } + m := auxIntToInt64(v_0.AuxInt) + if !(mergePPC64RShiftMask(m>>uint(s), s, 32) == 0) { + break + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (SRWconst (ANDconst [m] x) [s]) + // cond: mergePPC64AndSrwi(m>>uint(s),s) != 0 + // result: (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x) + for { + s := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64ANDconst { + break + } + m := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(mergePPC64AndSrwi(m>>uint(s), s) != 0) { + break + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m>>uint(s), s)) + v.AddArg(x) + return true + } + // match: (SRWconst (AND (MOVDconst [m]) x) [s]) + // cond: mergePPC64RShiftMask(m>>uint(s),s,32) == 0 + // result: (MOVDconst [0]) + for { + s := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64AND { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + if v_0_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0_0.AuxInt) + if !(mergePPC64RShiftMask(m>>uint(s), s, 32) == 0) { + continue + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + break + } + // match: (SRWconst (AND (MOVDconst [m]) x) [s]) + // cond: mergePPC64AndSrwi(m>>uint(s),s) != 0 + // result: (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x) + for { + s := auxIntToInt64(v.AuxInt) + if v_0.Op != OpPPC64AND { + break + } + _ = v_0.Args[1] + v_0_0 := v_0.Args[0] + v_0_1 := v_0.Args[1] + for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { + if v_0_0.Op != OpPPC64MOVDconst { + continue + } + m := auxIntToInt64(v_0_0.AuxInt) + x := v_0_1 + if !(mergePPC64AndSrwi(m>>uint(s), s) != 0) { + continue + } + v.reset(OpPPC64RLWINM) + v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m>>uint(s), s)) + v.AddArg(x) + return true + } + break + } + return false +} func rewriteValuePPC64_OpPPC64SUB(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index c178290343..fb507b65c4 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -4,6 +4,7 @@ package ssa import "math" +import "cmd/compile/internal/types" func rewriteValueRISCV64(v *Value) bool { switch v.Op { @@ -420,8 +421,12 @@ func rewriteValueRISCV64(v *Value) bool { return rewriteValueRISCV64_OpRISCV64AND(v) case OpRISCV64MOVBUload: return rewriteValueRISCV64_OpRISCV64MOVBUload(v) + case OpRISCV64MOVBUreg: + return rewriteValueRISCV64_OpRISCV64MOVBUreg(v) case OpRISCV64MOVBload: return rewriteValueRISCV64_OpRISCV64MOVBload(v) + case OpRISCV64MOVBreg: + return rewriteValueRISCV64_OpRISCV64MOVBreg(v) case OpRISCV64MOVBstore: return rewriteValueRISCV64_OpRISCV64MOVBstore(v) case OpRISCV64MOVBstorezero: @@ -430,22 +435,32 @@ func rewriteValueRISCV64(v *Value) bool { return rewriteValueRISCV64_OpRISCV64MOVDconst(v) case OpRISCV64MOVDload: return rewriteValueRISCV64_OpRISCV64MOVDload(v) + case OpRISCV64MOVDreg: + return rewriteValueRISCV64_OpRISCV64MOVDreg(v) case OpRISCV64MOVDstore: return rewriteValueRISCV64_OpRISCV64MOVDstore(v) case OpRISCV64MOVDstorezero: return rewriteValueRISCV64_OpRISCV64MOVDstorezero(v) case OpRISCV64MOVHUload: return rewriteValueRISCV64_OpRISCV64MOVHUload(v) + case OpRISCV64MOVHUreg: + return rewriteValueRISCV64_OpRISCV64MOVHUreg(v) case OpRISCV64MOVHload: return rewriteValueRISCV64_OpRISCV64MOVHload(v) + case OpRISCV64MOVHreg: + return rewriteValueRISCV64_OpRISCV64MOVHreg(v) case OpRISCV64MOVHstore: return rewriteValueRISCV64_OpRISCV64MOVHstore(v) case OpRISCV64MOVHstorezero: return rewriteValueRISCV64_OpRISCV64MOVHstorezero(v) case OpRISCV64MOVWUload: return rewriteValueRISCV64_OpRISCV64MOVWUload(v) + case OpRISCV64MOVWUreg: + return rewriteValueRISCV64_OpRISCV64MOVWUreg(v) case OpRISCV64MOVWload: return rewriteValueRISCV64_OpRISCV64MOVWload(v) + case OpRISCV64MOVWreg: + return rewriteValueRISCV64_OpRISCV64MOVWreg(v) case OpRISCV64MOVWstore: return rewriteValueRISCV64_OpRISCV64MOVWstore(v) case OpRISCV64MOVWstorezero: @@ -543,17 +558,23 @@ func rewriteValueRISCV64(v *Value) bool { case OpRsh8x8: return rewriteValueRISCV64_OpRsh8x8(v) case OpSignExt16to32: - return rewriteValueRISCV64_OpSignExt16to32(v) + v.Op = OpRISCV64MOVHreg + return true case OpSignExt16to64: - return rewriteValueRISCV64_OpSignExt16to64(v) + v.Op = OpRISCV64MOVHreg + return true case OpSignExt32to64: - return rewriteValueRISCV64_OpSignExt32to64(v) + v.Op = OpRISCV64MOVWreg + return true case OpSignExt8to16: - return rewriteValueRISCV64_OpSignExt8to16(v) + v.Op = OpRISCV64MOVBreg + return true case OpSignExt8to32: - return rewriteValueRISCV64_OpSignExt8to32(v) + v.Op = OpRISCV64MOVBreg + return true case OpSignExt8to64: - return rewriteValueRISCV64_OpSignExt8to64(v) + v.Op = OpRISCV64MOVBreg + return true case OpSlicemask: return rewriteValueRISCV64_OpSlicemask(v) case OpSqrt: @@ -621,17 +642,23 @@ func rewriteValueRISCV64(v *Value) bool { case OpZero: return rewriteValueRISCV64_OpZero(v) case OpZeroExt16to32: - return rewriteValueRISCV64_OpZeroExt16to32(v) + v.Op = OpRISCV64MOVHUreg + return true case OpZeroExt16to64: - return rewriteValueRISCV64_OpZeroExt16to64(v) + v.Op = OpRISCV64MOVHUreg + return true case OpZeroExt32to64: - return rewriteValueRISCV64_OpZeroExt32to64(v) + v.Op = OpRISCV64MOVWUreg + return true case OpZeroExt8to16: - return rewriteValueRISCV64_OpZeroExt8to16(v) + v.Op = OpRISCV64MOVBUreg + return true case OpZeroExt8to32: - return rewriteValueRISCV64_OpZeroExt8to32(v) + v.Op = OpRISCV64MOVBUreg + return true case OpZeroExt8to64: - return rewriteValueRISCV64_OpZeroExt8to64(v) + v.Op = OpRISCV64MOVBUreg + return true } return false } @@ -844,15 +871,17 @@ func rewriteValueRISCV64_OpEq16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Eq16 x y) - // result: (SEQZ (ZeroExt16to64 (SUB <x.Type> x y))) + // result: (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y))) for { x := v_0 y := v_1 v.reset(OpRISCV64SEQZ) - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) - v1.AddArg2(x, y) - v0.AddArg(v1) + v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v1.AddArg(x) + v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v2.AddArg(y) + v0.AddArg2(v1, v2) v.AddArg(v0) return true } @@ -895,15 +924,17 @@ func rewriteValueRISCV64_OpEq8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Eq8 x y) - // result: (SEQZ (ZeroExt8to64 (SUB <x.Type> x y))) + // result: (SEQZ (SUB <x.Type> (ZeroExt8to64 x) (ZeroExt8to64 y))) for { x := v_0 y := v_1 v.reset(OpRISCV64SEQZ) - v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) - v1.AddArg2(x, y) - v0.AddArg(v1) + v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v1.AddArg(x) + v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v2.AddArg(y) + v0.AddArg2(v1, v2) v.AddArg(v0) return true } @@ -990,11 +1021,12 @@ func rewriteValueRISCV64_OpIsNonNil(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (IsNonNil p) - // result: (NeqPtr (MOVDconst) p) + // result: (NeqPtr (MOVDconst [0]) p) for { p := v_0 v.reset(OpNeqPtr) v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(0) v.AddArg2(v0, p) return true } @@ -1941,51 +1973,414 @@ func rewriteValueRISCV64_OpMove(v *Value) bool { v.AddArg3(dst, v0, mem) return true } - // match: (Move [2] dst src mem) + // match: (Move [2] {t} dst src mem) + // cond: t.Alignment()%2 == 0 // result: (MOVHstore dst (MOVHload src mem) mem) for { if auxIntToInt64(v.AuxInt) != 2 { break } + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 + if !(t.Alignment()%2 == 0) { + break + } v.reset(OpRISCV64MOVHstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) v0.AddArg2(src, mem) v.AddArg3(dst, v0, mem) return true } - // match: (Move [4] dst src mem) + // match: (Move [2] dst src mem) + // result: (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem)) + for { + if auxIntToInt64(v.AuxInt) != 2 { + break + } + dst := v_0 + src := v_1 + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(1) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v0.AuxInt = int32ToAuxInt(1) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v2.AddArg2(src, mem) + v1.AddArg3(dst, v2, mem) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [4] {t} dst src mem) + // cond: t.Alignment()%4 == 0 // result: (MOVWstore dst (MOVWload src mem) mem) for { if auxIntToInt64(v.AuxInt) != 4 { break } + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 + if !(t.Alignment()%4 == 0) { + break + } v.reset(OpRISCV64MOVWstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) v0.AddArg2(src, mem) v.AddArg3(dst, v0, mem) return true } - // match: (Move [8] dst src mem) + // match: (Move [4] {t} dst src mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem)) + for { + if auxIntToInt64(v.AuxInt) != 4 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(2) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v0.AuxInt = int32ToAuxInt(2) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v2.AddArg2(src, mem) + v1.AddArg3(dst, v2, mem) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [4] dst src mem) + // result: (MOVBstore [3] dst (MOVBload [3] src mem) (MOVBstore [2] dst (MOVBload [2] src mem) (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem)))) + for { + if auxIntToInt64(v.AuxInt) != 4 { + break + } + dst := v_0 + src := v_1 + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(3) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v0.AuxInt = int32ToAuxInt(3) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(2) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v2.AuxInt = int32ToAuxInt(2) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v3.AuxInt = int32ToAuxInt(1) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v4.AuxInt = int32ToAuxInt(1) + v4.AddArg2(src, mem) + v5 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v6 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v6.AddArg2(src, mem) + v5.AddArg3(dst, v6, mem) + v3.AddArg3(dst, v4, v5) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [8] {t} dst src mem) + // cond: t.Alignment()%8 == 0 // result: (MOVDstore dst (MOVDload src mem) mem) for { if auxIntToInt64(v.AuxInt) != 8 { break } + t := auxToType(v.Aux) dst := v_0 src := v_1 mem := v_2 + if !(t.Alignment()%8 == 0) { + break + } v.reset(OpRISCV64MOVDstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) v0.AddArg2(src, mem) v.AddArg3(dst, v0, mem) return true } + // match: (Move [8] {t} dst src mem) + // cond: t.Alignment()%4 == 0 + // result: (MOVWstore [4] dst (MOVWload [4] src mem) (MOVWstore dst (MOVWload src mem) mem)) + for { + if auxIntToInt64(v.AuxInt) != 8 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%4 == 0) { + break + } + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(4) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) + v0.AuxInt = int32ToAuxInt(4) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) + v2.AddArg2(src, mem) + v1.AddArg3(dst, v2, mem) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [8] {t} dst src mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [6] dst (MOVHload [6] src mem) (MOVHstore [4] dst (MOVHload [4] src mem) (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem)))) + for { + if auxIntToInt64(v.AuxInt) != 8 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(6) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v0.AuxInt = int32ToAuxInt(6) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(4) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v2.AuxInt = int32ToAuxInt(4) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v3.AuxInt = int32ToAuxInt(2) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v4.AuxInt = int32ToAuxInt(2) + v4.AddArg2(src, mem) + v5 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v6 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v6.AddArg2(src, mem) + v5.AddArg3(dst, v6, mem) + v3.AddArg3(dst, v4, v5) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [3] dst src mem) + // result: (MOVBstore [2] dst (MOVBload [2] src mem) (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem))) + for { + if auxIntToInt64(v.AuxInt) != 3 { + break + } + dst := v_0 + src := v_1 + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(2) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v0.AuxInt = int32ToAuxInt(2) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(1) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v2.AuxInt = int32ToAuxInt(1) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVBload, typ.Int8) + v4.AddArg2(src, mem) + v3.AddArg3(dst, v4, mem) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [6] {t} dst src mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [4] dst (MOVHload [4] src mem) (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem))) + for { + if auxIntToInt64(v.AuxInt) != 6 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(4) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v0.AuxInt = int32ToAuxInt(4) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(2) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v2.AuxInt = int32ToAuxInt(2) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVHload, typ.Int16) + v4.AddArg2(src, mem) + v3.AddArg3(dst, v4, mem) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [12] {t} dst src mem) + // cond: t.Alignment()%4 == 0 + // result: (MOVWstore [8] dst (MOVWload [8] src mem) (MOVWstore [4] dst (MOVWload [4] src mem) (MOVWstore dst (MOVWload src mem) mem))) + for { + if auxIntToInt64(v.AuxInt) != 12 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%4 == 0) { + break + } + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(8) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) + v0.AuxInt = int32ToAuxInt(8) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(4) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) + v2.AuxInt = int32ToAuxInt(4) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVWload, typ.Int32) + v4.AddArg2(src, mem) + v3.AddArg3(dst, v4, mem) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [16] {t} dst src mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [8] dst (MOVDload [8] src mem) (MOVDstore dst (MOVDload src mem) mem)) + for { + if auxIntToInt64(v.AuxInt) != 16 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(8) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v0.AuxInt = int32ToAuxInt(8) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v2.AddArg2(src, mem) + v1.AddArg3(dst, v2, mem) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [24] {t} dst src mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [16] dst (MOVDload [16] src mem) (MOVDstore [8] dst (MOVDload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))) + for { + if auxIntToInt64(v.AuxInt) != 24 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(16) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v0.AuxInt = int32ToAuxInt(16) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(8) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v2.AuxInt = int32ToAuxInt(8) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v4.AddArg2(src, mem) + v3.AddArg3(dst, v4, mem) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [32] {t} dst src mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [24] dst (MOVDload [24] src mem) (MOVDstore [16] dst (MOVDload [16] src mem) (MOVDstore [8] dst (MOVDload [8] src mem) (MOVDstore dst (MOVDload src mem) mem)))) + for { + if auxIntToInt64(v.AuxInt) != 32 { + break + } + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(24) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v0.AuxInt = int32ToAuxInt(24) + v0.AddArg2(src, mem) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(16) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v2.AuxInt = int32ToAuxInt(16) + v2.AddArg2(src, mem) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v3.AuxInt = int32ToAuxInt(8) + v4 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v4.AuxInt = int32ToAuxInt(8) + v4.AddArg2(src, mem) + v5 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v6 := b.NewValue0(v.Pos, OpRISCV64MOVDload, typ.Int64) + v6.AddArg2(src, mem) + v5.AddArg3(dst, v6, mem) + v3.AddArg3(dst, v4, v5) + v1.AddArg3(dst, v2, v3) + v.AddArg3(dst, v0, v1) + return true + } + // match: (Move [s] {t} dst src mem) + // cond: s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice && logLargeCopy(v, s) + // result: (DUFFCOPY [16 * (128 - s/8)] dst src mem) + for { + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) + dst := v_0 + src := v_1 + mem := v_2 + if !(s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) { + break + } + v.reset(OpRISCV64DUFFCOPY) + v.AuxInt = int64ToAuxInt(16 * (128 - s/8)) + v.AddArg3(dst, src, mem) + return true + } // match: (Move [s] {t} dst src mem) // cond: (s <= 16 || logLargeCopy(v, s)) // result: (LoweredMove [t.Alignment()] dst src (ADDI <src.Type> [s-moveSize(t.Alignment(), config)] src) mem) @@ -2052,15 +2447,17 @@ func rewriteValueRISCV64_OpNeq16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Neq16 x y) - // result: (SNEZ (ZeroExt16to64 (SUB <x.Type> x y))) + // result: (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y))) for { x := v_0 y := v_1 v.reset(OpRISCV64SNEZ) - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) - v1.AddArg2(x, y) - v0.AddArg(v1) + v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v1.AddArg(x) + v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v2.AddArg(y) + v0.AddArg2(v1, v2) v.AddArg(v0) return true } @@ -2103,15 +2500,17 @@ func rewriteValueRISCV64_OpNeq8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Neq8 x y) - // result: (SNEZ (ZeroExt8to64 (SUB <x.Type> x y))) + // result: (SNEZ (SUB <x.Type> (ZeroExt8to64 x) (ZeroExt8to64 y))) for { x := v_0 y := v_1 v.reset(OpRISCV64SNEZ) - v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) - v1.AddArg2(x, y) - v0.AddArg(v1) + v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v1.AddArg(x) + v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v2.AddArg(y) + v0.AddArg2(v1, v2) v.AddArg(v0) return true } @@ -2415,7 +2814,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBUload(v *Value) bool { v_0 := v.Args[0] // match: (MOVBUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2431,7 +2830,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBUload(v *Value) bool { } v.reset(OpRISCV64MOVBUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2458,12 +2857,74 @@ func rewriteValueRISCV64_OpRISCV64MOVBUload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVBUreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVBUreg (MOVBconst [c])) + // result: (MOVDconst [int64(uint8(c))]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint8(c))) + return true + } + // match: (MOVBUreg x:(MOVBUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVBUreg x:(MOVBUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVBUreg <t> x:(MOVBload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVBUload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVBload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVBUload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVBload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVBload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2479,7 +2940,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBload(v *Value) bool { } v.reset(OpRISCV64MOVBload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2506,13 +2967,75 @@ func rewriteValueRISCV64_OpRISCV64MOVBload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVBreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVBreg (MOVBconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVBreg x:(MOVBload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVBreg x:(MOVBreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVBreg <t> x:(MOVBUload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVBload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVBload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVBstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVBstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2529,7 +3052,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBstore(v *Value) bool { } v.reset(OpRISCV64MOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2571,6 +3094,108 @@ func rewriteValueRISCV64_OpRISCV64MOVBstore(v *Value) bool { v.AddArg2(ptr, mem) return true } + // match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVBreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVHreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVBstore [off] {sym} ptr (MOVWreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVBUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVHUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVBstore [off] {sym} ptr (MOVWUreg x) mem) + // result: (MOVBstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVBstorezero(v *Value) bool { @@ -2578,7 +3203,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBstorezero(v *Value) bool { v_0 := v.Args[0] // match: (MOVBstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVBstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2594,7 +3219,7 @@ func rewriteValueRISCV64_OpRISCV64MOVBstorezero(v *Value) bool { } v.reset(OpRISCV64MOVBstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2671,7 +3296,7 @@ func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool { v_0 := v.Args[0] // match: (MOVDload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2687,7 +3312,7 @@ func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool { } v.reset(OpRISCV64MOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2714,13 +3339,29 @@ func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVDreg(v *Value) bool { + v_0 := v.Args[0] + // match: (MOVDreg x) + // cond: x.Uses == 1 + // result: (MOVDnop x) + for { + x := v_0 + if !(x.Uses == 1) { + break + } + v.reset(OpRISCV64MOVDnop) + v.AddArg(x) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVDstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVDstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2737,7 +3378,7 @@ func rewriteValueRISCV64_OpRISCV64MOVDstore(v *Value) bool { } v.reset(OpRISCV64MOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2786,7 +3427,7 @@ func rewriteValueRISCV64_OpRISCV64MOVDstorezero(v *Value) bool { v_0 := v.Args[0] // match: (MOVDstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVDstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2802,7 +3443,7 @@ func rewriteValueRISCV64_OpRISCV64MOVDstorezero(v *Value) bool { } v.reset(OpRISCV64MOVDstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -2834,7 +3475,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHUload(v *Value) bool { v_0 := v.Args[0] // match: (MOVHUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVHUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2850,7 +3491,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHUload(v *Value) bool { } v.reset(OpRISCV64MOVHUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2877,12 +3518,107 @@ func rewriteValueRISCV64_OpRISCV64MOVHUload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVHUreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVHUreg (MOVBconst [c])) + // result: (MOVDconst [int64(uint16(c))]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint16(c))) + return true + } + // match: (MOVHUreg (MOVHconst [c])) + // result: (MOVDconst [int64(uint16(c))]) + for { + if v_0.Op != OpRISCV64MOVHconst { + break + } + c := auxIntToInt16(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint16(c))) + return true + } + // match: (MOVHUreg x:(MOVBUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg x:(MOVHUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg x:(MOVBUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg x:(MOVHUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg <t> x:(MOVHload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVHUload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVHload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVHUload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVHload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVHload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2898,7 +3634,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHload(v *Value) bool { } v.reset(OpRISCV64MOVHload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -2925,13 +3661,130 @@ func rewriteValueRISCV64_OpRISCV64MOVHload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVHreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVHreg (MOVBconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVHreg (MOVHconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVHconst { + break + } + c := auxIntToInt16(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVHreg x:(MOVBload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVHload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVHreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVHreg <t> x:(MOVHUload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVHload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVHUload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVHload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVHstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVHstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -2948,7 +3801,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHstore(v *Value) bool { } v.reset(OpRISCV64MOVHstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -2990,6 +3843,74 @@ func rewriteValueRISCV64_OpRISCV64MOVHstore(v *Value) bool { v.AddArg2(ptr, mem) return true } + // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem) + // result: (MOVHstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVHreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVHstore [off] {sym} ptr (MOVWreg x) mem) + // result: (MOVHstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) + // result: (MOVHstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVHUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVHstore [off] {sym} ptr (MOVWUreg x) mem) + // result: (MOVHstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVHstorezero(v *Value) bool { @@ -2997,7 +3918,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHstorezero(v *Value) bool { v_0 := v.Args[0] // match: (MOVHstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVHstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3013,7 +3934,7 @@ func rewriteValueRISCV64_OpRISCV64MOVHstorezero(v *Value) bool { } v.reset(OpRISCV64MOVHstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -3045,7 +3966,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWUload(v *Value) bool { v_0 := v.Args[0] // match: (MOVWUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVWUload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3061,7 +3982,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWUload(v *Value) bool { } v.reset(OpRISCV64MOVWUload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3088,12 +4009,140 @@ func rewriteValueRISCV64_OpRISCV64MOVWUload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVWUreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVWUreg (MOVBconst [c])) + // result: (MOVDconst [int64(uint32(c))]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint32(c))) + return true + } + // match: (MOVWUreg (MOVHconst [c])) + // result: (MOVDconst [int64(uint32(c))]) + for { + if v_0.Op != OpRISCV64MOVHconst { + break + } + c := auxIntToInt16(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint32(c))) + return true + } + // match: (MOVWUreg (MOVWconst [c])) + // result: (MOVDconst [int64(uint32(c))]) + for { + if v_0.Op != OpRISCV64MOVWconst { + break + } + c := auxIntToInt32(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(uint32(c))) + return true + } + // match: (MOVWUreg x:(MOVBUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg x:(MOVHUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg x:(MOVWUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVWUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg x:(MOVBUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg x:(MOVHUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg x:(MOVWUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVWUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWUreg <t> x:(MOVWload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVWUload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVWload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVWUload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVWload(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVWload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3109,7 +4158,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWload(v *Value) bool { } v.reset(OpRISCV64MOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -3136,13 +4185,174 @@ func rewriteValueRISCV64_OpRISCV64MOVWload(v *Value) bool { } return false } +func rewriteValueRISCV64_OpRISCV64MOVWreg(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (MOVWreg (MOVBconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVBconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVWreg (MOVHconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVHconst { + break + } + c := auxIntToInt16(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVWreg (MOVWconst [c])) + // result: (MOVDconst [int64(c)]) + for { + if v_0.Op != OpRISCV64MOVWconst { + break + } + c := auxIntToInt32(v_0.AuxInt) + v.reset(OpRISCV64MOVDconst) + v.AuxInt = int64ToAuxInt(int64(c)) + return true + } + // match: (MOVWreg x:(MOVBload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVBUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVHload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVHUload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHUload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVWload _ _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVWload { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVBreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVBUreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVBUreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVHreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVHreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg x:(MOVWreg _)) + // result: (MOVDreg x) + for { + x := v_0 + if x.Op != OpRISCV64MOVWreg { + break + } + v.reset(OpRISCV64MOVDreg) + v.AddArg(x) + return true + } + // match: (MOVWreg <t> x:(MOVWUload [off] {sym} ptr mem)) + // cond: x.Uses == 1 && clobber(x) + // result: @x.Block (MOVWload <t> [off] {sym} ptr mem) + for { + t := v.Type + x := v_0 + if x.Op != OpRISCV64MOVWUload { + break + } + off := auxIntToInt32(x.AuxInt) + sym := auxToSym(x.Aux) + mem := x.Args[1] + ptr := x.Args[0] + if !(x.Uses == 1 && clobber(x)) { + break + } + b = x.Block + v0 := b.NewValue0(x.Pos, OpRISCV64MOVWload, t) + v.copyOf(v0) + v0.AuxInt = int32ToAuxInt(off) + v0.Aux = symToAux(sym) + v0.AddArg2(ptr, mem) + return true + } + return false +} func rewriteValueRISCV64_OpRISCV64MOVWstore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] // match: (MOVWstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3159,7 +4369,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWstore(v *Value) bool { } v.reset(OpRISCV64MOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -3201,6 +4411,40 @@ func rewriteValueRISCV64_OpRISCV64MOVWstore(v *Value) bool { v.AddArg2(ptr, mem) return true } + // match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem) + // result: (MOVWstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } + // match: (MOVWstore [off] {sym} ptr (MOVWUreg x) mem) + // result: (MOVWstore [off] {sym} ptr x mem) + for { + off := auxIntToInt32(v.AuxInt) + sym := auxToSym(v.Aux) + ptr := v_0 + if v_1.Op != OpRISCV64MOVWUreg { + break + } + x := v_1.Args[0] + mem := v_2 + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(off) + v.Aux = symToAux(sym) + v.AddArg3(ptr, x, mem) + return true + } return false } func rewriteValueRISCV64_OpRISCV64MOVWstorezero(v *Value) bool { @@ -3208,7 +4452,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWstorezero(v *Value) bool { v_0 := v.Args[0] // match: (MOVWstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) - // result: (MOVWstorezero [off1+off2] {mergeSymTyped(sym1,sym2)} ptr mem) + // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -3224,7 +4468,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWstorezero(v *Value) bool { } v.reset(OpRISCV64MOVWstorezero) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -4719,103 +5963,6 @@ func rewriteValueRISCV64_OpRsh8x8(v *Value) bool { return true } } -func rewriteValueRISCV64_OpSignExt16to32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (SignExt16to32 <t> x) - // result: (SRAI [48] (SLLI <t> [48] x)) - for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRAI) - v.AuxInt = int64ToAuxInt(48) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(48) - v0.AddArg(x) - v.AddArg(v0) - return true - } -} -func rewriteValueRISCV64_OpSignExt16to64(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (SignExt16to64 <t> x) - // result: (SRAI [48] (SLLI <t> [48] x)) - for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRAI) - v.AuxInt = int64ToAuxInt(48) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(48) - v0.AddArg(x) - v.AddArg(v0) - return true - } -} -func rewriteValueRISCV64_OpSignExt32to64(v *Value) bool { - v_0 := v.Args[0] - // match: (SignExt32to64 <t> x) - // result: (ADDIW [0] x) - for { - x := v_0 - v.reset(OpRISCV64ADDIW) - v.AuxInt = int64ToAuxInt(0) - v.AddArg(x) - return true - } -} -func rewriteValueRISCV64_OpSignExt8to16(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (SignExt8to16 <t> x) - // result: (SRAI [56] (SLLI <t> [56] x)) - for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRAI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) - return true - } -} -func rewriteValueRISCV64_OpSignExt8to32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (SignExt8to32 <t> x) - // result: (SRAI [56] (SLLI <t> [56] x)) - for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRAI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) - return true - } -} -func rewriteValueRISCV64_OpSignExt8to64(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (SignExt8to64 <t> x) - // result: (SRAI [56] (SLLI <t> [56] x)) - for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRAI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) - return true - } -} func rewriteValueRISCV64_OpSlicemask(v *Value) bool { v_0 := v.Args[0] b := v.Block @@ -4948,7 +6095,7 @@ func rewriteValueRISCV64_OpZero(v *Value) bool { return true } // match: (Zero [1] ptr mem) - // result: (MOVBstore ptr (MOVBconst) mem) + // result: (MOVBstore ptr (MOVBconst [0]) mem) for { if auxIntToInt64(v.AuxInt) != 1 { break @@ -4957,164 +6104,354 @@ func rewriteValueRISCV64_OpZero(v *Value) bool { mem := v_1 v.reset(OpRISCV64MOVBstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8) + v0.AuxInt = int8ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } - // match: (Zero [2] ptr mem) - // result: (MOVHstore ptr (MOVHconst) mem) + // match: (Zero [2] {t} ptr mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore ptr (MOVHconst [0]) mem) for { if auxIntToInt64(v.AuxInt) != 2 { break } + t := auxToType(v.Aux) ptr := v_0 mem := v_1 + if !(t.Alignment()%2 == 0) { + break + } v.reset(OpRISCV64MOVHstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16) + v0.AuxInt = int16ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } - // match: (Zero [4] ptr mem) - // result: (MOVWstore ptr (MOVWconst) mem) + // match: (Zero [2] ptr mem) + // result: (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem)) + for { + if auxIntToInt64(v.AuxInt) != 2 { + break + } + ptr := v_0 + mem := v_1 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(1) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8) + v0.AuxInt = int8ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v1.AddArg3(ptr, v0, mem) + v.AddArg3(ptr, v0, v1) + return true + } + // match: (Zero [4] {t} ptr mem) + // cond: t.Alignment()%4 == 0 + // result: (MOVWstore ptr (MOVWconst [0]) mem) for { if auxIntToInt64(v.AuxInt) != 4 { break } + t := auxToType(v.Aux) ptr := v_0 mem := v_1 + if !(t.Alignment()%4 == 0) { + break + } v.reset(OpRISCV64MOVWstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32) + v0.AuxInt = int32ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } - // match: (Zero [8] ptr mem) - // result: (MOVDstore ptr (MOVDconst) mem) + // match: (Zero [4] {t} ptr mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem)) + for { + if auxIntToInt64(v.AuxInt) != 4 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(2) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16) + v0.AuxInt = int16ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v1.AddArg3(ptr, v0, mem) + v.AddArg3(ptr, v0, v1) + return true + } + // match: (Zero [4] ptr mem) + // result: (MOVBstore [3] ptr (MOVBconst [0]) (MOVBstore [2] ptr (MOVBconst [0]) (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem)))) + for { + if auxIntToInt64(v.AuxInt) != 4 { + break + } + ptr := v_0 + mem := v_1 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(3) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8) + v0.AuxInt = int8ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(2) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v2.AuxInt = int32ToAuxInt(1) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v3.AddArg3(ptr, v0, mem) + v2.AddArg3(ptr, v0, v3) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) + return true + } + // match: (Zero [8] {t} ptr mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore ptr (MOVDconst [0]) mem) for { if auxIntToInt64(v.AuxInt) != 8 { break } + t := auxToType(v.Aux) ptr := v_0 mem := v_1 + if !(t.Alignment()%8 == 0) { + break + } v.reset(OpRISCV64MOVDstore) v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(0) v.AddArg3(ptr, v0, mem) return true } - // match: (Zero [s] {t} ptr mem) - // result: (LoweredZero [t.Alignment()] ptr (ADD <ptr.Type> ptr (MOVDconst [s-moveSize(t.Alignment(), config)])) mem) + // match: (Zero [8] {t} ptr mem) + // cond: t.Alignment()%4 == 0 + // result: (MOVWstore [4] ptr (MOVWconst [0]) (MOVWstore ptr (MOVWconst [0]) mem)) for { - s := auxIntToInt64(v.AuxInt) + if auxIntToInt64(v.AuxInt) != 8 { + break + } t := auxToType(v.Aux) ptr := v_0 mem := v_1 - v.reset(OpRISCV64LoweredZero) - v.AuxInt = int64ToAuxInt(t.Alignment()) - v0 := b.NewValue0(v.Pos, OpRISCV64ADD, ptr.Type) - v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) - v1.AuxInt = int64ToAuxInt(s - moveSize(t.Alignment(), config)) - v0.AddArg2(ptr, v1) - v.AddArg3(ptr, v0, mem) + if !(t.Alignment()%4 == 0) { + break + } + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(4) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32) + v0.AuxInt = int32ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v1.AddArg3(ptr, v0, mem) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt16to32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt16to32 <t> x) - // result: (SRLI [48] (SLLI <t> [48] x)) + // match: (Zero [8] {t} ptr mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [6] ptr (MOVHconst [0]) (MOVHstore [4] ptr (MOVHconst [0]) (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem)))) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(48) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(48) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 8 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(6) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16) + v0.AuxInt = int16ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(4) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v2.AuxInt = int32ToAuxInt(2) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v3.AddArg3(ptr, v0, mem) + v2.AddArg3(ptr, v0, v3) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt16to64(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt16to64 <t> x) - // result: (SRLI [48] (SLLI <t> [48] x)) + // match: (Zero [3] ptr mem) + // result: (MOVBstore [2] ptr (MOVBconst [0]) (MOVBstore [1] ptr (MOVBconst [0]) (MOVBstore ptr (MOVBconst [0]) mem))) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(48) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(48) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 3 { + break + } + ptr := v_0 + mem := v_1 + v.reset(OpRISCV64MOVBstore) + v.AuxInt = int32ToAuxInt(2) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVBconst, typ.UInt8) + v0.AuxInt = int8ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(1) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVBstore, types.TypeMem) + v2.AddArg3(ptr, v0, mem) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt32to64(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt32to64 <t> x) - // result: (SRLI [32] (SLLI <t> [32] x)) + // match: (Zero [6] {t} ptr mem) + // cond: t.Alignment()%2 == 0 + // result: (MOVHstore [4] ptr (MOVHconst [0]) (MOVHstore [2] ptr (MOVHconst [0]) (MOVHstore ptr (MOVHconst [0]) mem))) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(32) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(32) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 6 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%2 == 0) { + break + } + v.reset(OpRISCV64MOVHstore) + v.AuxInt = int32ToAuxInt(4) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVHconst, typ.UInt16) + v0.AuxInt = int16ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(2) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVHstore, types.TypeMem) + v2.AddArg3(ptr, v0, mem) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt8to16(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt8to16 <t> x) - // result: (SRLI [56] (SLLI <t> [56] x)) + // match: (Zero [12] {t} ptr mem) + // cond: t.Alignment()%4 == 0 + // result: (MOVWstore [8] ptr (MOVWconst [0]) (MOVWstore [4] ptr (MOVWconst [0]) (MOVWstore ptr (MOVWconst [0]) mem))) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 12 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%4 == 0) { + break + } + v.reset(OpRISCV64MOVWstore) + v.AuxInt = int32ToAuxInt(8) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVWconst, typ.UInt32) + v0.AuxInt = int32ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(4) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVWstore, types.TypeMem) + v2.AddArg3(ptr, v0, mem) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt8to32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt8to32 <t> x) - // result: (SRLI [56] (SLLI <t> [56] x)) + // match: (Zero [16] {t} ptr mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem)) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 16 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(8) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v1.AddArg3(ptr, v0, mem) + v.AddArg3(ptr, v0, v1) return true } -} -func rewriteValueRISCV64_OpZeroExt8to64(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - // match: (ZeroExt8to64 <t> x) - // result: (SRLI [56] (SLLI <t> [56] x)) + // match: (Zero [24] {t} ptr mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [16] ptr (MOVDconst [0]) (MOVDstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))) for { - t := v.Type - x := v_0 - v.reset(OpRISCV64SRLI) - v.AuxInt = int64ToAuxInt(56) - v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, t) - v0.AuxInt = int64ToAuxInt(56) - v0.AddArg(x) - v.AddArg(v0) + if auxIntToInt64(v.AuxInt) != 24 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(16) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(8) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v2.AddArg3(ptr, v0, mem) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) + return true + } + // match: (Zero [32] {t} ptr mem) + // cond: t.Alignment()%8 == 0 + // result: (MOVDstore [24] ptr (MOVDconst [0]) (MOVDstore [16] ptr (MOVDconst [0]) (MOVDstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem)))) + for { + if auxIntToInt64(v.AuxInt) != 32 { + break + } + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(t.Alignment()%8 == 0) { + break + } + v.reset(OpRISCV64MOVDstore) + v.AuxInt = int32ToAuxInt(24) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(0) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v1.AuxInt = int32ToAuxInt(16) + v2 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v2.AuxInt = int32ToAuxInt(8) + v3 := b.NewValue0(v.Pos, OpRISCV64MOVDstore, types.TypeMem) + v3.AddArg3(ptr, v0, mem) + v2.AddArg3(ptr, v0, v3) + v1.AddArg3(ptr, v0, v2) + v.AddArg3(ptr, v0, v1) + return true + } + // match: (Zero [s] {t} ptr mem) + // cond: s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice + // result: (DUFFZERO [8 * (128 - s/8)] ptr mem) + for { + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + if !(s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice) { + break + } + v.reset(OpRISCV64DUFFZERO) + v.AuxInt = int64ToAuxInt(8 * (128 - s/8)) + v.AddArg2(ptr, mem) + return true + } + // match: (Zero [s] {t} ptr mem) + // result: (LoweredZero [t.Alignment()] ptr (ADD <ptr.Type> ptr (MOVDconst [s-moveSize(t.Alignment(), config)])) mem) + for { + s := auxIntToInt64(v.AuxInt) + t := auxToType(v.Aux) + ptr := v_0 + mem := v_1 + v.reset(OpRISCV64LoweredZero) + v.AuxInt = int64ToAuxInt(t.Alignment()) + v0 := b.NewValue0(v.Pos, OpRISCV64ADD, ptr.Type) + v1 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v1.AuxInt = int64ToAuxInt(s - moveSize(t.Alignment(), config)) + v0.AddArg2(ptr, v1) + v.AddArg3(ptr, v0, mem) return true } } diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index 78a57c2388..d66113d111 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -49,6 +49,9 @@ func rewriteValueS390X(v *Value) bool { return rewriteValueS390X_OpAtomicAdd32(v) case OpAtomicAdd64: return rewriteValueS390X_OpAtomicAdd64(v) + case OpAtomicAnd32: + v.Op = OpS390XLAN + return true case OpAtomicAnd8: return rewriteValueS390X_OpAtomicAnd8(v) case OpAtomicCompareAndSwap32: @@ -69,6 +72,9 @@ func rewriteValueS390X(v *Value) bool { return rewriteValueS390X_OpAtomicLoadAcq32(v) case OpAtomicLoadPtr: return rewriteValueS390X_OpAtomicLoadPtr(v) + case OpAtomicOr32: + v.Op = OpS390XLAO + return true case OpAtomicOr8: return rewriteValueS390X_OpAtomicOr8(v) case OpAtomicStore32: @@ -693,6 +699,8 @@ func rewriteValueS390X(v *Value) bool { return rewriteValueS390X_OpS390XORconst(v) case OpS390XORload: return rewriteValueS390X_OpS390XORload(v) + case OpS390XRISBGZ: + return rewriteValueS390X_OpS390XRISBGZ(v) case OpS390XRLL: return rewriteValueS390X_OpS390XRLL(v) case OpS390XRLLG: @@ -5266,9 +5274,8 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool { } break } - // match: (ADD (SLDconst x [c]) (SRDconst x [d])) - // cond: d == 64-c - // result: (RLLGconst [c] x) + // match: (ADD (SLDconst x [c]) (SRDconst x [64-c])) + // result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)}) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLDconst { @@ -5276,15 +5283,11 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRDconst { - continue - } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 64-c) { + if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] { continue } - v.reset(OpS390XRLLGconst) - v.AuxInt = int8ToAuxInt(c) + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c)) v.AddArg(x) return true } @@ -5464,9 +5467,8 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool { } break } - // match: (ADDW (SLWconst x [c]) (SRWconst x [d])) - // cond: d == 32-c - // result: (RLLconst [c] x) + // match: (ADDW (SLWconst x [c]) (SRWconst x [32-c])) + // result: (RLLconst x [c]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLWconst { @@ -5474,11 +5476,7 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRWconst { - continue - } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 32-c) { + if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] { continue } v.reset(OpS390XRLLconst) @@ -5629,7 +5627,7 @@ func rewriteValueS390X_OpS390XADDWload(v *Value) bool { } // match: (ADDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ADDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ADDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -5646,7 +5644,7 @@ func rewriteValueS390X_OpS390XADDWload(v *Value) bool { } v.reset(OpS390XADDWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -5809,7 +5807,7 @@ func rewriteValueS390X_OpS390XADDload(v *Value) bool { } // match: (ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ADDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ADDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -5826,7 +5824,7 @@ func rewriteValueS390X_OpS390XADDload(v *Value) bool { } v.reset(OpS390XADDload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -5838,8 +5836,8 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (AND x (MOVDconst [c])) - // cond: is32Bit(c) && c < 0 - // result: (ANDconst [c] x) + // cond: s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c)) != nil + // result: (RISBGZ x {*s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c))}) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 @@ -5847,19 +5845,19 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool { continue } c := auxIntToInt64(v_1.AuxInt) - if !(is32Bit(c) && c < 0) { + if !(s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c)) != nil) { continue } - v.reset(OpS390XANDconst) - v.AuxInt = int64ToAuxInt(c) + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c))) v.AddArg(x) return true } break } // match: (AND x (MOVDconst [c])) - // cond: is32Bit(c) && c >= 0 - // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x)) + // cond: is32Bit(c) && c < 0 + // result: (ANDconst [c] x) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 @@ -5867,72 +5865,32 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool { continue } c := auxIntToInt64(v_1.AuxInt) - if !(is32Bit(c) && c >= 0) { - continue - } - v.reset(OpS390XMOVWZreg) - v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32) - v0.AuxInt = int32ToAuxInt(int32(c)) - v0.AddArg(x) - v.AddArg(v0) - return true - } - break - } - // match: (AND x (MOVDconst [0xFF])) - // result: (MOVBZreg x) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - x := v_0 - if v_1.Op != OpS390XMOVDconst || auxIntToInt64(v_1.AuxInt) != 0xFF { + if !(is32Bit(c) && c < 0) { continue } - v.reset(OpS390XMOVBZreg) + v.reset(OpS390XANDconst) + v.AuxInt = int64ToAuxInt(c) v.AddArg(x) return true } break } - // match: (AND x (MOVDconst [0xFFFF])) - // result: (MOVHZreg x) + // match: (AND x (MOVDconst [c])) + // cond: is32Bit(c) && c >= 0 + // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x)) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { x := v_0 - if v_1.Op != OpS390XMOVDconst || auxIntToInt64(v_1.AuxInt) != 0xFFFF { + if v_1.Op != OpS390XMOVDconst { continue } - v.reset(OpS390XMOVHZreg) - v.AddArg(x) - return true - } - break - } - // match: (AND x (MOVDconst [0xFFFFFFFF])) - // result: (MOVWZreg x) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - x := v_0 - if v_1.Op != OpS390XMOVDconst || auxIntToInt64(v_1.AuxInt) != 0xFFFFFFFF { + c := auxIntToInt64(v_1.AuxInt) + if !(is32Bit(c) && c >= 0) { continue } v.reset(OpS390XMOVWZreg) - v.AddArg(x) - return true - } - break - } - // match: (AND (MOVDconst [^(-1<<63)]) (LGDR <t> x)) - // result: (LGDR <t> (LPDFR <x.Type> x)) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_0.Op != OpS390XMOVDconst || auxIntToInt64(v_0.AuxInt) != ^(-1<<63) || v_1.Op != OpS390XLGDR { - continue - } - t := v_1.Type - x := v_1.Args[0] - v.reset(OpS390XLGDR) - v.Type = t - v0 := b.NewValue0(v.Pos, OpS390XLPDFR, x.Type) + v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32) + v0.AuxInt = int32ToAuxInt(int32(c)) v0.AddArg(x) v.AddArg(v0) return true @@ -6097,10 +6055,10 @@ func rewriteValueS390X_OpS390XANDWconst(v *Value) bool { v.AddArg(x) return true } - // match: (ANDWconst [0xFF] x) + // match: (ANDWconst [0x00ff] x) // result: (MOVBZreg x) for { - if auxIntToInt32(v.AuxInt) != 0xFF { + if auxIntToInt32(v.AuxInt) != 0x00ff { break } x := v_0 @@ -6108,10 +6066,10 @@ func rewriteValueS390X_OpS390XANDWconst(v *Value) bool { v.AddArg(x) return true } - // match: (ANDWconst [0xFFFF] x) + // match: (ANDWconst [0xffff] x) // result: (MOVHZreg x) for { - if auxIntToInt32(v.AuxInt) != 0xFFFF { + if auxIntToInt32(v.AuxInt) != 0xffff { break } x := v_0 @@ -6185,7 +6143,7 @@ func rewriteValueS390X_OpS390XANDWload(v *Value) bool { } // match: (ANDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ANDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ANDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -6202,7 +6160,7 @@ func rewriteValueS390X_OpS390XANDWload(v *Value) bool { } v.reset(OpS390XANDWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -6310,7 +6268,7 @@ func rewriteValueS390X_OpS390XANDload(v *Value) bool { } // match: (ANDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ANDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ANDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -6327,7 +6285,7 @@ func rewriteValueS390X_OpS390XANDload(v *Value) bool { } v.reset(OpS390XANDload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -6509,6 +6467,21 @@ func rewriteValueS390X_OpS390XCMPUconst(v *Value) bool { v.reset(OpS390XFlagLT) return true } + // match: (CMPUconst (RISBGZ x {r}) [c]) + // cond: r.OutMask() < uint64(uint32(c)) + // result: (FlagLT) + for { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + if !(r.OutMask() < uint64(uint32(c))) { + break + } + v.reset(OpS390XFlagLT) + return true + } // match: (CMPUconst (MOVWZreg x) [c]) // result: (CMPWUconst x [c]) for { @@ -7146,6 +7119,21 @@ func rewriteValueS390X_OpS390XCMPconst(v *Value) bool { v.reset(OpS390XFlagGT) return true } + // match: (CMPconst (RISBGZ x {r}) [c]) + // cond: c > 0 && r.OutMask() < uint64(c) + // result: (FlagLT) + for { + c := auxIntToInt32(v.AuxInt) + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + if !(c > 0 && r.OutMask() < uint64(c)) { + break + } + v.reset(OpS390XFlagLT) + return true + } // match: (CMPconst (MOVWreg x) [c]) // result: (CMPWconst x [c]) for { @@ -7433,7 +7421,7 @@ func rewriteValueS390X_OpS390XFMOVDload(v *Value) bool { } // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7449,7 +7437,7 @@ func rewriteValueS390X_OpS390XFMOVDload(v *Value) bool { } v.reset(OpS390XFMOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -7483,7 +7471,7 @@ func rewriteValueS390X_OpS390XFMOVDstore(v *Value) bool { } // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7500,7 +7488,7 @@ func rewriteValueS390X_OpS390XFMOVDstore(v *Value) bool { } v.reset(OpS390XFMOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -7550,7 +7538,7 @@ func rewriteValueS390X_OpS390XFMOVSload(v *Value) bool { } // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7566,7 +7554,7 @@ func rewriteValueS390X_OpS390XFMOVSload(v *Value) bool { } v.reset(OpS390XFMOVSload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -7600,7 +7588,7 @@ func rewriteValueS390X_OpS390XFMOVSstore(v *Value) bool { } // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -7617,7 +7605,7 @@ func rewriteValueS390X_OpS390XFMOVSstore(v *Value) bool { } v.reset(OpS390XFMOVSstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -7678,47 +7666,25 @@ func rewriteValueS390X_OpS390XFNEGS(v *Value) bool { func rewriteValueS390X_OpS390XLDGR(v *Value) bool { v_0 := v.Args[0] b := v.Block - // match: (LDGR <t> (SRDconst [1] (SLDconst [1] x))) + // match: (LDGR <t> (RISBGZ x {r})) + // cond: r == s390x.NewRotateParams(1, 63, 0) // result: (LPDFR (LDGR <t> x)) for { t := v.Type - if v_0.Op != OpS390XSRDconst || auxIntToInt8(v_0.AuxInt) != 1 { + if v_0.Op != OpS390XRISBGZ { break } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpS390XSLDconst || auxIntToInt8(v_0_0.AuxInt) != 1 { + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(r == s390x.NewRotateParams(1, 63, 0)) { break } - x := v_0_0.Args[0] v.reset(OpS390XLPDFR) v0 := b.NewValue0(v.Pos, OpS390XLDGR, t) v0.AddArg(x) v.AddArg(v0) return true } - // match: (LDGR <t> (AND (MOVDconst [^(-1<<63)]) x)) - // result: (LPDFR (LDGR <t> x)) - for { - t := v.Type - if v_0.Op != OpS390XAND { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - v_0_1 := v_0.Args[1] - for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 { - if v_0_0.Op != OpS390XMOVDconst || auxIntToInt64(v_0_0.AuxInt) != ^(-1<<63) { - continue - } - x := v_0_1 - v.reset(OpS390XLPDFR) - v0 := b.NewValue0(v.Pos, OpS390XLDGR, t) - v0.AddArg(x) - v.AddArg(v0) - return true - } - break - } // match: (LDGR <t> (OR (MOVDconst [-1<<63]) x)) // result: (LNDFR (LDGR <t> x)) for { @@ -8095,7 +8061,7 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value) bool { } // match: (MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8111,7 +8077,7 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value) bool { } v.reset(OpS390XMOVBZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -8303,6 +8269,23 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value) bool { v.copyOf(x) return true } + // match: (MOVBZreg (RISBGZ x {r})) + // cond: r.OutMerge(0x000000ff) != nil + // result: (RISBGZ x {*r.OutMerge(0x000000ff)}) + for { + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(r.OutMerge(0x000000ff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.OutMerge(0x000000ff)) + v.AddArg(x) + return true + } // match: (MOVBZreg (ANDWconst [m] x)) // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x)) for { @@ -8365,7 +8348,7 @@ func rewriteValueS390X_OpS390XMOVBload(v *Value) bool { } // match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8381,7 +8364,7 @@ func rewriteValueS390X_OpS390XMOVBload(v *Value) bool { } v.reset(OpS390XMOVBload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -8652,7 +8635,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool { } // match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) - // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8669,7 +8652,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool { } v.reset(OpS390XMOVBstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -8925,7 +8908,7 @@ func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool { } // match: (MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) - // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -8941,7 +8924,7 @@ func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool { } v.reset(OpS390XMOVBstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -9019,7 +9002,7 @@ func rewriteValueS390X_OpS390XMOVDaddridx(v *Value) bool { } // match: (MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB - // result: (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9035,13 +9018,13 @@ func rewriteValueS390X_OpS390XMOVDaddridx(v *Value) bool { } v.reset(OpS390XMOVDaddridx) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } // match: (MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y)) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB - // result: (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y) + // result: (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9057,7 +9040,7 @@ func rewriteValueS390X_OpS390XMOVDaddridx(v *Value) bool { } v.reset(OpS390XMOVDaddridx) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(x, y) return true } @@ -9126,7 +9109,7 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value) bool { } // match: (MOVDload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) - // result: (MOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9143,7 +9126,7 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value) bool { } v.reset(OpS390XMOVDload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -9198,7 +9181,7 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool { } // match: (MOVDstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) - // result: (MOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9216,7 +9199,7 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool { } v.reset(OpS390XMOVDstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -9329,7 +9312,7 @@ func rewriteValueS390X_OpS390XMOVDstoreconst(v *Value) bool { } // match: (MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) - // result: (MOVDstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVDstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9345,7 +9328,7 @@ func rewriteValueS390X_OpS390XMOVDstoreconst(v *Value) bool { } v.reset(OpS390XMOVDstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -9512,7 +9495,7 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value) bool { } // match: (MOVHZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) - // result: (MOVHZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9529,7 +9512,7 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value) bool { } v.reset(OpS390XMOVHZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -9691,6 +9674,23 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool { v.AuxInt = int64ToAuxInt(int64(uint16(c))) return true } + // match: (MOVHZreg (RISBGZ x {r})) + // cond: r.OutMerge(0x0000ffff) != nil + // result: (RISBGZ x {*r.OutMerge(0x0000ffff)}) + for { + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(r.OutMerge(0x0000ffff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.OutMerge(0x0000ffff)) + v.AddArg(x) + return true + } // match: (MOVHZreg (ANDWconst [m] x)) // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x)) for { @@ -9753,7 +9753,7 @@ func rewriteValueS390X_OpS390XMOVHload(v *Value) bool { } // match: (MOVHload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) - // result: (MOVHload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -9770,7 +9770,7 @@ func rewriteValueS390X_OpS390XMOVHload(v *Value) bool { } v.reset(OpS390XMOVHload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -10047,7 +10047,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool { } // match: (MOVHstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) - // result: (MOVHstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10065,7 +10065,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool { } v.reset(OpS390XMOVHstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -10213,7 +10213,7 @@ func rewriteValueS390X_OpS390XMOVHstoreconst(v *Value) bool { } // match: (MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) - // result: (MOVHstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVHstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10229,7 +10229,7 @@ func rewriteValueS390X_OpS390XMOVHstoreconst(v *Value) bool { } v.reset(OpS390XMOVHstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -10368,7 +10368,7 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value) bool { } // match: (MOVWZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) - // result: (MOVWZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10385,7 +10385,7 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value) bool { } v.reset(OpS390XMOVWZload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -10541,6 +10541,23 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool { v.AuxInt = int64ToAuxInt(int64(uint32(c))) return true } + // match: (MOVWZreg (RISBGZ x {r})) + // cond: r.OutMerge(0xffffffff) != nil + // result: (RISBGZ x {*r.OutMerge(0xffffffff)}) + for { + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(r.OutMerge(0xffffffff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.OutMerge(0xffffffff)) + v.AddArg(x) + return true + } return false } func rewriteValueS390X_OpS390XMOVWload(v *Value) bool { @@ -10588,7 +10605,7 @@ func rewriteValueS390X_OpS390XMOVWload(v *Value) bool { } // match: (MOVWload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) - // result: (MOVWload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem) + // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10605,7 +10622,7 @@ func rewriteValueS390X_OpS390XMOVWload(v *Value) bool { } v.reset(OpS390XMOVWload) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(base, mem) return true } @@ -10868,7 +10885,7 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool { } // match: (MOVWstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) - // result: (MOVWstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem) + // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) for { off1 := auxIntToInt32(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -10886,7 +10903,7 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool { } v.reset(OpS390XMOVWstore) v.AuxInt = int32ToAuxInt(off1 + off2) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg3(base, val, mem) return true } @@ -11057,7 +11074,7 @@ func rewriteValueS390X_OpS390XMOVWstoreconst(v *Value) bool { } // match: (MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) - // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem) + // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem) for { sc := auxIntToValAndOff(v.AuxInt) sym1 := auxToSym(v.Aux) @@ -11073,7 +11090,7 @@ func rewriteValueS390X_OpS390XMOVWstoreconst(v *Value) bool { } v.reset(OpS390XMOVWstoreconst) v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off)) - v.Aux = symToAux(mergeSymTyped(sym1, sym2)) + v.Aux = symToAux(mergeSym(sym1, sym2)) v.AddArg2(ptr, mem) return true } @@ -11287,7 +11304,7 @@ func rewriteValueS390X_OpS390XMULLDload(v *Value) bool { } // match: (MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (MULLDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -11304,7 +11321,7 @@ func rewriteValueS390X_OpS390XMULLDload(v *Value) bool { } v.reset(OpS390XMULLDload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -11490,7 +11507,7 @@ func rewriteValueS390X_OpS390XMULLWload(v *Value) bool { } // match: (MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (MULLWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -11507,7 +11524,7 @@ func rewriteValueS390X_OpS390XMULLWload(v *Value) bool { } v.reset(OpS390XMULLWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -11616,9 +11633,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } break } - // match: ( OR (SLDconst x [c]) (SRDconst x [d])) - // cond: d == 64-c - // result: (RLLGconst [c] x) + // match: (OR (SLDconst x [c]) (SRDconst x [64-c])) + // result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)}) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLDconst { @@ -11626,15 +11642,11 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRDconst { + if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] { continue } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 64-c) { - continue - } - v.reset(OpS390XRLLGconst) - v.AuxInt = int8ToAuxInt(c) + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c)) v.AddArg(x) return true } @@ -11658,22 +11670,20 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } break } - // match: (OR (SLDconst [63] (SRDconst [63] (LGDR x))) (LGDR (LPDFR <t> y))) + // match: (OR (RISBGZ (LGDR x) {r}) (LGDR (LPDFR <t> y))) + // cond: r == s390x.NewRotateParams(0, 0, 0) // result: (LGDR (CPSDR <t> y x)) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_0.Op != OpS390XSLDconst || auxIntToInt8(v_0.AuxInt) != 63 { + if v_0.Op != OpS390XRISBGZ { continue } + r := auxToS390xRotateParams(v_0.Aux) v_0_0 := v_0.Args[0] - if v_0_0.Op != OpS390XSRDconst || auxIntToInt8(v_0_0.AuxInt) != 63 { - continue - } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpS390XLGDR { + if v_0_0.Op != OpS390XLGDR { continue } - x := v_0_0_0.Args[0] + x := v_0_0.Args[0] if v_1.Op != OpS390XLGDR { continue } @@ -11683,6 +11693,9 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } t := v_1_0.Type y := v_1_0.Args[0] + if !(r == s390x.NewRotateParams(0, 0, 0)) { + continue + } v.reset(OpS390XLGDR) v0 := b.NewValue0(v.Pos, OpS390XCPSDR, t) v0.AddArg2(y, x) @@ -11691,28 +11704,25 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } break } - // match: (OR (SLDconst [63] (SRDconst [63] (LGDR x))) (MOVDconst [c])) - // cond: c & -1<<63 == 0 + // match: (OR (RISBGZ (LGDR x) {r}) (MOVDconst [c])) + // cond: c >= 0 && r == s390x.NewRotateParams(0, 0, 0) // result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x)) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_0.Op != OpS390XSLDconst || auxIntToInt8(v_0.AuxInt) != 63 { + if v_0.Op != OpS390XRISBGZ { continue } + r := auxToS390xRotateParams(v_0.Aux) v_0_0 := v_0.Args[0] - if v_0_0.Op != OpS390XSRDconst || auxIntToInt8(v_0_0.AuxInt) != 63 { + if v_0_0.Op != OpS390XLGDR { continue } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpS390XLGDR { - continue - } - x := v_0_0_0.Args[0] + x := v_0_0.Args[0] if v_1.Op != OpS390XMOVDconst { continue } c := auxIntToInt64(v_1.AuxInt) - if !(c&-1<<63 == 0) { + if !(c >= 0 && r == s390x.NewRotateParams(0, 0, 0)) { continue } v.reset(OpS390XLGDR) @@ -11725,73 +11735,6 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool { } break } - // match: (OR (AND (MOVDconst [-1<<63]) (LGDR x)) (LGDR (LPDFR <t> y))) - // result: (LGDR (CPSDR <t> y x)) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_0.Op != OpS390XAND { - continue - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - v_0_1 := v_0.Args[1] - for _i1 := 0; _i1 <= 1; _i1, v_0_0, v_0_1 = _i1+1, v_0_1, v_0_0 { - if v_0_0.Op != OpS390XMOVDconst || auxIntToInt64(v_0_0.AuxInt) != -1<<63 || v_0_1.Op != OpS390XLGDR { - continue - } - x := v_0_1.Args[0] - if v_1.Op != OpS390XLGDR { - continue - } - v_1_0 := v_1.Args[0] - if v_1_0.Op != OpS390XLPDFR { - continue - } - t := v_1_0.Type - y := v_1_0.Args[0] - v.reset(OpS390XLGDR) - v0 := b.NewValue0(v.Pos, OpS390XCPSDR, t) - v0.AddArg2(y, x) - v.AddArg(v0) - return true - } - } - break - } - // match: (OR (AND (MOVDconst [-1<<63]) (LGDR x)) (MOVDconst [c])) - // cond: c & -1<<63 == 0 - // result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x)) - for { - for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { - if v_0.Op != OpS390XAND { - continue - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - v_0_1 := v_0.Args[1] - for _i1 := 0; _i1 <= 1; _i1, v_0_0, v_0_1 = _i1+1, v_0_1, v_0_0 { - if v_0_0.Op != OpS390XMOVDconst || auxIntToInt64(v_0_0.AuxInt) != -1<<63 || v_0_1.Op != OpS390XLGDR { - continue - } - x := v_0_1.Args[0] - if v_1.Op != OpS390XMOVDconst { - continue - } - c := auxIntToInt64(v_1.AuxInt) - if !(c&-1<<63 == 0) { - continue - } - v.reset(OpS390XLGDR) - v0 := b.NewValue0(v.Pos, OpS390XCPSDR, x.Type) - v1 := b.NewValue0(v.Pos, OpS390XFMOVDconst, x.Type) - v1.AuxInt = float64ToAuxInt(math.Float64frombits(uint64(c))) - v0.AddArg2(v1, x) - v.AddArg(v0) - return true - } - } - break - } // match: (OR (MOVDconst [c]) (MOVDconst [d])) // result: (MOVDconst [c|d]) for { @@ -12388,9 +12331,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool { } break } - // match: ( ORW (SLWconst x [c]) (SRWconst x [d])) - // cond: d == 32-c - // result: (RLLconst [c] x) + // match: (ORW (SLWconst x [c]) (SRWconst x [32-c])) + // result: (RLLconst x [c]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLWconst { @@ -12398,11 +12340,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRWconst { - continue - } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 32-c) { + if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] { continue } v.reset(OpS390XRLLconst) @@ -12840,7 +12778,7 @@ func rewriteValueS390X_OpS390XORWload(v *Value) bool { } // match: (ORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -12857,7 +12795,7 @@ func rewriteValueS390X_OpS390XORWload(v *Value) bool { } v.reset(OpS390XORWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -12951,7 +12889,7 @@ func rewriteValueS390X_OpS390XORload(v *Value) bool { } // match: (ORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (ORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (ORload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -12968,12 +12906,227 @@ func rewriteValueS390X_OpS390XORload(v *Value) bool { } v.reset(OpS390XORload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } return false } +func rewriteValueS390X_OpS390XRISBGZ(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + // match: (RISBGZ (MOVWZreg x) {r}) + // cond: r.InMerge(0xffffffff) != nil + // result: (RISBGZ x {*r.InMerge(0xffffffff)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XMOVWZreg { + break + } + x := v_0.Args[0] + if !(r.InMerge(0xffffffff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.InMerge(0xffffffff)) + v.AddArg(x) + return true + } + // match: (RISBGZ (MOVHZreg x) {r}) + // cond: r.InMerge(0x0000ffff) != nil + // result: (RISBGZ x {*r.InMerge(0x0000ffff)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XMOVHZreg { + break + } + x := v_0.Args[0] + if !(r.InMerge(0x0000ffff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.InMerge(0x0000ffff)) + v.AddArg(x) + return true + } + // match: (RISBGZ (MOVBZreg x) {r}) + // cond: r.InMerge(0x000000ff) != nil + // result: (RISBGZ x {*r.InMerge(0x000000ff)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XMOVBZreg { + break + } + x := v_0.Args[0] + if !(r.InMerge(0x000000ff) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(*r.InMerge(0x000000ff)) + v.AddArg(x) + return true + } + // match: (RISBGZ (SLDconst x [c]) {r}) + // cond: r.InMerge(^uint64(0)<<c) != nil + // result: (RISBGZ x {(*r.InMerge(^uint64(0)<<c)).RotateLeft(c)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XSLDconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + x := v_0.Args[0] + if !(r.InMerge(^uint64(0)<<c) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux((*r.InMerge(^uint64(0) << c)).RotateLeft(c)) + v.AddArg(x) + return true + } + // match: (RISBGZ (SRDconst x [c]) {r}) + // cond: r.InMerge(^uint64(0)>>c) != nil + // result: (RISBGZ x {(*r.InMerge(^uint64(0)>>c)).RotateLeft(-c)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XSRDconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + x := v_0.Args[0] + if !(r.InMerge(^uint64(0)>>c) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux((*r.InMerge(^uint64(0) >> c)).RotateLeft(-c)) + v.AddArg(x) + return true + } + // match: (RISBGZ (RISBGZ x {y}) {z}) + // cond: z.InMerge(y.OutMask()) != nil + // result: (RISBGZ x {(*z.InMerge(y.OutMask())).RotateLeft(y.Amount)}) + for { + z := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XRISBGZ { + break + } + y := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(z.InMerge(y.OutMask()) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux((*z.InMerge(y.OutMask())).RotateLeft(y.Amount)) + v.AddArg(x) + return true + } + // match: (RISBGZ x {r}) + // cond: r.End == 63 && r.Start == -r.Amount&63 + // result: (SRDconst x [-r.Amount&63]) + for { + r := auxToS390xRotateParams(v.Aux) + x := v_0 + if !(r.End == 63 && r.Start == -r.Amount&63) { + break + } + v.reset(OpS390XSRDconst) + v.AuxInt = int8ToAuxInt(-r.Amount & 63) + v.AddArg(x) + return true + } + // match: (RISBGZ x {r}) + // cond: r.Start == 0 && r.End == 63-r.Amount + // result: (SLDconst x [r.Amount]) + for { + r := auxToS390xRotateParams(v.Aux) + x := v_0 + if !(r.Start == 0 && r.End == 63-r.Amount) { + break + } + v.reset(OpS390XSLDconst) + v.AuxInt = int8ToAuxInt(r.Amount) + v.AddArg(x) + return true + } + // match: (RISBGZ (SRADconst x [c]) {r}) + // cond: r.Start == r.End && (r.Start+r.Amount)&63 <= c + // result: (RISBGZ x {s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)}) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XSRADconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + x := v_0.Args[0] + if !(r.Start == r.End && (r.Start+r.Amount)&63 <= c) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)) + v.AddArg(x) + return true + } + // match: (RISBGZ x {r}) + // cond: r == s390x.NewRotateParams(56, 63, 0) + // result: (MOVBZreg x) + for { + r := auxToS390xRotateParams(v.Aux) + x := v_0 + if !(r == s390x.NewRotateParams(56, 63, 0)) { + break + } + v.reset(OpS390XMOVBZreg) + v.AddArg(x) + return true + } + // match: (RISBGZ x {r}) + // cond: r == s390x.NewRotateParams(48, 63, 0) + // result: (MOVHZreg x) + for { + r := auxToS390xRotateParams(v.Aux) + x := v_0 + if !(r == s390x.NewRotateParams(48, 63, 0)) { + break + } + v.reset(OpS390XMOVHZreg) + v.AddArg(x) + return true + } + // match: (RISBGZ x {r}) + // cond: r == s390x.NewRotateParams(32, 63, 0) + // result: (MOVWZreg x) + for { + r := auxToS390xRotateParams(v.Aux) + x := v_0 + if !(r == s390x.NewRotateParams(32, 63, 0)) { + break + } + v.reset(OpS390XMOVWZreg) + v.AddArg(x) + return true + } + // match: (RISBGZ (LGDR <t> x) {r}) + // cond: r == s390x.NewRotateParams(1, 63, 0) + // result: (LGDR <t> (LPDFR <x.Type> x)) + for { + r := auxToS390xRotateParams(v.Aux) + if v_0.Op != OpS390XLGDR { + break + } + t := v_0.Type + x := v_0.Args[0] + if !(r == s390x.NewRotateParams(1, 63, 0)) { + break + } + v.reset(OpS390XLGDR) + v.Type = t + v0 := b.NewValue0(v.Pos, OpS390XLPDFR, x.Type) + v0.AddArg(x) + v.AddArg(v0) + return true + } + return false +} func rewriteValueS390X_OpS390XRLL(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -12996,15 +13149,15 @@ func rewriteValueS390X_OpS390XRLLG(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] // match: (RLLG x (MOVDconst [c])) - // result: (RLLGconst x [int8(c&63)]) + // result: (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))}) for { x := v_0 if v_1.Op != OpS390XMOVDconst { break } c := auxIntToInt64(v_1.AuxInt) - v.reset(OpS390XRLLGconst) - v.AuxInt = int8ToAuxInt(int8(c & 63)) + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, int8(c&63))) v.AddArg(x) return true } @@ -13028,6 +13181,23 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool { v.AddArg(x) return true } + // match: (SLD x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SLD x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSLD) + v.AddArg2(x, y) + return true + } // match: (SLD x (AND (MOVDconst [c]) y)) // result: (SLD x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -13146,6 +13316,38 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool { } func rewriteValueS390X_OpS390XSLDconst(v *Value) bool { v_0 := v.Args[0] + // match: (SLDconst (SRDconst x [c]) [d]) + // result: (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)}) + for { + d := auxIntToInt8(v.AuxInt) + if v_0.Op != OpS390XSRDconst { + break + } + c := auxIntToInt8(v_0.AuxInt) + x := v_0.Args[0] + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)) + v.AddArg(x) + return true + } + // match: (SLDconst (RISBGZ x {r}) [c]) + // cond: s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil + // result: (RISBGZ x {(*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)}) + for { + c := auxIntToInt8(v.AuxInt) + if v_0.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux((*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)) + v.AddArg(x) + return true + } // match: (SLDconst x [0]) // result: x for { @@ -13164,18 +13366,54 @@ func rewriteValueS390X_OpS390XSLW(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (SLW x (MOVDconst [c])) - // result: (SLWconst x [int8(c&63)]) + // cond: c&32 == 0 + // result: (SLWconst x [int8(c&31)]) for { x := v_0 if v_1.Op != OpS390XMOVDconst { break } c := auxIntToInt64(v_1.AuxInt) + if !(c&32 == 0) { + break + } v.reset(OpS390XSLWconst) - v.AuxInt = int8ToAuxInt(int8(c & 63)) + v.AuxInt = int8ToAuxInt(int8(c & 31)) v.AddArg(x) return true } + // match: (SLW _ (MOVDconst [c])) + // cond: c&32 != 0 + // result: (MOVDconst [0]) + for { + if v_1.Op != OpS390XMOVDconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(c&32 != 0) { + break + } + v.reset(OpS390XMOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (SLW x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SLW x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSLW) + v.AddArg2(x, y) + return true + } // match: (SLW x (AND (MOVDconst [c]) y)) // result: (SLW x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -13324,6 +13562,23 @@ func rewriteValueS390X_OpS390XSRAD(v *Value) bool { v.AddArg(x) return true } + // match: (SRAD x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SRAD x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSRAD) + v.AddArg2(x, y) + return true + } // match: (SRAD x (AND (MOVDconst [c]) y)) // result: (SRAD x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -13472,18 +13727,56 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (SRAW x (MOVDconst [c])) - // result: (SRAWconst x [int8(c&63)]) + // cond: c&32 == 0 + // result: (SRAWconst x [int8(c&31)]) for { x := v_0 if v_1.Op != OpS390XMOVDconst { break } c := auxIntToInt64(v_1.AuxInt) + if !(c&32 == 0) { + break + } v.reset(OpS390XSRAWconst) - v.AuxInt = int8ToAuxInt(int8(c & 63)) + v.AuxInt = int8ToAuxInt(int8(c & 31)) v.AddArg(x) return true } + // match: (SRAW x (MOVDconst [c])) + // cond: c&32 != 0 + // result: (SRAWconst x [31]) + for { + x := v_0 + if v_1.Op != OpS390XMOVDconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(c&32 != 0) { + break + } + v.reset(OpS390XSRAWconst) + v.AuxInt = int8ToAuxInt(31) + v.AddArg(x) + return true + } + // match: (SRAW x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SRAW x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSRAW) + v.AddArg2(x, y) + return true + } // match: (SRAW x (AND (MOVDconst [c]) y)) // result: (SRAW x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -13644,6 +13937,23 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool { v.AddArg(x) return true } + // match: (SRD x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SRD x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSRD) + v.AddArg2(x, y) + return true + } // match: (SRD x (AND (MOVDconst [c]) y)) // result: (SRD x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -13762,24 +14072,36 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool { } func rewriteValueS390X_OpS390XSRDconst(v *Value) bool { v_0 := v.Args[0] - b := v.Block - // match: (SRDconst [1] (SLDconst [1] (LGDR <t> x))) - // result: (LGDR <t> (LPDFR <x.Type> x)) + // match: (SRDconst (SLDconst x [c]) [d]) + // result: (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)}) for { - if auxIntToInt8(v.AuxInt) != 1 || v_0.Op != OpS390XSLDconst || auxIntToInt8(v_0.AuxInt) != 1 { + d := auxIntToInt8(v.AuxInt) + if v_0.Op != OpS390XSLDconst { break } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpS390XLGDR { + c := auxIntToInt8(v_0.AuxInt) + x := v_0.Args[0] + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)) + v.AddArg(x) + return true + } + // match: (SRDconst (RISBGZ x {r}) [c]) + // cond: s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil + // result: (RISBGZ x {(*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)}) + for { + c := auxIntToInt8(v.AuxInt) + if v_0.Op != OpS390XRISBGZ { break } - t := v_0_0.Type - x := v_0_0.Args[0] - v.reset(OpS390XLGDR) - v.Type = t - v0 := b.NewValue0(v.Pos, OpS390XLPDFR, x.Type) - v0.AddArg(x) - v.AddArg(v0) + r := auxToS390xRotateParams(v_0.Aux) + x := v_0.Args[0] + if !(s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil) { + break + } + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux((*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)) + v.AddArg(x) return true } // match: (SRDconst x [0]) @@ -13800,18 +14122,54 @@ func rewriteValueS390X_OpS390XSRW(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (SRW x (MOVDconst [c])) - // result: (SRWconst x [int8(c&63)]) + // cond: c&32 == 0 + // result: (SRWconst x [int8(c&31)]) for { x := v_0 if v_1.Op != OpS390XMOVDconst { break } c := auxIntToInt64(v_1.AuxInt) + if !(c&32 == 0) { + break + } v.reset(OpS390XSRWconst) - v.AuxInt = int8ToAuxInt(int8(c & 63)) + v.AuxInt = int8ToAuxInt(int8(c & 31)) v.AddArg(x) return true } + // match: (SRW _ (MOVDconst [c])) + // cond: c&32 != 0 + // result: (MOVDconst [0]) + for { + if v_1.Op != OpS390XMOVDconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(c&32 != 0) { + break + } + v.reset(OpS390XMOVDconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (SRW x (RISBGZ y {r})) + // cond: r.Amount == 0 && r.OutMask()&63 == 63 + // result: (SRW x y) + for { + x := v_0 + if v_1.Op != OpS390XRISBGZ { + break + } + r := auxToS390xRotateParams(v_1.Aux) + y := v_1.Args[0] + if !(r.Amount == 0 && r.OutMask()&63 == 63) { + break + } + v.reset(OpS390XSRW) + v.AddArg2(x, y) + return true + } // match: (SRW x (AND (MOVDconst [c]) y)) // result: (SRW x (ANDWconst <typ.UInt32> [int32(c&63)] y)) for { @@ -14327,7 +14685,7 @@ func rewriteValueS390X_OpS390XSUBWload(v *Value) bool { } // match: (SUBWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (SUBWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (SUBWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -14344,7 +14702,7 @@ func rewriteValueS390X_OpS390XSUBWload(v *Value) bool { } v.reset(OpS390XSUBWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -14460,7 +14818,7 @@ func rewriteValueS390X_OpS390XSUBload(v *Value) bool { } // match: (SUBload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (SUBload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (SUBload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -14477,7 +14835,7 @@ func rewriteValueS390X_OpS390XSUBload(v *Value) bool { } v.reset(OpS390XSUBload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -14558,9 +14916,8 @@ func rewriteValueS390X_OpS390XXOR(v *Value) bool { } break } - // match: (XOR (SLDconst x [c]) (SRDconst x [d])) - // cond: d == 64-c - // result: (RLLGconst [c] x) + // match: (XOR (SLDconst x [c]) (SRDconst x [64-c])) + // result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)}) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLDconst { @@ -14568,15 +14925,11 @@ func rewriteValueS390X_OpS390XXOR(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRDconst { - continue - } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 64-c) { + if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] { continue } - v.reset(OpS390XRLLGconst) - v.AuxInt = int8ToAuxInt(c) + v.reset(OpS390XRISBGZ) + v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c)) v.AddArg(x) return true } @@ -14659,9 +15012,8 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool { } break } - // match: (XORW (SLWconst x [c]) (SRWconst x [d])) - // cond: d == 32-c - // result: (RLLconst [c] x) + // match: (XORW (SLWconst x [c]) (SRWconst x [32-c])) + // result: (RLLconst x [c]) for { for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { if v_0.Op != OpS390XSLWconst { @@ -14669,11 +15021,7 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) x := v_0.Args[0] - if v_1.Op != OpS390XSRWconst { - continue - } - d := auxIntToInt8(v_1.AuxInt) - if x != v_1.Args[0] || !(d == 32-c) { + if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] { continue } v.reset(OpS390XRLLconst) @@ -14806,7 +15154,7 @@ func rewriteValueS390X_OpS390XXORWload(v *Value) bool { } // match: (XORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (XORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (XORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -14823,7 +15171,7 @@ func rewriteValueS390X_OpS390XXORWload(v *Value) bool { } v.reset(OpS390XXORWload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } @@ -14907,7 +15255,7 @@ func rewriteValueS390X_OpS390XXORload(v *Value) bool { } // match: (XORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) - // result: (XORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem) + // result: (XORload [o1+o2] {mergeSym(s1, s2)} x ptr mem) for { o1 := auxIntToInt32(v.AuxInt) s1 := auxToSym(v.Aux) @@ -14924,7 +15272,7 @@ func rewriteValueS390X_OpS390XXORload(v *Value) bool { } v.reset(OpS390XXORload) v.AuxInt = int32ToAuxInt(o1 + o2) - v.Aux = symToAux(mergeSymTyped(s1, s2)) + v.Aux = symToAux(mergeSym(s1, s2)) v.AddArg3(x, ptr, mem) return true } diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go index 52b6f6bfc7..c8ecefc736 100644 --- a/src/cmd/compile/internal/ssa/rewriteWasm.go +++ b/src/cmd/compile/internal/ssa/rewriteWasm.go @@ -3693,6 +3693,20 @@ func rewriteValueWasm_OpWasmI64AddConst(v *Value) bool { v.AddArg(base) return true } + // match: (I64AddConst [off] x:(SP)) + // cond: isU32Bit(off) + // result: (LoweredAddr [int32(off)] x) + for { + off := auxIntToInt64(v.AuxInt) + x := v_0 + if x.Op != OpSP || !(isU32Bit(off)) { + break + } + v.reset(OpWasmLoweredAddr) + v.AuxInt = int32ToAuxInt(int32(off)) + v.AddArg(x) + return true + } return false } func rewriteValueWasm_OpWasmI64And(v *Value) bool { diff --git a/src/cmd/compile/internal/ssa/rewrite_test.go b/src/cmd/compile/internal/ssa/rewrite_test.go index 1a15d8c940..6fe429e85a 100644 --- a/src/cmd/compile/internal/ssa/rewrite_test.go +++ b/src/cmd/compile/internal/ssa/rewrite_test.go @@ -36,3 +36,184 @@ func TestSubFlags(t *testing.T) { t.Errorf("subFlags32(0,1).ult() returned false") } } + +func TestIsPPC64WordRotateMask(t *testing.T) { + tests := []struct { + input int64 + expected bool + }{ + {0x00000001, true}, + {0x80000001, true}, + {0x80010001, false}, + {0xFFFFFFFA, false}, + {0xF0F0F0F0, false}, + {0xFFFFFFFD, true}, + {0x80000000, true}, + {0x00000000, false}, + {0xFFFFFFFF, true}, + {0x0000FFFF, true}, + {0xFF0000FF, true}, + {0x00FFFF00, true}, + } + + for _, v := range tests { + if v.expected != isPPC64WordRotateMask(v.input) { + t.Errorf("isPPC64WordRotateMask(0x%x) failed", v.input) + } + } +} + +func TestEncodeDecodePPC64WordRotateMask(t *testing.T) { + tests := []struct { + rotate int64 + mask uint64 + nbits, + mb, + me, + encoded int64 + }{ + {1, 0x00000001, 32, 31, 31, 0x20011f20}, + {2, 0x80000001, 32, 31, 0, 0x20021f01}, + {3, 0xFFFFFFFD, 32, 31, 29, 0x20031f1e}, + {4, 0x80000000, 32, 0, 0, 0x20040001}, + {5, 0xFFFFFFFF, 32, 0, 31, 0x20050020}, + {6, 0x0000FFFF, 32, 16, 31, 0x20061020}, + {7, 0xFF0000FF, 32, 24, 7, 0x20071808}, + {8, 0x00FFFF00, 32, 8, 23, 0x20080818}, + + {9, 0x0000000000FFFF00, 64, 40, 55, 0x40092838}, + {10, 0xFFFF000000000000, 64, 0, 15, 0x400A0010}, + {10, 0xFFFF000000000001, 64, 63, 15, 0x400A3f10}, + } + + for i, v := range tests { + result := encodePPC64RotateMask(v.rotate, int64(v.mask), v.nbits) + if result != v.encoded { + t.Errorf("encodePPC64RotateMask(%d,0x%x,%d) = 0x%x, expected 0x%x", v.rotate, v.mask, v.nbits, result, v.encoded) + } + rotate, mb, me, mask := DecodePPC64RotateMask(result) + if rotate != v.rotate || mb != v.mb || me != v.me || mask != v.mask { + t.Errorf("DecodePPC64Failure(Test %d) got (%d, %d, %d, %x) expected (%d, %d, %d, %x)", i, rotate, mb, me, mask, v.rotate, v.mb, v.me, v.mask) + } + } +} + +func TestMergePPC64ClrlsldiSrw(t *testing.T) { + tests := []struct { + clrlsldi int32 + srw int64 + valid bool + rotate int64 + mask uint64 + }{ + // ((x>>4)&0xFF)<<4 + {newPPC64ShiftAuxInt(4, 56, 63, 64), 4, true, 0, 0xFF0}, + // ((x>>4)&0xFFFF)<<4 + {newPPC64ShiftAuxInt(4, 48, 63, 64), 4, true, 0, 0xFFFF0}, + // ((x>>4)&0xFFFF)<<17 + {newPPC64ShiftAuxInt(17, 48, 63, 64), 4, false, 0, 0}, + // ((x>>4)&0xFFFF)<<16 + {newPPC64ShiftAuxInt(16, 48, 63, 64), 4, true, 12, 0xFFFF0000}, + // ((x>>32)&0xFFFF)<<17 + {newPPC64ShiftAuxInt(17, 48, 63, 64), 32, false, 0, 0}, + } + for i, v := range tests { + result := mergePPC64ClrlsldiSrw(int64(v.clrlsldi), v.srw) + if v.valid && result == 0 { + t.Errorf("mergePPC64ClrlsldiSrw(Test %d) did not merge", i) + } else if !v.valid && result != 0 { + t.Errorf("mergePPC64ClrlsldiSrw(Test %d) should return 0", i) + } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m { + t.Errorf("mergePPC64ClrlsldiSrw(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask) + } + } +} + +func TestMergePPC64ClrlsldiRlwinm(t *testing.T) { + tests := []struct { + clrlsldi int32 + rlwinm int64 + valid bool + rotate int64 + mask uint64 + }{ + // ((x<<4)&0xFF00)<<4 + {newPPC64ShiftAuxInt(4, 56, 63, 64), encodePPC64RotateMask(4, 0xFF00, 32), false, 0, 0}, + // ((x>>4)&0xFF)<<4 + {newPPC64ShiftAuxInt(4, 56, 63, 64), encodePPC64RotateMask(28, 0x0FFFFFFF, 32), true, 0, 0xFF0}, + // ((x>>4)&0xFFFF)<<4 + {newPPC64ShiftAuxInt(4, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), true, 0, 0xFFFF0}, + // ((x>>4)&0xFFFF)<<17 + {newPPC64ShiftAuxInt(17, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), false, 0, 0}, + // ((x>>4)&0xFFFF)<<16 + {newPPC64ShiftAuxInt(16, 48, 63, 64), encodePPC64RotateMask(28, 0xFFFF, 32), true, 12, 0xFFFF0000}, + // ((x>>4)&0xF000FFFF)<<16 + {newPPC64ShiftAuxInt(16, 48, 63, 64), encodePPC64RotateMask(28, 0xF000FFFF, 32), true, 12, 0xFFFF0000}, + } + for i, v := range tests { + result := mergePPC64ClrlsldiRlwinm(v.clrlsldi, v.rlwinm) + if v.valid && result == 0 { + t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) did not merge", i) + } else if !v.valid && result != 0 { + t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) should return 0", i) + } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m { + t.Errorf("mergePPC64ClrlsldiRlwinm(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask) + } + } +} + +func TestMergePPC64SldiSrw(t *testing.T) { + tests := []struct { + sld int64 + srw int64 + valid bool + rotate int64 + mask uint64 + }{ + {4, 4, true, 0, 0xFFFFFFF0}, + {4, 8, true, 28, 0x0FFFFFF0}, + {0, 0, true, 0, 0xFFFFFFFF}, + {8, 4, false, 0, 0}, + {0, 32, false, 0, 0}, + {0, 31, true, 1, 0x1}, + {31, 31, true, 0, 0x80000000}, + {32, 32, false, 0, 0}, + } + for i, v := range tests { + result := mergePPC64SldiSrw(v.sld, v.srw) + if v.valid && result == 0 { + t.Errorf("mergePPC64SldiSrw(Test %d) did not merge", i) + } else if !v.valid && result != 0 { + t.Errorf("mergePPC64SldiSrw(Test %d) should return 0", i) + } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m { + t.Errorf("mergePPC64SldiSrw(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask) + } + } +} + +func TestMergePPC64AndSrwi(t *testing.T) { + tests := []struct { + and int64 + srw int64 + valid bool + rotate int64 + mask uint64 + }{ + {0x000000FF, 8, true, 24, 0xFF}, + {0xF00000FF, 8, true, 24, 0xFF}, + {0x0F0000FF, 4, false, 0, 0}, + {0x00000000, 4, false, 0, 0}, + {0xF0000000, 4, false, 0, 0}, + {0xF0000000, 32, false, 0, 0}, + } + for i, v := range tests { + result := mergePPC64AndSrwi(v.and, v.srw) + if v.valid && result == 0 { + t.Errorf("mergePPC64AndSrwi(Test %d) did not merge", i) + } else if !v.valid && result != 0 { + t.Errorf("mergePPC64AndSrwi(Test %d) should return 0", i) + } else if r, _, _, m := DecodePPC64RotateMask(result); v.rotate != r || v.mask != m { + t.Errorf("mergePPC64AndSrwi(Test %d) got (%d,0x%x) expected (%d,0x%x)", i, r, m, v.rotate, v.mask) + } + } +} diff --git a/src/cmd/compile/internal/ssa/rewritedec64.go b/src/cmd/compile/internal/ssa/rewritedec64.go index 86fbc9901a..c49bc8043e 100644 --- a/src/cmd/compile/internal/ssa/rewritedec64.go +++ b/src/cmd/compile/internal/ssa/rewritedec64.go @@ -62,6 +62,8 @@ func rewriteValuedec64(v *Value) bool { return rewriteValuedec64_OpNeg64(v) case OpNeq64: return rewriteValuedec64_OpNeq64(v) + case OpOr32: + return rewriteValuedec64_OpOr32(v) case OpOr64: return rewriteValuedec64_OpOr64(v) case OpRsh16Ux64: @@ -182,12 +184,12 @@ func rewriteValuedec64_OpArg(v *Value) bool { config := b.Func.Config typ := &b.Func.Config.Types // match: (Arg {n} [off]) - // cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() + // cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") // result: (Int64Make (Arg <typ.Int32> {n} [off+4]) (Arg <typ.UInt32> {n} [off])) for { off := auxIntToInt32(v.AuxInt) n := auxToSym(v.Aux) - if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned()) { + if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) { break } v.reset(OpInt64Make) @@ -201,12 +203,12 @@ func rewriteValuedec64_OpArg(v *Value) bool { return true } // match: (Arg {n} [off]) - // cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() + // cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") // result: (Int64Make (Arg <typ.UInt32> {n} [off+4]) (Arg <typ.UInt32> {n} [off])) for { off := auxIntToInt32(v.AuxInt) n := auxToSym(v.Aux) - if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned()) { + if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) { break } v.reset(OpInt64Make) @@ -220,12 +222,12 @@ func rewriteValuedec64_OpArg(v *Value) bool { return true } // match: (Arg {n} [off]) - // cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() + // cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") // result: (Int64Make (Arg <typ.Int32> {n} [off]) (Arg <typ.UInt32> {n} [off+4])) for { off := auxIntToInt32(v.AuxInt) n := auxToSym(v.Aux) - if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned()) { + if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) { break } v.reset(OpInt64Make) @@ -239,12 +241,12 @@ func rewriteValuedec64_OpArg(v *Value) bool { return true } // match: (Arg {n} [off]) - // cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() + // cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") // result: (Int64Make (Arg <typ.UInt32> {n} [off]) (Arg <typ.UInt32> {n} [off+4])) for { off := auxIntToInt32(v.AuxInt) n := auxToSym(v.Aux) - if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned()) { + if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) { break } v.reset(OpInt64Make) @@ -728,7 +730,23 @@ func rewriteValuedec64_OpLsh16x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Lsh16x64 x y) + // result: (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpLsh16x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpLsh32x64(v *Value) bool { v_1 := v.Args[1] @@ -793,83 +811,97 @@ func rewriteValuedec64_OpLsh32x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Lsh32x64 x y) + // result: (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpLsh32x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpLsh64x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh64x16 (Int64Make hi lo) s) - // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x16 <typ.UInt32> hi s) (Rsh32Ux16 <typ.UInt32> lo (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Lsh32x16 <typ.UInt32> lo (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))) (Lsh32x16 <typ.UInt32> lo s)) + // match: (Lsh64x16 x s) + // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x16 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux16 <typ.UInt32> (Int64Lo x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Lsh32x16 <typ.UInt32> (Int64Lo x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))) (Lsh32x16 <typ.UInt32> (Int64Lo x) s)) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v2 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) - v2.AddArg2(hi, s) - v3 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) - v4 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v5 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) - v5.AuxInt = int16ToAuxInt(32) - v4.AddArg2(v5, s) - v3.AddArg2(lo, v4) - v1.AddArg2(v2, v3) - v6 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) - v7 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v7.AddArg2(s, v5) - v6.AddArg2(lo, v7) - v0.AddArg2(v1, v6) + v3 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v3.AddArg(x) + v2.AddArg2(v3, s) + v4 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v6 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v7 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) + v7.AuxInt = int16ToAuxInt(32) + v6.AddArg2(v7, s) + v4.AddArg2(v5, v6) + v1.AddArg2(v2, v4) v8 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) - v8.AddArg2(lo, s) - v.AddArg2(v0, v8) + v9 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v9.AddArg2(s, v7) + v8.AddArg2(v5, v9) + v0.AddArg2(v1, v8) + v10 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) + v10.AddArg2(v5, s) + v.AddArg2(v0, v10) return true } - return false } func rewriteValuedec64_OpLsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh64x32 (Int64Make hi lo) s) - // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x32 <typ.UInt32> hi s) (Rsh32Ux32 <typ.UInt32> lo (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Lsh32x32 <typ.UInt32> lo (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))) (Lsh32x32 <typ.UInt32> lo s)) + // match: (Lsh64x32 x s) + // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x32 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux32 <typ.UInt32> (Int64Lo x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Lsh32x32 <typ.UInt32> (Int64Lo x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))) (Lsh32x32 <typ.UInt32> (Int64Lo x) s)) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v2 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) - v2.AddArg2(hi, s) - v3 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v4 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v5.AuxInt = int32ToAuxInt(32) - v4.AddArg2(v5, s) - v3.AddArg2(lo, v4) - v1.AddArg2(v2, v3) - v6 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) - v7 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v7.AddArg2(s, v5) - v6.AddArg2(lo, v7) - v0.AddArg2(v1, v6) + v3 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v3.AddArg(x) + v2.AddArg2(v3, s) + v4 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v6 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v7.AuxInt = int32ToAuxInt(32) + v6.AddArg2(v7, s) + v4.AddArg2(v5, v6) + v1.AddArg2(v2, v4) v8 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) - v8.AddArg2(lo, s) - v.AddArg2(v0, v8) + v9 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v9.AddArg2(s, v7) + v8.AddArg2(v5, v9) + v0.AddArg2(v1, v8) + v10 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) + v10.AddArg2(v5, s) + v.AddArg2(v0, v10) return true } - return false } func rewriteValuedec64_OpLsh64x64(v *Value) bool { v_1 := v.Args[1] @@ -934,45 +966,60 @@ func rewriteValuedec64_OpLsh64x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Lsh64x64 x y) + // result: (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpLsh64x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpLsh64x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh64x8 (Int64Make hi lo) s) - // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x8 <typ.UInt32> hi s) (Rsh32Ux8 <typ.UInt32> lo (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Lsh32x8 <typ.UInt32> lo (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))) (Lsh32x8 <typ.UInt32> lo s)) + // match: (Lsh64x8 x s) + // result: (Int64Make (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Lsh32x8 <typ.UInt32> (Int64Hi x) s) (Rsh32Ux8 <typ.UInt32> (Int64Lo x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Lsh32x8 <typ.UInt32> (Int64Lo x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))) (Lsh32x8 <typ.UInt32> (Int64Lo x) s)) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) v2 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) - v2.AddArg2(hi, s) - v3 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) - v4 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v5 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) - v5.AuxInt = int8ToAuxInt(32) - v4.AddArg2(v5, s) - v3.AddArg2(lo, v4) - v1.AddArg2(v2, v3) - v6 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) - v7 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v7.AddArg2(s, v5) - v6.AddArg2(lo, v7) - v0.AddArg2(v1, v6) + v3 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v3.AddArg(x) + v2.AddArg2(v3, s) + v4 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v6 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v7 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) + v7.AuxInt = int8ToAuxInt(32) + v6.AddArg2(v7, s) + v4.AddArg2(v5, v6) + v1.AddArg2(v2, v4) v8 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) - v8.AddArg2(lo, s) - v.AddArg2(v0, v8) + v9 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v9.AddArg2(s, v7) + v8.AddArg2(v5, v9) + v0.AddArg2(v1, v8) + v10 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) + v10.AddArg2(v5, s) + v.AddArg2(v0, v10) return true } - return false } func rewriteValuedec64_OpLsh8x64(v *Value) bool { v_1 := v.Args[1] @@ -1037,7 +1084,23 @@ func rewriteValuedec64_OpLsh8x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Lsh8x64 x y) + // result: (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpLsh8x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpMul64(v *Value) bool { v_1 := v.Args[1] @@ -1118,6 +1181,64 @@ func rewriteValuedec64_OpNeq64(v *Value) bool { return true } } +func rewriteValuedec64_OpOr32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) + // cond: c == 0 + // result: y + for { + if v.Type != typ.UInt32 { + break + } + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpZeromask { + continue + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpConst32 { + continue + } + c := auxIntToInt32(v_0_0.AuxInt) + y := v_1 + if !(c == 0) { + continue + } + v.copyOf(y) + return true + } + break + } + // match: (Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) + // cond: c != 0 + // result: (Const32 <typ.UInt32> [-1]) + for { + if v.Type != typ.UInt32 { + break + } + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + if v_0.Op != OpZeromask { + continue + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpConst32 { + continue + } + c := auxIntToInt32(v_0_0.AuxInt) + if !(c != 0) { + continue + } + v.reset(OpConst32) + v.Type = typ.UInt32 + v.AuxInt = int32ToAuxInt(-1) + return true + } + break + } + return false +} func rewriteValuedec64_OpOr64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -1208,7 +1329,23 @@ func rewriteValuedec64_OpRsh16Ux64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh16Ux64 x y) + // result: (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh16Ux32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh16x64(v *Value) bool { v_1 := v.Args[1] @@ -1276,7 +1413,23 @@ func rewriteValuedec64_OpRsh16x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh16x64 x y) + // result: (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh16x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh32Ux64(v *Value) bool { v_1 := v.Args[1] @@ -1341,7 +1494,23 @@ func rewriteValuedec64_OpRsh32Ux64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh32Ux64 x y) + // result: (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh32Ux32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh32x64(v *Value) bool { v_1 := v.Args[1] @@ -1407,83 +1576,97 @@ func rewriteValuedec64_OpRsh32x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh32x64 x y) + // result: (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh32x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh64Ux16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64Ux16 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32Ux16 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux16 <typ.UInt32> lo s) (Lsh32x16 <typ.UInt32> hi (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Rsh32Ux16 <typ.UInt32> hi (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))) + // match: (Rsh64Ux16 x s) + // result: (Int64Make (Rsh32Ux16 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s) (Lsh32x16 <typ.UInt32> (Int64Hi x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (Rsh32Ux16 <typ.UInt32> (Int64Hi x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v6 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) - v6.AuxInt = int16ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v8.AddArg2(s, v6) - v7.AddArg2(hi, v8) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v8 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) + v8.AuxInt = int16ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v10.AddArg2(s, v8) + v9.AddArg2(v1, v10) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh64Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64Ux32 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32Ux32 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux32 <typ.UInt32> lo s) (Lsh32x32 <typ.UInt32> hi (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Rsh32Ux32 <typ.UInt32> hi (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))) + // match: (Rsh64Ux32 x s) + // result: (Int64Make (Rsh32Ux32 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s) (Lsh32x32 <typ.UInt32> (Int64Hi x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (Rsh32Ux32 <typ.UInt32> (Int64Hi x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v6 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v6.AuxInt = int32ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v8.AddArg2(s, v6) - v7.AddArg2(hi, v8) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v8 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v8.AuxInt = int32ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v10.AddArg2(s, v8) + v9.AddArg2(v1, v10) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh64Ux64(v *Value) bool { v_1 := v.Args[1] @@ -1548,139 +1731,152 @@ func rewriteValuedec64_OpRsh64Ux64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh64Ux64 x y) + // result: (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh64Ux32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh64Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64Ux8 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32Ux8 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux8 <typ.UInt32> lo s) (Lsh32x8 <typ.UInt32> hi (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Rsh32Ux8 <typ.UInt32> hi (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))) + // match: (Rsh64Ux8 x s) + // result: (Int64Make (Rsh32Ux8 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s) (Lsh32x8 <typ.UInt32> (Int64Hi x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (Rsh32Ux8 <typ.UInt32> (Int64Hi x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v6 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) - v6.AuxInt = int8ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v8.AddArg2(s, v6) - v7.AddArg2(hi, v8) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v8 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) + v8.AuxInt = int8ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v10.AddArg2(s, v8) + v9.AddArg2(v1, v10) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh64x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64x16 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32x16 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux16 <typ.UInt32> lo s) (Lsh32x16 <typ.UInt32> hi (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (And32 <typ.UInt32> (Rsh32x16 <typ.UInt32> hi (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))) (Zeromask (ZeroExt16to32 (Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5]))))))) + // match: (Rsh64x16 x s) + // result: (Int64Make (Rsh32x16 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux16 <typ.UInt32> (Int64Lo x) s) (Lsh32x16 <typ.UInt32> (Int64Hi x) (Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s))) (And32 <typ.UInt32> (Rsh32x16 <typ.UInt32> (Int64Hi x) (Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))) (Zeromask (ZeroExt16to32 (Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5]))))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32x16, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v6 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) - v6.AuxInt = int16ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpRsh32x16, typ.UInt32) - v9 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) - v9.AddArg2(s, v6) - v8.AddArg2(hi, v9) - v10 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) - v11 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) - v12 := b.NewValue0(v.Pos, OpRsh16Ux32, typ.UInt16) - v13 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v13.AuxInt = int32ToAuxInt(5) - v12.AddArg2(s, v13) - v11.AddArg(v12) - v10.AddArg(v11) - v7.AddArg2(v8, v10) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux16, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x16, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v8 := b.NewValue0(v.Pos, OpConst16, typ.UInt16) + v8.AuxInt = int16ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpRsh32x16, typ.UInt32) + v11 := b.NewValue0(v.Pos, OpSub16, typ.UInt16) + v11.AddArg2(s, v8) + v10.AddArg2(v1, v11) + v12 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v13 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v14 := b.NewValue0(v.Pos, OpRsh16Ux32, typ.UInt16) + v15 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v15.AuxInt = int32ToAuxInt(5) + v14.AddArg2(s, v15) + v13.AddArg(v14) + v12.AddArg(v13) + v9.AddArg2(v10, v12) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64x32 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32x32 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux32 <typ.UInt32> lo s) (Lsh32x32 <typ.UInt32> hi (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (And32 <typ.UInt32> (Rsh32x32 <typ.UInt32> hi (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))) (Zeromask (Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5])))))) + // match: (Rsh64x32 x s) + // result: (Int64Make (Rsh32x32 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux32 <typ.UInt32> (Int64Lo x) s) (Lsh32x32 <typ.UInt32> (Int64Hi x) (Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s))) (And32 <typ.UInt32> (Rsh32x32 <typ.UInt32> (Int64Hi x) (Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))) (Zeromask (Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5])))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32x32, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v6 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v6.AuxInt = int32ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpRsh32x32, typ.UInt32) - v9 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) - v9.AddArg2(s, v6) - v8.AddArg2(hi, v9) - v10 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) - v11 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) - v12 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v12.AuxInt = int32ToAuxInt(5) - v11.AddArg2(s, v12) - v10.AddArg(v11) - v7.AddArg2(v8, v10) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x32, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v8 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v8.AuxInt = int32ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpRsh32x32, typ.UInt32) + v11 := b.NewValue0(v.Pos, OpSub32, typ.UInt32) + v11.AddArg2(s, v8) + v10.AddArg2(v1, v11) + v12 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v13 := b.NewValue0(v.Pos, OpRsh32Ux32, typ.UInt32) + v14 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v14.AuxInt = int32ToAuxInt(5) + v13.AddArg2(s, v14) + v12.AddArg(v13) + v9.AddArg2(v10, v12) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh64x64(v *Value) bool { v_1 := v.Args[1] @@ -1750,55 +1946,70 @@ func rewriteValuedec64_OpRsh64x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh64x64 x y) + // result: (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh64x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh64x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh64x8 (Int64Make hi lo) s) - // result: (Int64Make (Rsh32x8 <typ.UInt32> hi s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux8 <typ.UInt32> lo s) (Lsh32x8 <typ.UInt32> hi (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (And32 <typ.UInt32> (Rsh32x8 <typ.UInt32> hi (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))) (Zeromask (ZeroExt8to32 (Rsh8Ux32 <typ.UInt8> s (Const32 <typ.UInt32> [5]))))))) + // match: (Rsh64x8 x s) + // result: (Int64Make (Rsh32x8 <typ.UInt32> (Int64Hi x) s) (Or32 <typ.UInt32> (Or32 <typ.UInt32> (Rsh32Ux8 <typ.UInt32> (Int64Lo x) s) (Lsh32x8 <typ.UInt32> (Int64Hi x) (Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s))) (And32 <typ.UInt32> (Rsh32x8 <typ.UInt32> (Int64Hi x) (Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))) (Zeromask (ZeroExt8to32 (Rsh8Ux32 <typ.UInt8> s (Const32 <typ.UInt32> [5]))))))) for { - if v_0.Op != OpInt64Make { - break - } - lo := v_0.Args[1] - hi := v_0.Args[0] + x := v_0 s := v_1 v.reset(OpInt64Make) v0 := b.NewValue0(v.Pos, OpRsh32x8, typ.UInt32) - v0.AddArg2(hi, s) - v1 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v1.AddArg(x) + v0.AddArg2(v1, s) v2 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) - v3 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) - v3.AddArg2(lo, s) - v4 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) - v5 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v6 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) - v6.AuxInt = int8ToAuxInt(32) - v5.AddArg2(v6, s) - v4.AddArg2(hi, v5) - v2.AddArg2(v3, v4) - v7 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) - v8 := b.NewValue0(v.Pos, OpRsh32x8, typ.UInt32) - v9 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) - v9.AddArg2(s, v6) - v8.AddArg2(hi, v9) - v10 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) - v11 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) - v12 := b.NewValue0(v.Pos, OpRsh8Ux32, typ.UInt8) - v13 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) - v13.AuxInt = int32ToAuxInt(5) - v12.AddArg2(s, v13) - v11.AddArg(v12) - v10.AddArg(v11) - v7.AddArg2(v8, v10) - v1.AddArg2(v2, v7) - v.AddArg2(v0, v1) + v3 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v4 := b.NewValue0(v.Pos, OpRsh32Ux8, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v5.AddArg(x) + v4.AddArg2(v5, s) + v6 := b.NewValue0(v.Pos, OpLsh32x8, typ.UInt32) + v7 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v8 := b.NewValue0(v.Pos, OpConst8, typ.UInt8) + v8.AuxInt = int8ToAuxInt(32) + v7.AddArg2(v8, s) + v6.AddArg2(v1, v7) + v3.AddArg2(v4, v6) + v9 := b.NewValue0(v.Pos, OpAnd32, typ.UInt32) + v10 := b.NewValue0(v.Pos, OpRsh32x8, typ.UInt32) + v11 := b.NewValue0(v.Pos, OpSub8, typ.UInt8) + v11.AddArg2(s, v8) + v10.AddArg2(v1, v11) + v12 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v13 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v14 := b.NewValue0(v.Pos, OpRsh8Ux32, typ.UInt8) + v15 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v15.AuxInt = int32ToAuxInt(5) + v14.AddArg2(s, v15) + v13.AddArg(v14) + v12.AddArg(v13) + v9.AddArg2(v10, v12) + v2.AddArg2(v3, v9) + v.AddArg2(v0, v2) return true } - return false } func rewriteValuedec64_OpRsh8Ux64(v *Value) bool { v_1 := v.Args[1] @@ -1863,7 +2074,23 @@ func rewriteValuedec64_OpRsh8Ux64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh8Ux64 x y) + // result: (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh8Ux32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpRsh8x64(v *Value) bool { v_1 := v.Args[1] @@ -1931,7 +2158,23 @@ func rewriteValuedec64_OpRsh8x64(v *Value) bool { v.AddArg2(x, v0) return true } - return false + // match: (Rsh8x64 x y) + // result: (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y))) + for { + x := v_0 + y := v_1 + v.reset(OpRsh8x32) + v0 := b.NewValue0(v.Pos, OpOr32, typ.UInt32) + v1 := b.NewValue0(v.Pos, OpZeromask, typ.UInt32) + v2 := b.NewValue0(v.Pos, OpInt64Hi, typ.UInt32) + v2.AddArg(y) + v1.AddArg(v2) + v3 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v3.AddArg(y) + v0.AddArg2(v1, v3) + v.AddArg2(x, v0) + return true + } } func rewriteValuedec64_OpSignExt16to64(v *Value) bool { v_0 := v.Args[0] @@ -2071,6 +2314,8 @@ func rewriteValuedec64_OpSub64(v *Value) bool { } func rewriteValuedec64_OpTrunc64to16(v *Value) bool { v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types // match: (Trunc64to16 (Int64Make _ lo)) // result: (Trunc32to16 lo) for { @@ -2082,7 +2327,16 @@ func rewriteValuedec64_OpTrunc64to16(v *Value) bool { v.AddArg(lo) return true } - return false + // match: (Trunc64to16 x) + // result: (Trunc32to16 (Int64Lo x)) + for { + x := v_0 + v.reset(OpTrunc32to16) + v0 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v0.AddArg(x) + v.AddArg(v0) + return true + } } func rewriteValuedec64_OpTrunc64to32(v *Value) bool { v_0 := v.Args[0] @@ -2096,10 +2350,19 @@ func rewriteValuedec64_OpTrunc64to32(v *Value) bool { v.copyOf(lo) return true } - return false + // match: (Trunc64to32 x) + // result: (Int64Lo x) + for { + x := v_0 + v.reset(OpInt64Lo) + v.AddArg(x) + return true + } } func rewriteValuedec64_OpTrunc64to8(v *Value) bool { v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types // match: (Trunc64to8 (Int64Make _ lo)) // result: (Trunc32to8 lo) for { @@ -2111,7 +2374,16 @@ func rewriteValuedec64_OpTrunc64to8(v *Value) bool { v.AddArg(lo) return true } - return false + // match: (Trunc64to8 x) + // result: (Trunc32to8 (Int64Lo x)) + for { + x := v_0 + v.reset(OpTrunc32to8) + v0 := b.NewValue0(v.Pos, OpInt64Lo, typ.UInt32) + v0.AddArg(x) + v.AddArg(v0) + return true + } } func rewriteValuedec64_OpXor64(v *Value) bool { v_1 := v.Args[1] diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 180e48b34c..4cb9a8f328 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -124,6 +124,8 @@ func rewriteValuegeneric(v *Value) bool { return rewriteValuegeneric_OpIMake(v) case OpInterCall: return rewriteValuegeneric_OpInterCall(v) + case OpInterLECall: + return rewriteValuegeneric_OpInterLECall(v) case OpIsInBounds: return rewriteValuegeneric_OpIsInBounds(v) case OpIsNonNil: @@ -366,6 +368,8 @@ func rewriteValuegeneric(v *Value) bool { return rewriteValuegeneric_OpSelect0(v) case OpSelect1: return rewriteValuegeneric_OpSelect1(v) + case OpSelectN: + return rewriteValuegeneric_OpSelectN(v) case OpSignExt16to32: return rewriteValuegeneric_OpSignExt16to32(v) case OpSignExt16to64: @@ -390,6 +394,8 @@ func rewriteValuegeneric(v *Value) bool { return rewriteValuegeneric_OpSqrt(v) case OpStaticCall: return rewriteValuegeneric_OpStaticCall(v) + case OpStaticLECall: + return rewriteValuegeneric_OpStaticLECall(v) case OpStore: return rewriteValuegeneric_OpStore(v) case OpStringLen: @@ -5204,6 +5210,66 @@ func rewriteValuegeneric_OpDiv64u(v *Value) bool { return true } // match: (Div64u x (Const64 [c])) + // cond: c > 0 && c <= 0xFFFF && umagicOK32(int32(c)) && config.RegSize == 4 && config.useHmul + // result: (Add64 (Add64 <typ.UInt64> (Add64 <typ.UInt64> (Lsh64x64 <typ.UInt64> (ZeroExt32to64 (Div32u <typ.UInt32> (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) (Const32 <typ.UInt32> [int32(c)]))) (Const64 <typ.UInt64> [32])) (ZeroExt32to64 (Div32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)])))) (Mul64 <typ.UInt64> (ZeroExt32to64 <typ.UInt64> (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) (Const32 <typ.UInt32> [int32(c)]))) (Const64 <typ.UInt64> [int64((1<<32)/c)]))) (ZeroExt32to64 (Div32u <typ.UInt32> (Add32 <typ.UInt32> (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)])) (Mul32 <typ.UInt32> (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32]))) (Const32 <typ.UInt32> [int32(c)])) (Const32 <typ.UInt32> [int32((1<<32)%c)]))) (Const32 <typ.UInt32> [int32(c)])))) + for { + x := v_0 + if v_1.Op != OpConst64 { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(c > 0 && c <= 0xFFFF && umagicOK32(int32(c)) && config.RegSize == 4 && config.useHmul) { + break + } + v.reset(OpAdd64) + v0 := b.NewValue0(v.Pos, OpAdd64, typ.UInt64) + v1 := b.NewValue0(v.Pos, OpAdd64, typ.UInt64) + v2 := b.NewValue0(v.Pos, OpLsh64x64, typ.UInt64) + v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v4 := b.NewValue0(v.Pos, OpDiv32u, typ.UInt32) + v5 := b.NewValue0(v.Pos, OpTrunc64to32, typ.UInt32) + v6 := b.NewValue0(v.Pos, OpRsh64Ux64, typ.UInt64) + v7 := b.NewValue0(v.Pos, OpConst64, typ.UInt64) + v7.AuxInt = int64ToAuxInt(32) + v6.AddArg2(x, v7) + v5.AddArg(v6) + v8 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v8.AuxInt = int32ToAuxInt(int32(c)) + v4.AddArg2(v5, v8) + v3.AddArg(v4) + v2.AddArg2(v3, v7) + v9 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v10 := b.NewValue0(v.Pos, OpDiv32u, typ.UInt32) + v11 := b.NewValue0(v.Pos, OpTrunc64to32, typ.UInt32) + v11.AddArg(x) + v10.AddArg2(v11, v8) + v9.AddArg(v10) + v1.AddArg2(v2, v9) + v12 := b.NewValue0(v.Pos, OpMul64, typ.UInt64) + v13 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v14 := b.NewValue0(v.Pos, OpMod32u, typ.UInt32) + v14.AddArg2(v5, v8) + v13.AddArg(v14) + v15 := b.NewValue0(v.Pos, OpConst64, typ.UInt64) + v15.AuxInt = int64ToAuxInt(int64((1 << 32) / c)) + v12.AddArg2(v13, v15) + v0.AddArg2(v1, v12) + v16 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v17 := b.NewValue0(v.Pos, OpDiv32u, typ.UInt32) + v18 := b.NewValue0(v.Pos, OpAdd32, typ.UInt32) + v19 := b.NewValue0(v.Pos, OpMod32u, typ.UInt32) + v19.AddArg2(v11, v8) + v20 := b.NewValue0(v.Pos, OpMul32, typ.UInt32) + v21 := b.NewValue0(v.Pos, OpConst32, typ.UInt32) + v21.AuxInt = int32ToAuxInt(int32((1 << 32) % c)) + v20.AddArg2(v14, v21) + v18.AddArg2(v19, v20) + v17.AddArg2(v18, v8) + v16.AddArg(v17) + v.AddArg2(v0, v16) + return true + } + // match: (Div64u x (Const64 [c])) // cond: umagicOK64(c) && config.RegSize == 8 && umagic64(c).m&1 == 0 && config.useHmul // result: (Rsh64Ux64 <typ.UInt64> (Hmul64u <typ.UInt64> (Const64 <typ.UInt64> [int64(1<<63+umagic64(c).m/2)]) x) (Const64 <typ.UInt64> [umagic64(c).s-1])) for { @@ -8479,11 +8545,12 @@ func rewriteValuegeneric_OpIMake(v *Value) bool { func rewriteValuegeneric_OpInterCall(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - // match: (InterCall [argsize] (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) - // cond: devirt(v, itab, off) != nil - // result: (StaticCall [int32(argsize)] {devirt(v, itab, off)} mem) + // match: (InterCall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) + // cond: devirt(v, auxCall, itab, off) != nil + // result: (StaticCall [int32(argsize)] {devirt(v, auxCall, itab, off)} mem) for { - argsize := auxIntToInt64(v.AuxInt) + argsize := auxIntToInt32(v.AuxInt) + auxCall := auxToCall(v.Aux) if v_0.Op != OpLoad { break } @@ -8510,17 +8577,57 @@ func rewriteValuegeneric_OpInterCall(v *Value) bool { break } mem := v_1 - if !(devirt(v, itab, off) != nil) { + if !(devirt(v, auxCall, itab, off) != nil) { break } v.reset(OpStaticCall) v.AuxInt = int32ToAuxInt(int32(argsize)) - v.Aux = symToAux(devirt(v, itab, off)) + v.Aux = callToAux(devirt(v, auxCall, itab, off)) v.AddArg(mem) return true } return false } +func rewriteValuegeneric_OpInterLECall(v *Value) bool { + // match: (InterLECall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) ___) + // cond: devirtLESym(v, auxCall, itab, off) != nil + // result: devirtLECall(v, devirtLESym(v, auxCall, itab, off)) + for { + if len(v.Args) < 1 { + break + } + auxCall := auxToCall(v.Aux) + v_0 := v.Args[0] + if v_0.Op != OpLoad { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpOffPtr { + break + } + off := auxIntToInt64(v_0_0.AuxInt) + v_0_0_0 := v_0_0.Args[0] + if v_0_0_0.Op != OpITab { + break + } + v_0_0_0_0 := v_0_0_0.Args[0] + if v_0_0_0_0.Op != OpIMake { + break + } + v_0_0_0_0_0 := v_0_0_0_0.Args[0] + if v_0_0_0_0_0.Op != OpAddr { + break + } + itab := auxToSym(v_0_0_0_0_0.Aux) + v_0_0_0_0_0_0 := v_0_0_0_0_0.Args[0] + if v_0_0_0_0_0_0.Op != OpSB || !(devirtLESym(v, auxCall, itab, off) != nil) { + break + } + v.copyOf(devirtLECall(v, devirtLESym(v, auxCall, itab, off))) + return true + } + return false +} func rewriteValuegeneric_OpIsInBounds(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -16022,7 +16129,7 @@ func rewriteValuegeneric_OpNilCheck(v *Value) bool { return true } // match: (NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _) - // cond: symNamed(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check") + // cond: isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check") // result: (Invalid) for { if v_0.Op != OpLoad { @@ -16042,15 +16149,15 @@ func rewriteValuegeneric_OpNilCheck(v *Value) bool { if v_0_1.Op != OpStaticCall { break } - sym := auxToSym(v_0_1.Aux) - if !(symNamed(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) { + sym := auxToCall(v_0_1.Aux) + if !(isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) { break } v.reset(OpInvalid) return true } // match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _) - // cond: symNamed(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check") + // cond: isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check") // result: (Invalid) for { if v_0.Op != OpOffPtr { @@ -16074,8 +16181,40 @@ func rewriteValuegeneric_OpNilCheck(v *Value) bool { if v_0_0_1.Op != OpStaticCall { break } - sym := auxToSym(v_0_0_1.Aux) - if !(symNamed(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) { + sym := auxToCall(v_0_0_1.Aux) + if !(isSameCall(sym, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(fe.Debug_checknil(), v, "removed nil check")) { + break + } + v.reset(OpInvalid) + return true + } + // match: (NilCheck (SelectN [0] call:(StaticLECall _ _)) (SelectN [1] call)) + // cond: isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check") + // result: (Invalid) + for { + if v_0.Op != OpSelectN || auxIntToInt64(v_0.AuxInt) != 0 { + break + } + call := v_0.Args[0] + if call.Op != OpStaticLECall || len(call.Args) != 2 || v_1.Op != OpSelectN || auxIntToInt64(v_1.AuxInt) != 1 || call != v_1.Args[0] || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) { + break + } + v.reset(OpInvalid) + return true + } + // match: (NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) (SelectN [1] call)) + // cond: isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check") + // result: (Invalid) + for { + if v_0.Op != OpOffPtr { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpSelectN || auxIntToInt64(v_0_0.AuxInt) != 0 { + break + } + call := v_0_0.Args[0] + if call.Op != OpStaticLECall || len(call.Args) != 2 || v_1.Op != OpSelectN || auxIntToInt64(v_1.AuxInt) != 1 || call != v_1.Args[0] || !(isSameCall(call.Aux, "runtime.newobject") && warnRule(fe.Debug_checknil(), v, "removed nil check")) { break } v.reset(OpInvalid) @@ -18548,6 +18687,9 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { // match: (Phi (Const8 [c]) (Const8 [c])) // result: (Const8 [c]) for { + if len(v.Args) != 2 { + break + } _ = v.Args[1] v_0 := v.Args[0] if v_0.Op != OpConst8 { @@ -18555,7 +18697,7 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { } c := auxIntToInt8(v_0.AuxInt) v_1 := v.Args[1] - if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != c || len(v.Args) != 2 { + if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != c { break } v.reset(OpConst8) @@ -18565,6 +18707,9 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { // match: (Phi (Const16 [c]) (Const16 [c])) // result: (Const16 [c]) for { + if len(v.Args) != 2 { + break + } _ = v.Args[1] v_0 := v.Args[0] if v_0.Op != OpConst16 { @@ -18572,7 +18717,7 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { } c := auxIntToInt16(v_0.AuxInt) v_1 := v.Args[1] - if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != c || len(v.Args) != 2 { + if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != c { break } v.reset(OpConst16) @@ -18582,6 +18727,9 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { // match: (Phi (Const32 [c]) (Const32 [c])) // result: (Const32 [c]) for { + if len(v.Args) != 2 { + break + } _ = v.Args[1] v_0 := v.Args[0] if v_0.Op != OpConst32 { @@ -18589,7 +18737,7 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { } c := auxIntToInt32(v_0.AuxInt) v_1 := v.Args[1] - if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != c || len(v.Args) != 2 { + if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != c { break } v.reset(OpConst32) @@ -18599,6 +18747,9 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { // match: (Phi (Const64 [c]) (Const64 [c])) // result: (Const64 [c]) for { + if len(v.Args) != 2 { + break + } _ = v.Args[1] v_0 := v.Args[0] if v_0.Op != OpConst64 { @@ -18606,7 +18757,7 @@ func rewriteValuegeneric_OpPhi(v *Value) bool { } c := auxIntToInt64(v_0.AuxInt) v_1 := v.Args[1] - if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || len(v.Args) != 2 { + if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c { break } v.reset(OpConst64) @@ -20614,6 +20765,100 @@ func rewriteValuegeneric_OpSelect1(v *Value) bool { } return false } +func rewriteValuegeneric_OpSelectN(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + config := b.Func.Config + // match: (SelectN [0] (MakeResult a ___)) + // result: a + for { + if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpMakeResult || len(v_0.Args) < 1 { + break + } + a := v_0.Args[0] + v.copyOf(a) + return true + } + // match: (SelectN [1] (MakeResult a b ___)) + // result: b + for { + if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpMakeResult || len(v_0.Args) < 2 { + break + } + b := v_0.Args[1] + v.copyOf(b) + return true + } + // match: (SelectN [2] (MakeResult a b c ___)) + // result: c + for { + if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpMakeResult || len(v_0.Args) < 3 { + break + } + c := v_0.Args[2] + v.copyOf(c) + return true + } + // match: (SelectN [0] call:(StaticLECall {sym} dst src (Const64 [sz]) mem)) + // cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call) + // result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem) + for { + if auxIntToInt64(v.AuxInt) != 0 { + break + } + call := v_0 + if call.Op != OpStaticLECall || len(call.Args) != 4 { + break + } + sym := auxToCall(call.Aux) + mem := call.Args[3] + dst := call.Args[0] + src := call.Args[1] + call_2 := call.Args[2] + if call_2.Op != OpConst64 { + break + } + sz := auxIntToInt64(call_2.AuxInt) + if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) { + break + } + v.reset(OpMove) + v.AuxInt = int64ToAuxInt(int64(sz)) + v.Aux = typeToAux(dst.Type.Elem()) + v.AddArg3(dst, src, mem) + return true + } + // match: (SelectN [0] call:(StaticLECall {sym} dst src (Const32 [sz]) mem)) + // cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call) + // result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem) + for { + if auxIntToInt64(v.AuxInt) != 0 { + break + } + call := v_0 + if call.Op != OpStaticLECall || len(call.Args) != 4 { + break + } + sym := auxToCall(call.Aux) + mem := call.Args[3] + dst := call.Args[0] + src := call.Args[1] + call_2 := call.Args[2] + if call_2.Op != OpConst32 { + break + } + sz := auxIntToInt32(call_2.AuxInt) + if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) { + break + } + v.reset(OpMove) + v.AuxInt = int64ToAuxInt(int64(sz)) + v.Aux = typeToAux(dst.Type.Elem()) + v.AddArg3(dst, src, mem) + return true + } + return false +} func rewriteValuegeneric_OpSignExt16to32(v *Value) bool { v_0 := v.Args[0] // match: (SignExt16to32 (Const16 [c])) @@ -21067,10 +21312,10 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { b := v.Block config := b.Func.Config // match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))) - // cond: sz >= 0 && symNamed(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3) + // cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3) // result: (Move {t.Elem()} [int64(sz)] dst src mem) for { - sym := auxToSym(v.Aux) + sym := auxToCall(v.Aux) s1 := v_0 if s1.Op != OpStore { break @@ -21094,7 +21339,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { t := auxToType(s3.Aux) mem := s3.Args[2] dst := s3.Args[1] - if !(sz >= 0 && symNamed(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) { + if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) { break } v.reset(OpMove) @@ -21104,10 +21349,10 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { return true } // match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))) - // cond: sz >= 0 && symNamed(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3) + // cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3) // result: (Move {t.Elem()} [int64(sz)] dst src mem) for { - sym := auxToSym(v.Aux) + sym := auxToCall(v.Aux) s1 := v_0 if s1.Op != OpStore { break @@ -21131,7 +21376,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { t := auxToType(s3.Aux) mem := s3.Args[2] dst := s3.Args[1] - if !(sz >= 0 && symNamed(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) { + if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3)) { break } v.reset(OpMove) @@ -21144,7 +21389,7 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { // cond: needRaceCleanup(sym, v) // result: x for { - sym := auxToSym(v.Aux) + sym := auxToCall(v.Aux) x := v_0 if !(needRaceCleanup(sym, v)) { break @@ -21154,6 +21399,44 @@ func rewriteValuegeneric_OpStaticCall(v *Value) bool { } return false } +func rewriteValuegeneric_OpStaticLECall(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [1]) mem) + // cond: isSameCall(callAux, "runtime.memequal") && symIsRO(scon) + // result: (MakeResult (Eq8 (Load <typ.Int8> sptr mem) (Const8 <typ.Int8> [int8(read8(scon,0))])) mem) + for { + if len(v.Args) != 4 { + break + } + callAux := auxToCall(v.Aux) + mem := v.Args[3] + sptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAddr { + break + } + scon := auxToSym(v_1.Aux) + v_1_0 := v_1.Args[0] + if v_1_0.Op != OpSB { + break + } + v_2 := v.Args[2] + if v_2.Op != OpConst64 || auxIntToInt64(v_2.AuxInt) != 1 || !(isSameCall(callAux, "runtime.memequal") && symIsRO(scon)) { + break + } + v.reset(OpMakeResult) + v0 := b.NewValue0(v.Pos, OpEq8, typ.Bool) + v1 := b.NewValue0(v.Pos, OpLoad, typ.Int8) + v1.AddArg2(sptr, mem) + v2 := b.NewValue0(v.Pos, OpConst8, typ.Int8) + v2.AuxInt = int8ToAuxInt(int8(read8(scon, 0))) + v0.AddArg2(v1, v2) + v.AddArg2(v0, mem) + return true + } + return false +} func rewriteValuegeneric_OpStore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -21608,7 +21891,7 @@ func rewriteValuegeneric_OpStore(v *Value) bool { return true } // match: (Store (Load (OffPtr [c] (SP)) mem) x mem) - // cond: isConstZero(x) && mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize + // cond: isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // result: mem for { if v_0.Op != OpLoad { @@ -21625,14 +21908,14 @@ func rewriteValuegeneric_OpStore(v *Value) bool { break } x := v_1 - if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { + if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { break } v.copyOf(mem) return true } // match: (Store (OffPtr (Load (OffPtr [c] (SP)) mem)) x mem) - // cond: isConstZero(x) && mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize + // cond: isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // result: mem for { if v_0.Op != OpOffPtr { @@ -21653,7 +21936,49 @@ func rewriteValuegeneric_OpStore(v *Value) bool { break } x := v_1 - if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { + if mem != v_2 || !(isConstZero(x) && mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { + break + } + v.copyOf(mem) + return true + } + // match: (Store (SelectN [0] call:(StaticLECall _ _)) x mem:(SelectN [1] call)) + // cond: isConstZero(x) && isSameCall(call.Aux, "runtime.newobject") + // result: mem + for { + if v_0.Op != OpSelectN || auxIntToInt64(v_0.AuxInt) != 0 { + break + } + call := v_0.Args[0] + if call.Op != OpStaticLECall || len(call.Args) != 2 { + break + } + x := v_1 + mem := v_2 + if mem.Op != OpSelectN || auxIntToInt64(mem.AuxInt) != 1 || call != mem.Args[0] || !(isConstZero(x) && isSameCall(call.Aux, "runtime.newobject")) { + break + } + v.copyOf(mem) + return true + } + // match: (Store (OffPtr (SelectN [0] call:(StaticLECall _ _))) x mem:(SelectN [1] call)) + // cond: isConstZero(x) && isSameCall(call.Aux, "runtime.newobject") + // result: mem + for { + if v_0.Op != OpOffPtr { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpSelectN || auxIntToInt64(v_0_0.AuxInt) != 0 { + break + } + call := v_0_0.Args[0] + if call.Op != OpStaticLECall || len(call.Args) != 2 { + break + } + x := v_1 + mem := v_2 + if mem.Op != OpSelectN || auxIntToInt64(mem.AuxInt) != 1 || call != mem.Args[0] || !(isConstZero(x) && isSameCall(call.Aux, "runtime.newobject")) { break } v.copyOf(mem) @@ -24337,7 +24662,7 @@ func rewriteValuegeneric_OpZero(v *Value) bool { b := v.Block config := b.Func.Config // match: (Zero (Load (OffPtr [c] (SP)) mem) mem) - // cond: mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize + // cond: mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize // result: mem for { if v_0.Op != OpLoad { @@ -24350,7 +24675,25 @@ func rewriteValuegeneric_OpZero(v *Value) bool { } c := auxIntToInt64(v_0_0.AuxInt) v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpSP || mem != v_1 || !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { + if v_0_0_0.Op != OpSP || mem != v_1 || !(mem.Op == OpStaticCall && isSameCall(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize) { + break + } + v.copyOf(mem) + return true + } + // match: (Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call)) + // cond: isSameCall(call.Aux, "runtime.newobject") + // result: mem + for { + if v_0.Op != OpSelectN || auxIntToInt64(v_0.AuxInt) != 0 { + break + } + call := v_0.Args[0] + if call.Op != OpStaticLECall || len(call.Args) != 2 { + break + } + mem := v_1 + if mem.Op != OpSelectN || auxIntToInt64(mem.AuxInt) != 1 || call != mem.Args[0] || !(isSameCall(call.Aux, "runtime.newobject")) { break } v.copyOf(mem) diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go index c5df457c4e..7b4ee2e81c 100644 --- a/src/cmd/compile/internal/ssa/shortcircuit.go +++ b/src/cmd/compile/internal/ssa/shortcircuit.go @@ -261,11 +261,6 @@ func shortcircuitBlock(b *Block) bool { // and the CFG modifications must not proceed. // The returned function assumes that shortcircuitBlock has completed its CFG modifications. func shortcircuitPhiPlan(b *Block, ctl *Value, cidx int, ti int64) func(*Value, int) { - const go115shortcircuitPhis = true - if !go115shortcircuitPhis { - return nil - } - // t is the "taken" branch: the successor we always go to when coming in from p. t := b.Succs[ti].b // u is the "untaken" branch: the successor we never go to when coming in from p. diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go index 7612585136..406a3c3ea5 100644 --- a/src/cmd/compile/internal/ssa/stackalloc.go +++ b/src/cmd/compile/internal/ssa/stackalloc.go @@ -153,6 +153,9 @@ func (s *stackAllocState) stackalloc() { if v.Op != OpArg { continue } + if v.Aux == nil { + f.Fatalf("%s has nil Aux\n", v.LongString()) + } loc := LocalSlot{N: v.Aux.(GCNode), Type: v.Type, Off: v.AuxInt} if f.pass.debug > stackDebug { fmt.Printf("stackalloc %s to %s\n", v, loc) diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go index 6692df7921..edc43aaae7 100644 --- a/src/cmd/compile/internal/ssa/value.go +++ b/src/cmd/compile/internal/ssa/value.go @@ -193,11 +193,11 @@ func (v *Value) auxString() string { return fmt.Sprintf(" [%g]", v.AuxFloat()) case auxString: return fmt.Sprintf(" {%q}", v.Aux) - case auxSym, auxTyp: + case auxSym, auxCall, auxTyp: if v.Aux != nil { return fmt.Sprintf(" {%v}", v.Aux) } - case auxSymOff, auxTypSize: + case auxSymOff, auxCallOff, auxTypSize: s := "" if v.Aux != nil { s = fmt.Sprintf(" {%v}", v.Aux) @@ -348,6 +348,9 @@ func (v *Value) reset(op Op) { // It modifies v to be (Copy a). //go:noinline func (v *Value) copyOf(a *Value) { + if v == a { + return + } if v.InCache { v.Block.Func.unCache(v) } diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go index 214798a1ab..849c9e8967 100644 --- a/src/cmd/compile/internal/ssa/writebarrier.go +++ b/src/cmd/compile/internal/ssa/writebarrier.go @@ -125,23 +125,7 @@ func writebarrier(f *Func) { // lazily initialize global values for write barrier test and calls // find SB and SP values in entry block initpos := f.Entry.Pos - for _, v := range f.Entry.Values { - if v.Op == OpSB { - sb = v - } - if v.Op == OpSP { - sp = v - } - if sb != nil && sp != nil { - break - } - } - if sb == nil { - sb = f.Entry.NewValue0(initpos, OpSB, f.Config.Types.Uintptr) - } - if sp == nil { - sp = f.Entry.NewValue0(initpos, OpSP, f.Config.Types.Uintptr) - } + sp, sb = f.spSb() wbsym := f.fe.Syslook("writeBarrier") wbaddr = f.Entry.NewValue1A(initpos, OpAddr, f.Config.Types.UInt32Ptr, wbsym, sb) gcWriteBarrier = f.fe.Syslook("gcWriteBarrier") @@ -501,29 +485,33 @@ func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Va // put arguments on stack off := config.ctxt.FixedFrameSize() + var ACArgs []Param if typ != nil { // for typedmemmove taddr := b.NewValue1A(pos, OpAddr, b.Func.Config.Types.Uintptr, typ, sb) off = round(off, taddr.Type.Alignment()) arg := b.NewValue1I(pos, OpOffPtr, taddr.Type.PtrTo(), off, sp) mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, taddr, mem) + ACArgs = append(ACArgs, Param{Type: b.Func.Config.Types.Uintptr, Offset: int32(off)}) off += taddr.Type.Size() } off = round(off, ptr.Type.Alignment()) arg := b.NewValue1I(pos, OpOffPtr, ptr.Type.PtrTo(), off, sp) mem = b.NewValue3A(pos, OpStore, types.TypeMem, ptr.Type, arg, ptr, mem) + ACArgs = append(ACArgs, Param{Type: ptr.Type, Offset: int32(off)}) off += ptr.Type.Size() if val != nil { off = round(off, val.Type.Alignment()) arg = b.NewValue1I(pos, OpOffPtr, val.Type.PtrTo(), off, sp) mem = b.NewValue3A(pos, OpStore, types.TypeMem, val.Type, arg, val, mem) + ACArgs = append(ACArgs, Param{Type: val.Type, Offset: int32(off)}) off += val.Type.Size() } off = round(off, config.PtrSize) // issue call - mem = b.NewValue1A(pos, OpStaticCall, types.TypeMem, fn, mem) + mem = b.NewValue1A(pos, OpStaticCall, types.TypeMem, StaticAuxCall(fn, ACArgs, nil), mem) mem.AuxInt = off - config.ctxt.FixedFrameSize() return mem } @@ -539,7 +527,7 @@ func IsStackAddr(v *Value) bool { v = v.Args[0] } switch v.Op { - case OpSP, OpLocalAddr: + case OpSP, OpLocalAddr, OpSelectNAddr: return true } return false @@ -582,7 +570,7 @@ func IsNewObject(v *Value, mem *Value) bool { if mem.Op != OpStaticCall { return false } - if !isSameSym(mem.Aux, "runtime.newobject") { + if !isSameCall(mem.Aux, "runtime.newobject") { return false } if v.Args[0].Op != OpOffPtr { @@ -605,7 +593,7 @@ func IsSanitizerSafeAddr(v *Value) bool { v = v.Args[0] } switch v.Op { - case OpSP, OpLocalAddr: + case OpSP, OpLocalAddr, OpSelectNAddr: // Stack addresses are always safe. return true case OpITab, OpStringPtr, OpGetClosurePtr: @@ -621,7 +609,7 @@ func IsSanitizerSafeAddr(v *Value) bool { // isVolatile reports whether v is a pointer to argument region on stack which // will be clobbered by a function call. func isVolatile(v *Value) bool { - for v.Op == OpOffPtr || v.Op == OpAddPtr || v.Op == OpPtrIndex || v.Op == OpCopy { + for v.Op == OpOffPtr || v.Op == OpAddPtr || v.Op == OpPtrIndex || v.Op == OpCopy || v.Op == OpSelectNAddr { v = v.Args[0] } return v.Op == OpSP diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index 9601fab9e0..1485b70059 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -287,6 +287,7 @@ func tokstring(tok token) string { // Convenience methods using the current token position. func (p *parser) pos() Pos { return p.posAt(p.line, p.col) } +func (p *parser) error(msg string) { p.errorAt(p.pos(), msg) } func (p *parser) syntaxError(msg string) { p.syntaxErrorAt(p.pos(), msg) } // The stopset contains keywords that start a statement. @@ -997,17 +998,20 @@ loop: // x[i:j... t.Index[1] = p.expr() } - if p.got(_Colon) { + if p.tok == _Colon { t.Full = true // x[i:j:...] if t.Index[1] == nil { p.error("middle index required in 3-index slice") + t.Index[1] = p.badExpr() } + p.next() if p.tok != _Rbrack { // x[i:j:k... t.Index[2] = p.expr() } else { p.error("final index required in 3-index slice") + t.Index[2] = p.badExpr() } } p.want(_Rbrack) @@ -1836,6 +1840,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS if p.tok == _Lbrace { if keyword == _If { p.syntaxError("missing condition in if statement") + cond = p.badExpr() } return } @@ -1907,6 +1912,9 @@ done: } else { p.syntaxErrorAt(semi.pos, "missing condition in if statement") } + b := new(BadExpr) + b.pos = semi.pos + cond = b } case *ExprStmt: cond = s.X diff --git a/src/cmd/compile/internal/test/divconst_test.go b/src/cmd/compile/internal/test/divconst_test.go index b03550058f..9358a60374 100644 --- a/src/cmd/compile/internal/test/divconst_test.go +++ b/src/cmd/compile/internal/test/divconst_test.go @@ -44,10 +44,85 @@ func BenchmarkDivisibleWDivconstI64(b *testing.B) { var u64res uint64 -func BenchmarkDivconstU64(b *testing.B) { - for i := 0; i < b.N; i++ { - u64res = uint64(i) / 7 +func TestDivmodConstU64(t *testing.T) { + // Test division by c. Function f must be func(n) { return n/c, n%c } + testdiv := func(c uint64, f func(uint64) (uint64, uint64)) func(*testing.T) { + return func(t *testing.T) { + x := uint64(12345) + for i := 0; i < 10000; i++ { + x += x << 2 + q, r := f(x) + if r < 0 || r >= c || q*c+r != x { + t.Errorf("divmod(%d, %d) returned incorrect (%d, %d)", x, c, q, r) + } + } + max := uint64(1<<64-1) / c * c + xs := []uint64{0, 1, c - 1, c, c + 1, 2*c - 1, 2 * c, 2*c + 1, + c*c - 1, c * c, c*c + 1, max - 1, max, max + 1, 1<<64 - 1} + for _, x := range xs { + q, r := f(x) + if r < 0 || r >= c || q*c+r != x { + t.Errorf("divmod(%d, %d) returned incorrect (%d, %d)", x, c, q, r) + } + } + } } + t.Run("2", testdiv(2, func(n uint64) (uint64, uint64) { return n / 2, n % 2 })) + t.Run("3", testdiv(3, func(n uint64) (uint64, uint64) { return n / 3, n % 3 })) + t.Run("4", testdiv(4, func(n uint64) (uint64, uint64) { return n / 4, n % 4 })) + t.Run("5", testdiv(5, func(n uint64) (uint64, uint64) { return n / 5, n % 5 })) + t.Run("6", testdiv(6, func(n uint64) (uint64, uint64) { return n / 6, n % 6 })) + t.Run("7", testdiv(7, func(n uint64) (uint64, uint64) { return n / 7, n % 7 })) + t.Run("8", testdiv(8, func(n uint64) (uint64, uint64) { return n / 8, n % 8 })) + t.Run("9", testdiv(9, func(n uint64) (uint64, uint64) { return n / 9, n % 9 })) + t.Run("10", testdiv(10, func(n uint64) (uint64, uint64) { return n / 10, n % 10 })) + t.Run("11", testdiv(11, func(n uint64) (uint64, uint64) { return n / 11, n % 11 })) + t.Run("12", testdiv(12, func(n uint64) (uint64, uint64) { return n / 12, n % 12 })) + t.Run("13", testdiv(13, func(n uint64) (uint64, uint64) { return n / 13, n % 13 })) + t.Run("14", testdiv(14, func(n uint64) (uint64, uint64) { return n / 14, n % 14 })) + t.Run("15", testdiv(15, func(n uint64) (uint64, uint64) { return n / 15, n % 15 })) + t.Run("16", testdiv(16, func(n uint64) (uint64, uint64) { return n / 16, n % 16 })) + t.Run("17", testdiv(17, func(n uint64) (uint64, uint64) { return n / 17, n % 17 })) + t.Run("255", testdiv(255, func(n uint64) (uint64, uint64) { return n / 255, n % 255 })) + t.Run("256", testdiv(256, func(n uint64) (uint64, uint64) { return n / 256, n % 256 })) + t.Run("257", testdiv(257, func(n uint64) (uint64, uint64) { return n / 257, n % 257 })) + t.Run("65535", testdiv(65535, func(n uint64) (uint64, uint64) { return n / 65535, n % 65535 })) + t.Run("65536", testdiv(65536, func(n uint64) (uint64, uint64) { return n / 65536, n % 65536 })) + t.Run("65537", testdiv(65537, func(n uint64) (uint64, uint64) { return n / 65537, n % 65537 })) + t.Run("1<<32-1", testdiv(1<<32-1, func(n uint64) (uint64, uint64) { return n / (1<<32 - 1), n % (1<<32 - 1) })) + t.Run("1<<32+1", testdiv(1<<32+1, func(n uint64) (uint64, uint64) { return n / (1<<32 + 1), n % (1<<32 + 1) })) + t.Run("1<<64-1", testdiv(1<<64-1, func(n uint64) (uint64, uint64) { return n / (1<<64 - 1), n % (1<<64 - 1) })) +} + +func BenchmarkDivconstU64(b *testing.B) { + b.Run("3", func(b *testing.B) { + x := uint64(123456789123456789) + for i := 0; i < b.N; i++ { + x += x << 4 + u64res = uint64(x) / 3 + } + }) + b.Run("5", func(b *testing.B) { + x := uint64(123456789123456789) + for i := 0; i < b.N; i++ { + x += x << 4 + u64res = uint64(x) / 5 + } + }) + b.Run("37", func(b *testing.B) { + x := uint64(123456789123456789) + for i := 0; i < b.N; i++ { + x += x << 4 + u64res = uint64(x) / 37 + } + }) + b.Run("1234567", func(b *testing.B) { + x := uint64(123456789123456789) + for i := 0; i < b.N; i++ { + x += x << 4 + u64res = uint64(x) / 1234567 + } + }) } func BenchmarkModconstU64(b *testing.B) { diff --git a/src/cmd/compile/internal/types/etype_string.go b/src/cmd/compile/internal/types/etype_string.go index 0ff05a8c2a..14fd5b71df 100644 --- a/src/cmd/compile/internal/types/etype_string.go +++ b/src/cmd/compile/internal/types/etype_string.go @@ -44,12 +44,13 @@ func _() { _ = x[TCHANARGS-33] _ = x[TSSA-34] _ = x[TTUPLE-35] - _ = x[NTYPE-36] + _ = x[TRESULTS-36] + _ = x[NTYPE-37] } -const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSSSATUPLENTYPE" +const _EType_name = "xxxINT8UINT8INT16UINT16INT32UINT32INT64UINT64INTUINTUINTPTRCOMPLEX64COMPLEX128FLOAT32FLOAT64BOOLPTRFUNCSLICEARRAYSTRUCTCHANMAPINTERFORWANYSTRINGUNSAFEPTRIDEALNILBLANKFUNCARGSCHANARGSSSATUPLERESULTSNTYPE" -var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 158, 161, 166, 174, 182, 185, 190, 195} +var _EType_index = [...]uint8{0, 3, 7, 12, 17, 23, 28, 34, 39, 45, 48, 52, 59, 68, 78, 85, 92, 96, 99, 103, 108, 113, 119, 123, 126, 131, 135, 138, 144, 153, 158, 161, 166, 174, 182, 185, 190, 197, 202} func (i EType) String() string { if i >= EType(len(_EType_index)-1) { diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index e4b3d885d9..023ab9af88 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -66,8 +66,9 @@ const ( TCHANARGS // SSA backend types - TSSA // internal types used by SSA backend (flags, memory, etc.) - TTUPLE // a pair of types, used by SSA backend + TSSA // internal types used by SSA backend (flags, memory, etc.) + TTUPLE // a pair of types, used by SSA backend + TRESULTS // multiple types; the result of calling a function or method, with a memory at the end. NTYPE ) @@ -104,14 +105,14 @@ var ( Errortype *Type // Types to represent untyped string and boolean constants. - Idealstring *Type - Idealbool *Type + UntypedString *Type + UntypedBool *Type // Types to represent untyped numeric constants. - Idealint = New(TIDEAL) - Idealrune = New(TIDEAL) - Idealfloat = New(TIDEAL) - Idealcomplex = New(TIDEAL) + UntypedInt = New(TIDEAL) + UntypedRune = New(TIDEAL) + UntypedFloat = New(TIDEAL) + UntypedComplex = New(TIDEAL) ) // A Type represents a Go type. @@ -330,6 +331,11 @@ type Tuple struct { // Any tuple with a memory type must put that memory type second. } +// Results are the output from calls that will be late-expanded. +type Results struct { + Types []*Type // Last element is memory output from call. +} + // Array contains Type fields specific to array types. type Array struct { Elem *Type // element type @@ -466,6 +472,8 @@ func New(et EType) *Type { t.Extra = new(Chan) case TTUPLE: t.Extra = new(Tuple) + case TRESULTS: + t.Extra = new(Results) } return t } @@ -512,6 +520,12 @@ func NewTuple(t1, t2 *Type) *Type { return t } +func NewResults(types []*Type) *Type { + t := New(TRESULTS) + t.Extra.(*Results).Types = types + return t +} + func newSSA(name string) *Type { t := New(TSSA) t.Extra = name @@ -688,7 +702,7 @@ func (t *Type) copy() *Type { case TARRAY: x := *t.Extra.(*Array) nt.Extra = &x - case TTUPLE, TSSA: + case TTUPLE, TSSA, TRESULTS: Fatalf("ssa types cannot be copied") } // TODO(mdempsky): Find out why this is necessary and explain. @@ -1051,6 +1065,23 @@ func (t *Type) cmp(x *Type) Cmp { } return ttup.second.Compare(xtup.second) + case TRESULTS: + xResults := x.Extra.(*Results) + tResults := t.Extra.(*Results) + xl, tl := len(xResults.Types), len(tResults.Types) + if tl != xl { + if tl < xl { + return CMPlt + } + return CMPgt + } + for i := 0; i < tl; i++ { + if c := tResults.Types[i].Compare(xResults.Types[i]); c != CMPeq { + return c + } + } + return CMPeq + case TMAP: if c := t.Key().cmp(x.Key()); c != CMPeq { return c @@ -1230,6 +1261,11 @@ func (t *Type) IsUnsafePtr() bool { return t.Etype == TUNSAFEPTR } +// IsUintptr reports whether t is an uintptr. +func (t *Type) IsUintptr() bool { + return t.Etype == TUINTPTR +} + // IsPtrShaped reports whether t is represented by a single machine pointer. // In addition to regular Go pointer types, this includes map, channel, and // function types and unsafe.Pointer. It does not include array or struct types @@ -1300,6 +1336,9 @@ func (t *Type) FieldType(i int) *Type { panic("bad tuple index") } } + if t.Etype == TRESULTS { + return t.Extra.(*Results).Types[i] + } return t.Field(i).Type } func (t *Type) FieldOff(i int) int64 { @@ -1377,18 +1416,27 @@ func (t *Type) ChanDir() ChanDir { } func (t *Type) IsMemory() bool { - return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem + if t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem { + return true + } + if t.Etype == TRESULTS { + if types := t.Extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem { + return true + } + } + return false } -func (t *Type) IsFlags() bool { return t == TypeFlags } -func (t *Type) IsVoid() bool { return t == TypeVoid } -func (t *Type) IsTuple() bool { return t.Etype == TTUPLE } +func (t *Type) IsFlags() bool { return t == TypeFlags } +func (t *Type) IsVoid() bool { return t == TypeVoid } +func (t *Type) IsTuple() bool { return t.Etype == TTUPLE } +func (t *Type) IsResults() bool { return t.Etype == TRESULTS } // IsUntyped reports whether t is an untyped type. func (t *Type) IsUntyped() bool { if t == nil { return false } - if t == Idealstring || t == Idealbool { + if t == UntypedString || t == UntypedBool { return true } switch t.Etype { @@ -1426,6 +1474,15 @@ func (t *Type) HasPointers() bool { case TTUPLE: ttup := t.Extra.(*Tuple) return ttup.first.HasPointers() || ttup.second.HasPointers() + + case TRESULTS: + types := t.Extra.(*Results).Types + for _, et := range types { + if et.HasPointers() { + return true + } + } + return false } return true diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go index 7861667b88..9c9f6edc5f 100644 --- a/src/cmd/compile/internal/wasm/ssa.go +++ b/src/cmd/compile/internal/wasm/ssa.go @@ -122,7 +122,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { switch v.Op { case ssa.OpWasmLoweredStaticCall, ssa.OpWasmLoweredClosureCall, ssa.OpWasmLoweredInterCall: s.PrepareCall(v) - if v.Aux == gc.Deferreturn { + if call, ok := v.Aux.(*ssa.AuxCall); ok && call.Fn == gc.Deferreturn { // add a resume point before call to deferreturn so it can be called again via jmpdefer s.Prog(wasm.ARESUMEPOINT) } @@ -130,7 +130,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { getValue64(s, v.Args[1]) setReg(s, wasm.REG_CTXT) } - if sym, ok := v.Aux.(*obj.LSym); ok { + if call, ok := v.Aux.(*ssa.AuxCall); ok && call.Fn != nil { + sym := call.Fn p := s.Prog(obj.ACALL) p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: sym} p.Pos = v.Pos @@ -229,6 +230,12 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { } case ssa.OpWasmLoweredAddr: + if v.Aux == nil { // address of off(SP), no symbol + getValue64(s, v.Args[0]) + i64Const(s, v.AuxInt) + s.Prog(wasm.AI64Add) + break + } p := s.Prog(wasm.AGet) p.From.Type = obj.TYPE_ADDR switch v.Aux.(type) { diff --git a/src/cmd/compile/internal/x86/387.go b/src/cmd/compile/internal/x86/387.go deleted file mode 100644 index 796aa82f19..0000000000 --- a/src/cmd/compile/internal/x86/387.go +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package x86 - -import ( - "cmd/compile/internal/gc" - "cmd/compile/internal/ssa" - "cmd/compile/internal/types" - "cmd/internal/obj" - "cmd/internal/obj/x86" - "math" -) - -// Generates code for v using 387 instructions. -func ssaGenValue387(s *gc.SSAGenState, v *ssa.Value) { - // The SSA compiler pretends that it has an SSE backend. - // If we don't have one of those, we need to translate - // all the SSE ops to equivalent 387 ops. That's what this - // function does. - - switch v.Op { - case ssa.Op386MOVSSconst, ssa.Op386MOVSDconst: - iv := uint64(v.AuxInt) - if iv == 0x0000000000000000 { // +0.0 - s.Prog(x86.AFLDZ) - } else if iv == 0x3ff0000000000000 { // +1.0 - s.Prog(x86.AFLD1) - } else if iv == 0x8000000000000000 { // -0.0 - s.Prog(x86.AFLDZ) - s.Prog(x86.AFCHS) - } else if iv == 0xbff0000000000000 { // -1.0 - s.Prog(x86.AFLD1) - s.Prog(x86.AFCHS) - } else if iv == 0x400921fb54442d18 { // +pi - s.Prog(x86.AFLDPI) - } else if iv == 0xc00921fb54442d18 { // -pi - s.Prog(x86.AFLDPI) - s.Prog(x86.AFCHS) - } else { // others - p := s.Prog(loadPush(v.Type)) - p.From.Type = obj.TYPE_FCONST - p.From.Val = math.Float64frombits(iv) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - } - popAndSave(s, v) - - case ssa.Op386MOVSSconst2, ssa.Op386MOVSDconst2: - p := s.Prog(loadPush(v.Type)) - p.From.Type = obj.TYPE_MEM - p.From.Reg = v.Args[0].Reg() - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - popAndSave(s, v) - - case ssa.Op386MOVSSload, ssa.Op386MOVSDload, ssa.Op386MOVSSloadidx1, ssa.Op386MOVSDloadidx1, ssa.Op386MOVSSloadidx4, ssa.Op386MOVSDloadidx8: - p := s.Prog(loadPush(v.Type)) - p.From.Type = obj.TYPE_MEM - p.From.Reg = v.Args[0].Reg() - gc.AddAux(&p.From, v) - switch v.Op { - case ssa.Op386MOVSSloadidx1, ssa.Op386MOVSDloadidx1: - p.From.Scale = 1 - p.From.Index = v.Args[1].Reg() - if p.From.Index == x86.REG_SP { - p.From.Reg, p.From.Index = p.From.Index, p.From.Reg - } - case ssa.Op386MOVSSloadidx4: - p.From.Scale = 4 - p.From.Index = v.Args[1].Reg() - case ssa.Op386MOVSDloadidx8: - p.From.Scale = 8 - p.From.Index = v.Args[1].Reg() - } - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - popAndSave(s, v) - - case ssa.Op386MOVSSstore, ssa.Op386MOVSDstore: - // Push to-be-stored value on top of stack. - push(s, v.Args[1]) - - // Pop and store value. - var op obj.As - switch v.Op { - case ssa.Op386MOVSSstore: - op = x86.AFMOVFP - case ssa.Op386MOVSDstore: - op = x86.AFMOVDP - } - p := s.Prog(op) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_MEM - p.To.Reg = v.Args[0].Reg() - gc.AddAux(&p.To, v) - - case ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSDstoreidx1, ssa.Op386MOVSSstoreidx4, ssa.Op386MOVSDstoreidx8: - push(s, v.Args[2]) - var op obj.As - switch v.Op { - case ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSSstoreidx4: - op = x86.AFMOVFP - case ssa.Op386MOVSDstoreidx1, ssa.Op386MOVSDstoreidx8: - op = x86.AFMOVDP - } - p := s.Prog(op) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_MEM - p.To.Reg = v.Args[0].Reg() - gc.AddAux(&p.To, v) - switch v.Op { - case ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSDstoreidx1: - p.To.Scale = 1 - p.To.Index = v.Args[1].Reg() - if p.To.Index == x86.REG_SP { - p.To.Reg, p.To.Index = p.To.Index, p.To.Reg - } - case ssa.Op386MOVSSstoreidx4: - p.To.Scale = 4 - p.To.Index = v.Args[1].Reg() - case ssa.Op386MOVSDstoreidx8: - p.To.Scale = 8 - p.To.Index = v.Args[1].Reg() - } - - case ssa.Op386ADDSS, ssa.Op386ADDSD, ssa.Op386SUBSS, ssa.Op386SUBSD, - ssa.Op386MULSS, ssa.Op386MULSD, ssa.Op386DIVSS, ssa.Op386DIVSD: - if v.Reg() != v.Args[0].Reg() { - v.Fatalf("input[0] and output not in same register %s", v.LongString()) - } - - // Push arg1 on top of stack - push(s, v.Args[1]) - - // Set precision if needed. 64 bits is the default. - switch v.Op { - case ssa.Op386ADDSS, ssa.Op386SUBSS, ssa.Op386MULSS, ssa.Op386DIVSS: - p := s.Prog(x86.AFSTCW) - s.AddrScratch(&p.To) - p = s.Prog(x86.AFLDCW) - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = gc.ControlWord32 - } - - var op obj.As - switch v.Op { - case ssa.Op386ADDSS, ssa.Op386ADDSD: - op = x86.AFADDDP - case ssa.Op386SUBSS, ssa.Op386SUBSD: - op = x86.AFSUBDP - case ssa.Op386MULSS, ssa.Op386MULSD: - op = x86.AFMULDP - case ssa.Op386DIVSS, ssa.Op386DIVSD: - op = x86.AFDIVDP - } - p := s.Prog(op) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_REG - p.To.Reg = s.SSEto387[v.Reg()] + 1 - - // Restore precision if needed. - switch v.Op { - case ssa.Op386ADDSS, ssa.Op386SUBSS, ssa.Op386MULSS, ssa.Op386DIVSS: - p := s.Prog(x86.AFLDCW) - s.AddrScratch(&p.From) - } - - case ssa.Op386UCOMISS, ssa.Op386UCOMISD: - push(s, v.Args[0]) - - // Compare. - p := s.Prog(x86.AFUCOMP) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_REG - p.To.Reg = s.SSEto387[v.Args[1].Reg()] + 1 - - // Save AX. - p = s.Prog(x86.AMOVL) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_AX - s.AddrScratch(&p.To) - - // Move status word into AX. - p = s.Prog(x86.AFSTSW) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_AX - - // Then move the flags we need to the integer flags. - s.Prog(x86.ASAHF) - - // Restore AX. - p = s.Prog(x86.AMOVL) - s.AddrScratch(&p.From) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_AX - - case ssa.Op386SQRTSD: - push(s, v.Args[0]) - s.Prog(x86.AFSQRT) - popAndSave(s, v) - - case ssa.Op386FCHS: - push(s, v.Args[0]) - s.Prog(x86.AFCHS) - popAndSave(s, v) - - case ssa.Op386CVTSL2SS, ssa.Op386CVTSL2SD: - p := s.Prog(x86.AMOVL) - p.From.Type = obj.TYPE_REG - p.From.Reg = v.Args[0].Reg() - s.AddrScratch(&p.To) - p = s.Prog(x86.AFMOVL) - s.AddrScratch(&p.From) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - popAndSave(s, v) - - case ssa.Op386CVTTSD2SL, ssa.Op386CVTTSS2SL: - push(s, v.Args[0]) - - // Save control word. - p := s.Prog(x86.AFSTCW) - s.AddrScratch(&p.To) - p.To.Offset += 4 - - // Load control word which truncates (rounds towards zero). - p = s.Prog(x86.AFLDCW) - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = gc.ControlWord64trunc - - // Now do the conversion. - p = s.Prog(x86.AFMOVLP) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - s.AddrScratch(&p.To) - p = s.Prog(x86.AMOVL) - s.AddrScratch(&p.From) - p.To.Type = obj.TYPE_REG - p.To.Reg = v.Reg() - - // Restore control word. - p = s.Prog(x86.AFLDCW) - s.AddrScratch(&p.From) - p.From.Offset += 4 - - case ssa.Op386CVTSS2SD: - // float32 -> float64 is a nop - push(s, v.Args[0]) - popAndSave(s, v) - - case ssa.Op386CVTSD2SS: - // Round to nearest float32. - push(s, v.Args[0]) - p := s.Prog(x86.AFMOVFP) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - s.AddrScratch(&p.To) - p = s.Prog(x86.AFMOVF) - s.AddrScratch(&p.From) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - popAndSave(s, v) - - case ssa.OpLoadReg: - if !v.Type.IsFloat() { - ssaGenValue(s, v) - return - } - // Load+push the value we need. - p := s.Prog(loadPush(v.Type)) - gc.AddrAuto(&p.From, v.Args[0]) - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - // Move the value to its assigned register. - popAndSave(s, v) - - case ssa.OpStoreReg: - if !v.Type.IsFloat() { - ssaGenValue(s, v) - return - } - push(s, v.Args[0]) - var op obj.As - switch v.Type.Size() { - case 4: - op = x86.AFMOVFP - case 8: - op = x86.AFMOVDP - } - p := s.Prog(op) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - gc.AddrAuto(&p.To, v) - - case ssa.OpCopy: - if !v.Type.IsFloat() { - ssaGenValue(s, v) - return - } - push(s, v.Args[0]) - popAndSave(s, v) - - case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter: - flush387(s) // Calls must empty the FP stack. - fallthrough // then issue the call as normal - default: - ssaGenValue(s, v) - } -} - -// push pushes v onto the floating-point stack. v must be in a register. -func push(s *gc.SSAGenState, v *ssa.Value) { - p := s.Prog(x86.AFMOVD) - p.From.Type = obj.TYPE_REG - p.From.Reg = s.SSEto387[v.Reg()] - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 -} - -// popAndSave pops a value off of the floating-point stack and stores -// it in the register assigned to v. -func popAndSave(s *gc.SSAGenState, v *ssa.Value) { - r := v.Reg() - if _, ok := s.SSEto387[r]; ok { - // Pop value, write to correct register. - p := s.Prog(x86.AFMOVDP) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_REG - p.To.Reg = s.SSEto387[v.Reg()] + 1 - } else { - // Don't actually pop value. This 387 register is now the - // new home for the not-yet-assigned-a-home SSE register. - // Increase the register mapping of all other registers by one. - for rSSE, r387 := range s.SSEto387 { - s.SSEto387[rSSE] = r387 + 1 - } - s.SSEto387[r] = x86.REG_F0 - } -} - -// loadPush returns the opcode for load+push of the given type. -func loadPush(t *types.Type) obj.As { - if t.Size() == 4 { - return x86.AFMOVF - } - return x86.AFMOVD -} - -// flush387 removes all entries from the 387 floating-point stack. -func flush387(s *gc.SSAGenState) { - for k := range s.SSEto387 { - p := s.Prog(x86.AFMOVDP) - p.From.Type = obj.TYPE_REG - p.From.Reg = x86.REG_F0 - p.To.Type = obj.TYPE_REG - p.To.Reg = x86.REG_F0 - delete(s.SSEto387, k) - } -} - -func ssaGenBlock387(s *gc.SSAGenState, b, next *ssa.Block) { - // Empty the 387's FP stack before the block ends. - flush387(s) - - ssaGenBlock(s, b, next) -} diff --git a/src/cmd/compile/internal/x86/galign.go b/src/cmd/compile/internal/x86/galign.go index 56c6989d93..e137daa3fc 100644 --- a/src/cmd/compile/internal/x86/galign.go +++ b/src/cmd/compile/internal/x86/galign.go @@ -15,19 +15,21 @@ import ( func Init(arch *gc.Arch) { arch.LinkArch = &x86.Link386 arch.REGSP = x86.REGSP + arch.SSAGenValue = ssaGenValue + arch.SSAGenBlock = ssaGenBlock + arch.MAXWIDTH = (1 << 32) - 1 switch v := objabi.GO386; v { - case "387": - arch.Use387 = true - arch.SSAGenValue = ssaGenValue387 - arch.SSAGenBlock = ssaGenBlock387 case "sse2": - arch.SSAGenValue = ssaGenValue - arch.SSAGenBlock = ssaGenBlock + case "softfloat": + arch.SoftFloat = true + case "387": + fmt.Fprintf(os.Stderr, "unsupported setting GO386=387. Consider using GO386=softfloat instead.\n") + gc.Exit(1) default: fmt.Fprintf(os.Stderr, "unsupported setting GO386=%s\n", v) gc.Exit(1) + } - arch.MAXWIDTH = (1 << 32) - 1 arch.ZeroRange = zerorange arch.Ginsnop = ginsnop diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go index c21ac32297..fbf76d0c5e 100644 --- a/src/cmd/compile/internal/x86/ssa.go +++ b/src/cmd/compile/internal/x86/ssa.go @@ -42,10 +42,11 @@ func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) { // loadByType returns the load instruction of the given type. func loadByType(t *types.Type) obj.As { // Avoid partial register write - if !t.IsFloat() && t.Size() <= 2 { - if t.Size() == 1 { + if !t.IsFloat() { + switch t.Size() { + case 1: return x86.AMOVBLZX - } else { + case 2: return x86.AMOVWLZX } } @@ -852,8 +853,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers gc.Warnl(v.Pos, "generated nil check") } - case ssa.Op386FCHS: - v.Fatalf("FCHS in non-387 mode") case ssa.OpClobber: p := s.Prog(x86.AMOVL) p.From.Type = obj.TYPE_CONST diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go index 360f9aeb06..7ee000861b 100644 --- a/src/cmd/cover/cover.go +++ b/src/cmd/cover/cover.go @@ -12,7 +12,6 @@ import ( "go/parser" "go/token" "io" - "io/ioutil" "log" "os" "sort" @@ -304,7 +303,7 @@ func (f *File) Visit(node ast.Node) ast.Visitor { func annotate(name string) { fset := token.NewFileSet() - content, err := ioutil.ReadFile(name) + content, err := os.ReadFile(name) if err != nil { log.Fatalf("cover: %s: %s", name, err) } diff --git a/src/cmd/cover/cover_test.go b/src/cmd/cover/cover_test.go index 1c252e6e45..86c95d15c5 100644 --- a/src/cmd/cover/cover_test.go +++ b/src/cmd/cover/cover_test.go @@ -13,7 +13,6 @@ import ( "go/parser" "go/token" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -81,7 +80,7 @@ var debug = flag.Bool("debug", false, "keep rewritten files for debugging") // We use TestMain to set up a temporary directory and remove it when // the tests are done. func TestMain(m *testing.M) { - dir, err := ioutil.TempDir("", "go-testcover") + dir, err := os.MkdirTemp("", "go-testcover") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -173,7 +172,7 @@ func TestCover(t *testing.T) { buildCover(t) // Read in the test file (testTest) and write it, with LINEs specified, to coverInput. - file, err := ioutil.ReadFile(testTest) + file, err := os.ReadFile(testTest) if err != nil { t.Fatal(err) } @@ -192,7 +191,7 @@ func TestCover(t *testing.T) { []byte("}")) lines = append(lines, []byte("func unFormatted2(b bool) {if b{}else{}}")) - if err := ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil { + if err := os.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil { t.Fatal(err) } @@ -208,11 +207,11 @@ func TestCover(t *testing.T) { // Copy testmain to testTempDir, so that it is in the same directory // as coverOutput. - b, err := ioutil.ReadFile(testMain) + b, err := os.ReadFile(testMain) if err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(tmpTestMain, b, 0444); err != nil { + if err := os.WriteFile(tmpTestMain, b, 0444); err != nil { t.Fatal(err) } @@ -220,7 +219,7 @@ func TestCover(t *testing.T) { cmd = exec.Command(testenv.GoToolPath(t), "run", tmpTestMain, coverOutput) run(cmd, t) - file, err = ioutil.ReadFile(coverOutput) + file, err = os.ReadFile(coverOutput) if err != nil { t.Fatal(err) } @@ -251,7 +250,7 @@ func TestDirectives(t *testing.T) { // Read the source file and find all the directives. We'll keep // track of whether each one has been seen in the output. testDirectives := filepath.Join(testdata, "directives.go") - source, err := ioutil.ReadFile(testDirectives) + source, err := os.ReadFile(testDirectives) if err != nil { t.Fatal(err) } @@ -398,7 +397,7 @@ func TestCoverHTML(t *testing.T) { // Extract the parts of the HTML with comment markers, // and compare against a golden file. - entireHTML, err := ioutil.ReadFile(htmlHTML) + entireHTML, err := os.ReadFile(htmlHTML) if err != nil { t.Fatal(err) } @@ -420,7 +419,7 @@ func TestCoverHTML(t *testing.T) { if scan.Err() != nil { t.Error(scan.Err()) } - golden, err := ioutil.ReadFile(htmlGolden) + golden, err := os.ReadFile(htmlGolden) if err != nil { t.Fatalf("reading golden file: %v", err) } @@ -457,7 +456,7 @@ func TestHtmlUnformatted(t *testing.T) { t.Fatal(err) } - if err := ioutil.WriteFile(filepath.Join(htmlUDir, "go.mod"), []byte("module htmlunformatted\n"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(htmlUDir, "go.mod"), []byte("module htmlunformatted\n"), 0666); err != nil { t.Fatal(err) } @@ -474,10 +473,10 @@ lab: const htmlUTestContents = `package htmlunformatted` - if err := ioutil.WriteFile(htmlU, []byte(htmlUContents), 0444); err != nil { + if err := os.WriteFile(htmlU, []byte(htmlUContents), 0444); err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(htmlUTest, []byte(htmlUTestContents), 0444); err != nil { + if err := os.WriteFile(htmlUTest, []byte(htmlUTestContents), 0444); err != nil { t.Fatal(err) } @@ -540,13 +539,13 @@ func TestFuncWithDuplicateLines(t *testing.T) { t.Fatal(err) } - if err := ioutil.WriteFile(filepath.Join(lineDupDir, "go.mod"), []byte("module linedup\n"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(lineDupDir, "go.mod"), []byte("module linedup\n"), 0666); err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(lineDupGo, []byte(lineDupContents), 0444); err != nil { + if err := os.WriteFile(lineDupGo, []byte(lineDupContents), 0444); err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(lineDupTestGo, []byte(lineDupTestContents), 0444); err != nil { + if err := os.WriteFile(lineDupTestGo, []byte(lineDupTestContents), 0444); err != nil { t.Fatal(err) } diff --git a/src/cmd/cover/html.go b/src/cmd/cover/html.go index f76ea03cf5..b2865c427c 100644 --- a/src/cmd/cover/html.go +++ b/src/cmd/cover/html.go @@ -11,7 +11,6 @@ import ( "fmt" "html/template" "io" - "io/ioutil" "math" "os" "path/filepath" @@ -43,7 +42,7 @@ func htmlOutput(profile, outfile string) error { if err != nil { return err } - src, err := ioutil.ReadFile(file) + src, err := os.ReadFile(file) if err != nil { return fmt.Errorf("can't read %q: %v", fn, err) } @@ -62,7 +61,7 @@ func htmlOutput(profile, outfile string) error { var out *os.File if outfile == "" { var dir string - dir, err = ioutil.TempDir("", "cover") + dir, err = os.MkdirTemp("", "cover") if err != nil { return err } diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 397b3bb88f..c8c3212d16 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -80,6 +80,7 @@ var okgoos = []string{ "darwin", "dragonfly", "illumos", + "ios", "js", "linux", "android", @@ -143,11 +144,7 @@ func xinit() { b = os.Getenv("GO386") if b == "" { - if cansse2() { - b = "sse2" - } else { - b = "387" - } + b = "sse2" } go386 = b @@ -835,6 +832,21 @@ func runInstall(pkg string, ch chan struct{}) { asmArgs = append(asmArgs, "-D", "GOMIPS64_"+gomips64) } goasmh := pathf("%s/go_asm.h", workdir) + if IsRuntimePackagePath(pkg) { + asmArgs = append(asmArgs, "-compiling-runtime") + if os.Getenv("GOEXPERIMENT") == "regabi" { + // In order to make it easier to port runtime assembly + // to the register ABI, we introduce a macro + // indicating the experiment is enabled. + // + // Note: a similar change also appears in + // cmd/go/internal/work/gc.go. + // + // TODO(austin): Remove this once we commit to the + // register ABI (#40724). + asmArgs = append(asmArgs, "-D=GOEXPERIMENT_REGABI=1") + } + } // Collect symabis from assembly code. var symabis string @@ -970,7 +982,10 @@ func matchtag(tag string) bool { } return !matchtag(tag[1:]) } - return tag == "gc" || tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux") || (goos == "illumos" && tag == "solaris") + return tag == "gc" || tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || + (goos == "android" && tag == "linux") || + (goos == "illumos" && tag == "solaris") || + (goos == "ios" && tag == "darwin") } // shouldbuild reports whether we should build this file. @@ -984,7 +999,7 @@ func shouldbuild(file, pkg string) bool { name := filepath.Base(file) excluded := func(list []string, ok string) bool { for _, x := range list { - if x == ok || (ok == "android" && x == "linux") || (ok == "illumos" && x == "solaris") { + if x == ok || (ok == "android" && x == "linux") || (ok == "illumos" && x == "solaris") || (ok == "ios" && x == "darwin") { continue } i := strings.Index(name, x) @@ -1462,9 +1477,9 @@ func wrapperPathFor(goos, goarch string) string { if gohostos != "android" { return pathf("%s/misc/android/go_android_exec.go", goroot) } - case goos == "darwin" && goarch == "arm64": - if gohostos != "darwin" || gohostarch != "arm64" { - return pathf("%s/misc/ios/go_darwin_arm_exec.go", goroot) + case goos == "ios": + if gohostos != "ios" { + return pathf("%s/misc/ios/go_ios_exec.go", goroot) } } return "" @@ -1534,13 +1549,15 @@ var cgoEnabled = map[string]bool{ "linux/mipsle": true, "linux/mips64": true, "linux/mips64le": true, - "linux/riscv64": false, // Issue 36641 + "linux/riscv64": true, "linux/s390x": true, "linux/sparc64": true, "android/386": true, "android/amd64": true, "android/arm": true, "android/arm64": true, + "ios/arm64": true, + "ios/amd64": true, "js/wasm": false, "netbsd/386": true, "netbsd/amd64": true, @@ -1550,6 +1567,7 @@ var cgoEnabled = map[string]bool{ "openbsd/amd64": true, "openbsd/arm": true, "openbsd/arm64": true, + "openbsd/mips64": false, "plan9/386": false, "plan9/amd64": false, "plan9/arm": false, @@ -1732,3 +1750,23 @@ func cmdlist() { fatalf("write failed: %v", err) } } + +// IsRuntimePackagePath examines 'pkgpath' and returns TRUE if it +// belongs to the collection of "runtime-related" packages, including +// "runtime" itself, "reflect", "syscall", and the +// "runtime/internal/*" packages. See also the function of the same +// name in cmd/internal/objabi/path.go. +func IsRuntimePackagePath(pkgpath string) bool { + rval := false + switch pkgpath { + case "runtime": + rval = true + case "reflect": + rval = true + case "syscall": + rval = true + default: + rval = strings.HasPrefix(pkgpath, "runtime/internal") + } + return rval +} diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 79eab24d29..e7bedfb84e 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -53,6 +53,7 @@ var bootstrapDirs = []string{ "cmd/compile/internal/x86", "cmd/compile/internal/wasm", "cmd/internal/bio", + "cmd/internal/codesign", "cmd/internal/gcprog", "cmd/internal/dwarf", "cmd/internal/edit", @@ -67,6 +68,7 @@ var bootstrapDirs = []string{ "cmd/internal/obj/s390x", "cmd/internal/obj/x86", "cmd/internal/obj/wasm", + "cmd/internal/pkgpath", "cmd/internal/src", "cmd/internal/sys", "cmd/link", diff --git a/src/cmd/dist/cpuid_386.s b/src/cmd/dist/cpuid_386.s deleted file mode 100644 index 65fbb2dcb7..0000000000 --- a/src/cmd/dist/cpuid_386.s +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -TEXT ·cpuid(SB),$0-8 - MOVL ax+4(FP), AX - CPUID - MOVL info+0(FP), DI - MOVL AX, 0(DI) - MOVL BX, 4(DI) - MOVL CX, 8(DI) - MOVL DX, 12(DI) - RET - diff --git a/src/cmd/dist/cpuid_amd64.s b/src/cmd/dist/cpuid_amd64.s deleted file mode 100644 index ea0b9d4dc9..0000000000 --- a/src/cmd/dist/cpuid_amd64.s +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -TEXT ·cpuid(SB),$0-12 - MOVL ax+8(FP), AX - CPUID - MOVQ info+0(FP), DI - MOVL AX, 0(DI) - MOVL BX, 4(DI) - MOVL CX, 8(DI) - MOVL DX, 12(DI) - RET - diff --git a/src/cmd/dist/cpuid_default.s b/src/cmd/dist/cpuid_default.s deleted file mode 100644 index 6412a507a9..0000000000 --- a/src/cmd/dist/cpuid_default.s +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !386,!amd64,!gccgo - -#include "textflag.h" - -TEXT ·cpuid(SB),NOSPLIT,$0-0 - RET diff --git a/src/cmd/dist/main.go b/src/cmd/dist/main.go index b8a8c5f2e6..37de1acc31 100644 --- a/src/cmd/dist/main.go +++ b/src/cmd/dist/main.go @@ -108,6 +108,9 @@ func main() { gohostarch = "arm64" case strings.Contains(out, "arm"): gohostarch = "arm" + if gohostos == "netbsd" && strings.Contains(run("", CheckExit, "uname", "-p"), "aarch64") { + gohostarch = "arm64" + } case strings.Contains(out, "ppc64le"): gohostarch = "ppc64le" case strings.Contains(out, "ppc64"): @@ -126,10 +129,14 @@ func main() { gohostarch = "riscv64" case strings.Contains(out, "s390x"): gohostarch = "s390x" - case gohostos == "darwin": + case gohostos == "darwin", gohostos == "ios": if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM64_") { gohostarch = "arm64" } + case gohostos == "openbsd": + if strings.Contains(run("", CheckExit, "uname", "-p"), "mips64") { + gohostarch = "mips64" + } default: fatalf("unknown architecture: %s", out) } diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 5ea5c81656..955ce2a063 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -217,6 +217,9 @@ func (t *tester) run() { fmt.Println("\nFAILED") xexit(1) } else if incomplete[goos+"/"+goarch] { + // The test succeeded, but consider it as failed so we don't + // forget to remove the port from the incomplete map once the + // port is complete. fmt.Println("\nFAILED (incomplete port)") xexit(1) } else if t.partial { @@ -463,13 +466,14 @@ func (t *tester) registerTests() { }) } - // Test the ios build tag on darwin/amd64 for the iOS simulator. - if goos == "darwin" && !t.iOS() { + // Test ios/amd64 for the iOS simulator. + if goos == "darwin" && goarch == "amd64" && t.cgoEnabled { t.tests = append(t.tests, distTest{ name: "amd64ios", - heading: "ios tag on darwin/amd64", + heading: "GOOS=ios on darwin/amd64", fn: func(dt *distTest) error { - t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-tags=ios", "-run=SystemRoots", "crypto/x509") + cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-run=SystemRoots", "crypto/x509") + cmd.Env = append(os.Environ(), "GOOS=ios", "CGO_ENABLED=1") return nil }, }) @@ -903,7 +907,7 @@ func (t *tester) addCmd(dt *distTest, dir string, cmdline ...interface{}) *exec. } func (t *tester) iOS() bool { - return goos == "darwin" && goarch == "arm64" + return goos == "ios" } func (t *tester) out(v string) { @@ -921,7 +925,7 @@ func (t *tester) extLink() bool { "darwin-amd64", "darwin-arm64", "dragonfly-amd64", "freebsd-386", "freebsd-amd64", "freebsd-arm", - "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-mips64", "linux-mips64le", "linux-mips", "linux-mipsle", "linux-s390x", + "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-mips64", "linux-mips64le", "linux-mips", "linux-mipsle", "linux-riscv64", "linux-s390x", "netbsd-386", "netbsd-amd64", "openbsd-386", "openbsd-amd64", "windows-386", "windows-amd64": @@ -943,13 +947,13 @@ func (t *tester) internalLink() bool { if goos == "android" { return false } - if t.iOS() { + if goos == "ios" { return false } // Internally linking cgo is incomplete on some architectures. // https://golang.org/issue/10373 // https://golang.org/issue/14449 - if goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" { + if goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" || goarch == "riscv64" { return false } if goos == "aix" { @@ -961,10 +965,10 @@ func (t *tester) internalLink() bool { func (t *tester) internalLinkPIE() bool { switch goos + "-" + goarch { - case "linux-amd64", "linux-arm64", - "android-arm64": - return true - case "windows-amd64", "windows-386", "windows-arm": + case "darwin-amd64", "darwin-arm64", + "linux-amd64", "linux-arm64", + "android-arm64", + "windows-amd64", "windows-386", "windows-arm": return true } return false @@ -979,7 +983,7 @@ func (t *tester) supportedBuildmode(mode string) bool { } switch pair { case "aix-ppc64", - "darwin-amd64", "darwin-arm64", + "darwin-amd64", "darwin-arm64", "ios-arm64", "linux-amd64", "linux-386", "linux-ppc64le", "linux-s390x", "freebsd-amd64", "windows-amd64", "windows-386": @@ -989,7 +993,7 @@ func (t *tester) supportedBuildmode(mode string) bool { case "c-shared": switch pair { case "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-s390x", - "darwin-amd64", + "darwin-amd64", "darwin-arm64", "freebsd-amd64", "android-arm", "android-arm64", "android-386", "windows-amd64", "windows-386": @@ -1008,7 +1012,7 @@ func (t *tester) supportedBuildmode(mode string) bool { switch pair { case "linux-386", "linux-amd64", "linux-arm", "linux-s390x", "linux-ppc64le": return true - case "darwin-amd64": + case "darwin-amd64", "darwin-arm64": return true case "freebsd-amd64": return true @@ -1017,10 +1021,10 @@ func (t *tester) supportedBuildmode(mode string) bool { case "pie": switch pair { case "aix/ppc64", - "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-s390x", + "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-riscv64", "linux-s390x", "android-amd64", "android-arm", "android-arm64", "android-386": return true - case "darwin-amd64": + case "darwin-amd64", "darwin-arm64": return true case "windows-amd64", "windows-386", "windows-arm": return true @@ -1078,15 +1082,19 @@ func (t *tester) cgoTest(dt *distTest) error { cmd := t.addCmd(dt, "misc/cgo/test", t.goTest()) cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=auto") - if t.internalLink() { + // Skip internal linking cases on arm64 to support GCC-9.4 and above, + // only for linux, conservatively. + // See issue #39466. + skipInternalLink := goarch == "arm64" && goos == "linux" + + if t.internalLink() && !skipInternalLink { cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=internal") cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=internal") } pair := gohostos + "-" + goarch switch pair { - case "darwin-amd64", - "openbsd-386", "openbsd-amd64", + case "darwin-amd64", "darwin-arm64", "windows-386", "windows-amd64": // test linkmode=external, but __thread not supported, so skip testtls. if !t.extLink() { @@ -1097,12 +1105,20 @@ func (t *tester) cgoTest(dt *distTest) error { cmd = t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external -s") + if t.supportedBuildmode("pie") { + t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie") + if t.internalLink() && t.internalLinkPIE() { + t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal", "-tags=internal,internal_pie") + } + } + case "aix-ppc64", "android-arm", "android-arm64", "dragonfly-amd64", "freebsd-386", "freebsd-amd64", "freebsd-arm", - "linux-386", "linux-amd64", "linux-arm", "linux-ppc64le", "linux-s390x", - "netbsd-386", "netbsd-amd64", "linux-arm64": + "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-riscv64", "linux-s390x", + "netbsd-386", "netbsd-amd64", + "openbsd-386", "openbsd-amd64", "openbsd-arm", "openbsd-arm64", "openbsd-mips64": cmd := t.addCmd(dt, "misc/cgo/test", t.goTest()) cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=external") @@ -1147,8 +1163,8 @@ func (t *tester) cgoTest(dt *distTest) error { if t.supportedBuildmode("pie") { t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie") - if t.internalLink() && t.internalLinkPIE() { - t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal") + if t.internalLink() && t.internalLinkPIE() && !skipInternalLink { + t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal", "-tags=internal,internal_pie") } t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-buildmode=pie") t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-buildmode=pie") @@ -1428,7 +1444,6 @@ func (t *tester) testDirTest(dt *distTest, shard, shards int) error { // cgoPackages is the standard packages that use cgo. var cgoPackages = []string{ - "crypto/x509", "net", "os/user", } @@ -1494,6 +1509,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) { } gocacheSubdir, _ := filepath.Rel(dir, gocache) + // Note: Can't use WalkDir here, because this has to compile with Go 1.4. filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if suffix := strings.TrimPrefix(path, dir+string(filepath.Separator)); suffix != "" { if suffix == gocacheSubdir { @@ -1603,7 +1619,9 @@ func raceDetectorSupported(goos, goarch string) bool { switch goos { case "linux": return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" - case "darwin", "freebsd", "netbsd", "windows": + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "windows": return goarch == "amd64" default: return false diff --git a/src/cmd/dist/util_gc.go b/src/cmd/dist/util_gc.go index 698beef704..17a0e6fbb5 100644 --- a/src/cmd/dist/util_gc.go +++ b/src/cmd/dist/util_gc.go @@ -6,18 +6,6 @@ package main -func cpuid(info *[4]uint32, ax uint32) - -func cansse2() bool { - if gohostarch != "386" && gohostarch != "amd64" { - return false - } - - var info [4]uint32 - cpuid(&info, 1) - return info[3]&(1<<26) != 0 // SSE2 -} - // useVFPv1 tries to execute one VFPv1 instruction on ARM. // It will crash the current process if VFPv1 is missing. func useVFPv1() diff --git a/src/cmd/dist/util_gccgo.go b/src/cmd/dist/util_gccgo.go index f9f01dc048..dc897236fb 100644 --- a/src/cmd/dist/util_gccgo.go +++ b/src/cmd/dist/util_gccgo.go @@ -6,19 +6,6 @@ package main -/* -int supports_sse2() { -#if defined(__i386__) || defined(__x86_64__) - return __builtin_cpu_supports("sse2"); -#else - return 0; -#endif -} -*/ -import "C" - -func cansse2() bool { return C.supports_sse2() != 0 } - func useVFPv1() {} func useVFPv3() {} diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go index f13d917634..39530e3c2d 100644 --- a/src/cmd/doc/doc_test.go +++ b/src/cmd/doc/doc_test.go @@ -36,8 +36,8 @@ func TestMain(m *testing.M) { } func maybeSkip(t *testing.T) { - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { - t.Skip("darwin/arm64 does not have a full file tree") + if runtime.GOOS == "ios" { + t.Skip("iOS does not have a full file tree") } } diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go index ffc302c78c..c2e06ebc8b 100644 --- a/src/cmd/doc/pkg.go +++ b/src/cmd/doc/pkg.go @@ -16,8 +16,8 @@ import ( "go/printer" "go/token" "io" + "io/fs" "log" - "os" "path/filepath" "strings" "unicode" @@ -129,11 +129,10 @@ func (pkg *Package) Fatalf(format string, args ...interface{}) { // parsePackage turns the build package we found into a parsed package // we can then use to generate documentation. func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Package { - fs := token.NewFileSet() // include tells parser.ParseDir which files to include. // That means the file must be in the build package's GoFiles or CgoFiles // list only (no tag-ignored files, tests, swig or other non-Go files). - include := func(info os.FileInfo) bool { + include := func(info fs.FileInfo) bool { for _, name := range pkg.GoFiles { if name == info.Name() { return true @@ -146,7 +145,8 @@ func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Packag } return false } - pkgs, err := parser.ParseDir(fs, pkg.Dir, include, parser.ParseComments) + fset := token.NewFileSet() + pkgs, err := parser.ParseDir(fset, pkg.Dir, include, parser.ParseComments) if err != nil { log.Fatal(err) } @@ -203,7 +203,7 @@ func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Packag typedValue: typedValue, constructor: constructor, build: pkg, - fs: fs, + fs: fset, } p.buf.pkg = p return p diff --git a/src/cmd/fix/gotypes.go b/src/cmd/fix/gotypes.go index 8a4019cc8c..031f85c9cc 100644 --- a/src/cmd/fix/gotypes.go +++ b/src/cmd/fix/gotypes.go @@ -21,11 +21,11 @@ var gotypesFix = fix{ } func gotypes(f *ast.File) bool { - truth := fixGoTypes(f) + fixed := fixGoTypes(f) if fixGoExact(f) { - truth = true + fixed = true } - return truth + return fixed } func fixGoTypes(f *ast.File) bool { diff --git a/src/cmd/fix/main.go b/src/cmd/fix/main.go index e72c66398f..d055929aac 100644 --- a/src/cmd/fix/main.go +++ b/src/cmd/fix/main.go @@ -13,7 +13,8 @@ import ( "go/parser" "go/scanner" "go/token" - "io/ioutil" + "io" + "io/fs" "os" "path/filepath" "sort" @@ -127,7 +128,7 @@ func processFile(filename string, useStdin bool) error { defer f.Close() } - src, err := ioutil.ReadAll(f) + src, err := io.ReadAll(f) if err != nil { return err } @@ -137,6 +138,21 @@ func processFile(filename string, useStdin bool) error { return err } + // Make sure file is in canonical format. + // This "fmt" pseudo-fix cannot be disabled. + newSrc, err := gofmtFile(file) + if err != nil { + return err + } + if !bytes.Equal(newSrc, src) { + newFile, err := parser.ParseFile(fset, filename, newSrc, parserMode) + if err != nil { + return err + } + file = newFile + fmt.Fprintf(&fixlog, " fmt") + } + // Apply all fixes to file. newFile := file fixed := false @@ -180,7 +196,7 @@ func processFile(filename string, useStdin bool) error { // output of the printer run on a standard AST generated by the parser, // but the source we generated inside the loop above is the // output of the printer run on a mangled AST generated by a fixer. - newSrc, err := gofmtFile(newFile) + newSrc, err = gofmtFile(newFile) if err != nil { return err } @@ -200,7 +216,7 @@ func processFile(filename string, useStdin bool) error { return nil } - return ioutil.WriteFile(f.Name(), newSrc, 0) + return os.WriteFile(f.Name(), newSrc, 0) } func gofmt(n interface{}) string { @@ -217,10 +233,10 @@ func report(err error) { } func walkDir(path string) { - filepath.Walk(path, visitFile) + filepath.WalkDir(path, visitFile) } -func visitFile(path string, f os.FileInfo, err error) error { +func visitFile(path string, f fs.DirEntry, err error) error { if err == nil && isGoFile(f) { err = processFile(path, false) } @@ -230,7 +246,7 @@ func visitFile(path string, f os.FileInfo, err error) error { return nil } -func isGoFile(f os.FileInfo) bool { +func isGoFile(f fs.DirEntry) bool { // ignore non-Go files name := f.Name() return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") diff --git a/src/cmd/fix/typecheck.go b/src/cmd/fix/typecheck.go index 66e0cdcec0..40b2287f26 100644 --- a/src/cmd/fix/typecheck.go +++ b/src/cmd/fix/typecheck.go @@ -9,7 +9,6 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -162,12 +161,12 @@ func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, ass if err != nil { return err } - dir, err := ioutil.TempDir(os.TempDir(), "fix_cgo_typecheck") + dir, err := os.MkdirTemp(os.TempDir(), "fix_cgo_typecheck") if err != nil { return err } defer os.RemoveAll(dir) - err = ioutil.WriteFile(filepath.Join(dir, "in.go"), txt, 0600) + err = os.WriteFile(filepath.Join(dir, "in.go"), txt, 0600) if err != nil { return err } @@ -176,7 +175,7 @@ func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, ass if err != nil { return err } - out, err := ioutil.ReadFile(filepath.Join(dir, "_cgo_gotypes.go")) + out, err := os.ReadFile(filepath.Join(dir, "_cgo_gotypes.go")) if err != nil { return err } @@ -207,7 +206,7 @@ func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, ass return nil }() if err != nil { - fmt.Printf("warning: no cgo types: %s\n", err) + fmt.Fprintf(os.Stderr, "go fix: warning: no cgo types: %s\n", err) } } diff --git a/src/cmd/go.mod b/src/cmd/go.mod index 68ce1705e4..031b8d4ab7 100644 --- a/src/cmd/go.mod +++ b/src/cmd/go.mod @@ -1,14 +1,12 @@ module cmd -go 1.15 +go 1.16 require ( - github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 - github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect - golang.org/x/arch v0.0.0-20200511175325-f7c78586839d - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 - golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 - golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect - golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 - golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 // indirect + github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 + golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 + golang.org/x/mod v0.4.0 + golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect + golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 ) diff --git a/src/cmd/go.sum b/src/cmd/go.sum index cb64a5d475..2fde9445f6 100644 --- a/src/cmd/go.sum +++ b/src/cmd/go.sum @@ -1,38 +1,40 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 h1:SRgJV+IoxM5MKyFdlSUeNy6/ycRUF2yBAKdAQswoHUk= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 h1:S1+yTUaFPXuDZnPDbO+TrDFIjPzQraYH8/CwSlu9Fac= -github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/arch v0.0.0-20200511175325-f7c78586839d h1:YvwchuJby5xEAPdBGmdAVSiVME50C+RJfJJwJJsGEV8= -golang.org/x/arch v0.0.0-20200511175325-f7c78586839d/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 h1:HyOHhUtuB/Ruw/L5s5pG2D0kckkN2/IzBs9OClGHnHI= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff h1:XmKBi9R6duxOB3lfc72wyrwiOY7X2Jl1wuI+RFOyMDE= +golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= -golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 h1:9j/upNXDRpADUw2RpUfJ7E7GHtfhDih62kX6JM8vs2c= +golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 h1:Jhw4VC65LaKnpq9FvcK+a8ZzrFm3D+UygvMMrhkOw70= -golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 8ad4f66d09..c4913ce695 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -49,10 +49,11 @@ // modules modules, module versions, and more // module-get module-aware go get // module-auth module authentication using go.sum -// module-private module configuration for non-public modules // packages package lists and patterns +// private configuration for downloading non-public code // testflag testing flags // testfunc testing functions +// vcs controlling version control with GOVCS // // Use "go help <topic>" for more information about that topic. // @@ -71,7 +72,7 @@ // // Usage: // -// go build [-o output] [-i] [build flags] [packages] +// go build [-o output] [build flags] [packages] // // Build compiles the packages named by the import paths, // along with their dependencies, but it does not install the results. @@ -93,10 +94,12 @@ // // The -o flag forces build to write the resulting executable or object // to the named output file or directory, instead of the default behavior described -// in the last two paragraphs. If the named output is a directory that exists, -// then any resulting executables will be written to that directory. +// in the last two paragraphs. If the named output is an existing directory or +// ends with a slash or backslash, then any resulting executables +// will be written to that directory. // // The -i flag installs the packages that are dependencies of the target. +// The -i flag is deprecated. Compiled packages are cached automatically. // // The build flags are shared by the build, clean, get, install, list, run, // and test commands: @@ -161,6 +164,17 @@ // directory, but it is not accessed. When -modfile is specified, an // alternate go.sum file is also used: its path is derived from the // -modfile flag by trimming the ".mod" extension and appending ".sum". +// -overlay file +// read a JSON config file that provides an overlay for build operations. +// The file is a JSON struct with a single field, named 'Replace', that +// maps each disk file path (a string) to its backing file path, so that +// a build will run as if the disk file path exists with the contents +// given by the backing file paths, or as if the disk file path does not +// exist if its backing file path is empty. Support for the -overlay flag +// has some limitations:importantly, cgo files included from outside the +// include path must be in the same directory as the Go package they are +// included from, and overlays will not appear when binaries and tests are +// run through go run and go test respectively. // -pkgdir dir // install and load all packages from dir instead of the usual locations. // For example, when building with a non-standard configuration, @@ -616,15 +630,15 @@ // dependency should be removed entirely, downgrading or removing modules // depending on it as needed. // -// The version suffix @latest explicitly requests the latest minor release of the -// module named by the given path. The suffix @upgrade is like @latest but +// The version suffix @latest explicitly requests the latest minor release of +// the module named by the given path. The suffix @upgrade is like @latest but // will not downgrade a module if it is already required at a revision or // pre-release version newer than the latest released version. The suffix // @patch requests the latest patch release: the latest released version // with the same major and minor version numbers as the currently required // version. Like @upgrade, @patch will not downgrade a module already required -// at a newer version. If the path is not already required, @upgrade and @patch -// are equivalent to @latest. +// at a newer version. If the path is not already required, @upgrade is +// equivalent to @latest, and @patch is disallowed. // // Although get defaults to using the latest version of the module containing // a named package, it does not use the latest version of that module's @@ -661,14 +675,27 @@ // this automatically as well. // // The -insecure flag permits fetching from repositories and resolving -// custom domains using insecure schemes such as HTTP. Use with caution. The -// GOINSECURE environment variable is usually a better alternative, since it -// provides control over which modules may be retrieved using an insecure scheme. -// See 'go help environment' for details. +// custom domains using insecure schemes such as HTTP, and also bypassess +// module sum validation using the checksum database. Use with caution. +// This flag is deprecated and will be removed in a future version of go. +// To permit the use of insecure schemes, use the GOINSECURE environment +// variable instead. To bypass module sum validation, use GOPRIVATE or +// GONOSUMDB. See 'go help environment' for details. // // The second step is to download (if needed), build, and install // the named packages. // +// The -d flag instructs get to skip this step, downloading source code +// needed to build the named packages and their dependencies, but not +// building or installing. +// +// Building and installing packages with get is deprecated. In a future release, +// the -d flag will be enabled by default, and 'go get' will be only be used to +// adjust dependencies of the current module. To install a package using +// dependencies from the current module, use 'go install'. To install a package +// ignoring the current module, use 'go install' with an @version suffix like +// "@latest" after each argument. +// // If an argument names a module but not a package (because there is no // Go source code in the module's root directory), then the install step // is skipped for that argument, instead of causing a build failure. @@ -680,10 +707,6 @@ // adds the latest golang.org/x/perf and then installs the commands in that // latest version. // -// The -d flag instructs get to download the source code needed to build -// the named packages, including downloading necessary dependencies, -// but not to build and install them. -// // With no package arguments, 'go get' applies to Go package in the // current directory, if any. In particular, 'go get -u' and // 'go get -u=patch' update all the dependencies of that package. @@ -706,7 +729,7 @@ // // Usage: // -// go install [-i] [build flags] [packages] +// go install [build flags] [packages] // // Install compiles and installs the packages named by the import paths. // @@ -715,11 +738,39 @@ // environment variable is not set. Executables in $GOROOT // are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN. // +// If the arguments have version suffixes (like @latest or @v1.0.0), "go install" +// builds packages in module-aware mode, ignoring the go.mod file in the current +// directory or any parent directory, if there is one. This is useful for +// installing executables without affecting the dependencies of the main module. +// To eliminate ambiguity about which module versions are used in the build, the +// arguments must satisfy the following constraints: +// +// - Arguments must be package paths or package patterns (with "..." wildcards). +// They must not be standard packages (like fmt), meta-patterns (std, cmd, +// all), or relative or absolute file paths. +// - All arguments must have the same version suffix. Different queries are not +// allowed, even if they refer to the same version. +// - All arguments must refer to packages in the same module at the same version. +// - No module is considered the "main" module. If the module containing +// packages named on the command line has a go.mod file, it must not contain +// directives (replace and exclude) that would cause it to be interpreted +// differently than if it were the main module. The module must not require +// a higher version of itself. +// - Package path arguments must refer to main packages. Pattern arguments +// will only match main packages. +// +// If the arguments don't have version suffixes, "go install" may run in +// module-aware mode or GOPATH mode, depending on the GO111MODULE environment +// variable and the presence of a go.mod file. See 'go help modules' for details. +// If module-aware mode is enabled, "go install" runs in the context of the main +// module. +// // When module-aware mode is disabled, other packages are installed in the // directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled, // other packages are built and cached but not installed. // // The -i flag installs the dependencies of the named packages as well. +// The -i flag is deprecated. Compiled packages are cached automatically. // // For more about the build flags, see 'go help build'. // For more about specifying packages, see 'go help packages'. @@ -766,26 +817,28 @@ // BinaryOnly bool // binary-only package (no longer supported) // ForTest string // package is only for use in named test // Export string // file containing export data (when using -export) +// BuildID string // build ID of the compiled package (when using -export) // Module *Module // info about package's containing module, if any (can be nil) // Match []string // command-line patterns matching this package // DepOnly bool // package is only a dependency, not explicitly listed // // // Source files -// GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) -// CgoFiles []string // .go source files that import "C" -// CompiledGoFiles []string // .go files presented to compiler (when using -compiled) -// IgnoredGoFiles []string // .go source files ignored due to build constraints -// CFiles []string // .c source files -// CXXFiles []string // .cc, .cxx and .cpp source files -// MFiles []string // .m source files -// HFiles []string // .h, .hh, .hpp and .hxx source files -// FFiles []string // .f, .F, .for and .f90 Fortran source files -// SFiles []string // .s source files -// SwigFiles []string // .swig files -// SwigCXXFiles []string // .swigcxx files -// SysoFiles []string // .syso object files to add to archive -// TestGoFiles []string // _test.go files in package -// XTestGoFiles []string // _test.go files outside package +// GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) +// CgoFiles []string // .go source files that import "C" +// CompiledGoFiles []string // .go files presented to compiler (when using -compiled) +// IgnoredGoFiles []string // .go source files ignored due to build constraints +// IgnoredOtherFiles []string // non-.go source files ignored due to build constraints +// CFiles []string // .c source files +// CXXFiles []string // .cc, .cxx and .cpp source files +// MFiles []string // .m source files +// HFiles []string // .h, .hh, .hpp and .hxx source files +// FFiles []string // .f, .F, .for and .f90 Fortran source files +// SFiles []string // .s source files +// SwigFiles []string // .swig files +// SwigCXXFiles []string // .swigcxx files +// SysoFiles []string // .syso object files to add to archive +// TestGoFiles []string // _test.go files in package +// XTestGoFiles []string // _test.go files outside package // // // Cgo directives // CgoCFLAGS []string // cgo: flags for C compiler @@ -1113,7 +1166,7 @@ // // The -retract=version and -dropretract=version flags add and drop a // retraction on the given version. The version may be a single version -// like "v1.2.3" or a closed interval like "[v1.1.0-v1.1.9]". Note that +// like "v1.2.3" or a closed interval like "[v1.1.0,v1.1.9]". Note that // -retract=version is a no-op if that retraction already exists. // // The -require, -droprequire, -exclude, -dropexclude, -replace, @@ -1188,19 +1241,24 @@ // // go mod init [module] // -// Init initializes and writes a new go.mod to the current directory, -// in effect creating a new module rooted at the current directory. -// The file go.mod must not already exist. -// If possible, init will guess the module path from import comments -// (see 'go help importpath') or from version control configuration. -// To override this guess, supply the module path as an argument. +// Init initializes and writes a new go.mod file in the current directory, in +// effect creating a new module rooted at the current directory. The go.mod file +// must not already exist. +// +// Init accepts one optional argument, the module path for the new module. If the +// module path argument is omitted, init will attempt to infer the module path +// using import comments in .go files, vendoring tool configuration files (like +// Gopkg.lock), and the current directory (if in GOPATH). +// +// If a configuration file for a vendoring tool is present, init will attempt to +// import module requirements from it. // // // Add missing and remove unused modules // // Usage: // -// go mod tidy [-v] +// go mod tidy [-e] [-v] // // Tidy makes sure go.mod matches the source code in the module. // It adds any missing modules necessary to build the current module's @@ -1211,12 +1269,15 @@ // The -v flag causes tidy to print information about removed modules // to standard error. // +// The -e flag causes tidy to attempt to proceed despite errors +// encountered while loading packages. +// // // Make vendored copy of dependencies // // Usage: // -// go mod vendor [-v] +// go mod vendor [-e] [-v] // // Vendor resets the main module's vendor directory to include all packages // needed to build and test all the main module's packages. @@ -1225,6 +1286,9 @@ // The -v flag causes vendor to print the names of vendored // modules and packages to standard error. // +// The -e flag causes vendor to attempt to proceed despite errors +// encountered while loading packages. +// // // Verify dependencies have expected content // @@ -1413,6 +1477,7 @@ // -i // Install packages that are dependencies of the test. // Do not run the test. +// The -i flag is deprecated. Compiled packages are cached automatically. // // -json // Convert test output to JSON suitable for automated processing. @@ -1571,6 +1636,9 @@ // Using GOOS=illumos matches build tags and files as for GOOS=solaris // in addition to illumos tags and files. // +// Using GOOS=ios matches build tags and files as for GOOS=darwin +// in addition to ios tags and files. +// // To keep a file from being considered for the build: // // // +build ignore @@ -1758,7 +1826,7 @@ // Comma-separated list of glob patterns (in the syntax of Go's path.Match) // of module path prefixes that should always be fetched directly // or that should not be compared against the checksum database. -// See 'go help module-private'. +// See 'go help private'. // GOROOT // The root of the go tree. // GOSUMDB @@ -1814,8 +1882,8 @@ // For GOARCH=arm, the ARM architecture for which to compile. // Valid values are 5, 6, 7. // GO386 -// For GOARCH=386, the floating point instruction set. -// Valid values are 387, sse2. +// For GOARCH=386, how to implement floating point instructions. +// Valid values are sse2 (default), softfloat. // GOMIPS // For GOARCH=mips{,le}, whether to use floating point instructions. // Valid values are hardfloat (default), softfloat. @@ -1864,6 +1932,8 @@ // If module-aware mode is disabled, GOMOD will be the empty string. // GOTOOLDIR // The directory where the go tools (compile, cover, doc, etc...) are installed. +// GOVERSION +// The version of the installed Go tree, as reported by runtime.Version. // // // File types @@ -1935,7 +2005,7 @@ // like in Go imports: // // require ( -// new/thing v2.3.4 +// new/thing/v2 v2.3.4 // old/thing v1.2.3 // ) // @@ -2172,10 +2242,11 @@ // before resolving dependencies or building the code. // // The -insecure flag permits fetching from repositories and resolving -// custom domains using insecure schemes such as HTTP. Use with caution. The -// GOINSECURE environment variable is usually a better alternative, since it -// provides control over which modules may be retrieved using an insecure scheme. -// See 'go help environment' for details. +// custom domains using insecure schemes such as HTTP. Use with caution. +// This flag is deprecated and will be removed in a future version of go. +// The GOINSECURE environment variable should be used instead, since it +// provides control over which packages may be retrieved using an insecure +// scheme. See 'go help environment' for details. // // The -t flag instructs get to also download the packages required to build // the tests for the specified packages. @@ -2586,72 +2657,63 @@ // // Maintaining module requirements // -// The go.mod file is meant to be readable and editable by both -// programmers and tools. The go command itself automatically updates the go.mod file -// to maintain a standard formatting and the accuracy of require statements. +// The go.mod file is meant to be readable and editable by both programmers and +// tools. Most updates to dependencies can be performed using "go get" and +// "go mod tidy". Other module-aware build commands may be invoked using the +// -mod=mod flag to automatically add missing requirements and fix inconsistencies. // -// Any go command that finds an unfamiliar import will look up the module -// containing that import and add the latest version of that module -// to go.mod automatically. In most cases, therefore, it suffices to -// add an import to source code and run 'go build', 'go test', or even 'go list': -// as part of analyzing the package, the go command will discover -// and resolve the import and update the go.mod file. +// The "go get" command updates go.mod to change the module versions used in a +// build. An upgrade of one module may imply upgrading others, and similarly a +// downgrade of one module may imply downgrading others. The "go get" command +// makes these implied changes as well. See "go help module-get". // -// Any go command can determine that a module requirement is -// missing and must be added, even when considering only a single -// package from the module. On the other hand, determining that a module requirement -// is no longer necessary and can be deleted requires a full view of -// all packages in the module, across all possible build configurations -// (architectures, operating systems, build tags, and so on). -// The 'go mod tidy' command builds that view and then -// adds any missing module requirements and removes unnecessary ones. +// The "go mod" command provides other functionality for use in maintaining +// and understanding modules and go.mod files. See "go help mod", particularly +// "go help mod tidy" and "go help mod edit". // // As part of maintaining the require statements in go.mod, the go command // tracks which ones provide packages imported directly by the current module // and which ones provide packages only used indirectly by other module // dependencies. Requirements needed only for indirect uses are marked with a -// "// indirect" comment in the go.mod file. Indirect requirements are +// "// indirect" comment in the go.mod file. Indirect requirements may be // automatically removed from the go.mod file once they are implied by other // direct requirements. Indirect requirements only arise when using modules // that fail to state some of their own dependencies or when explicitly // upgrading a module's dependencies ahead of its own stated requirements. // -// Because of this automatic maintenance, the information in go.mod is an -// up-to-date, readable description of the build. +// The -mod build flag provides additional control over the updating and use of +// go.mod for commands that build packages like "go build" and "go test". // -// The 'go get' command updates go.mod to change the module versions used in a -// build. An upgrade of one module may imply upgrading others, and similarly a -// downgrade of one module may imply downgrading others. The 'go get' command -// makes these implied changes as well. If go.mod is edited directly, commands -// like 'go build' or 'go list' will assume that an upgrade is intended and -// automatically make any implied upgrades and update go.mod to reflect them. -// -// The 'go mod' command provides other functionality for use in maintaining -// and understanding modules and go.mod files. See 'go help mod'. +// If invoked with -mod=readonly (the default in most situations), the go command +// reports an error if a package named on the command line or an imported package +// is not provided by any module in the build list computed from the main module's +// requirements. The go command also reports an error if a module's checksum is +// missing from go.sum (see Module downloading and verification). Either go.mod or +// go.sum must be updated in these situations. // -// The -mod build flag provides additional control over updating and use of go.mod. -// -// If invoked with -mod=readonly, the go command is disallowed from the implicit -// automatic updating of go.mod described above. Instead, it fails when any changes -// to go.mod are needed. This setting is most useful to check that go.mod does -// not need updates, such as in a continuous integration and testing system. -// The "go get" command remains permitted to update go.mod even with -mod=readonly, -// and the "go mod" commands do not take the -mod flag (or any other build flags). +// If invoked with -mod=mod, the go command automatically updates go.mod and +// go.sum, fixing inconsistencies and adding missing requirements and checksums +// as needed. If the go command finds an unfamiliar import, it looks up the +// module containing that import and adds a requirement for the latest version +// of that module to go.mod. In most cases, therefore, one may add an import to +// source code and run "go build", "go test", or even "go list" with -mod=mod: +// as part of analyzing the package, the go command will resolve the import and +// update the go.mod file. // // If invoked with -mod=vendor, the go command loads packages from the main // module's vendor directory instead of downloading modules to and loading packages // from the module cache. The go command assumes the vendor directory holds // correct copies of dependencies, and it does not compute the set of required // module versions from go.mod files. However, the go command does check that -// vendor/modules.txt (generated by 'go mod vendor') contains metadata consistent +// vendor/modules.txt (generated by "go mod vendor") contains metadata consistent // with go.mod. // -// If invoked with -mod=mod, the go command loads modules from the module cache -// even if there is a vendor directory present. +// If the go command is not invoked with a -mod flag, and the vendor directory +// is present, and the "go" version in go.mod is 1.14 or higher, the go command +// will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag +// defaults to -mod=readonly. // -// If the go command is not invoked with a -mod flag and the vendor directory -// is present and the "go" version in go.mod is 1.14 or higher, the go command -// will act as if it were invoked with -mod=vendor. +// Note that neither "go get" nor the "go mod" subcommands accept the -mod flag. // // Pseudo-versions // @@ -2836,7 +2898,7 @@ // followed by a pipe character, indicating it is safe to fall back on any error. // // The GOPRIVATE and GONOPROXY environment variables allow bypassing -// the proxy for selected modules. See 'go help module-private' for details. +// the proxy for selected modules. See 'go help private' for details. // // No matter the source of the modules, the go command checks downloads against // known checksums, to detect unexpected changes in the content of any specific @@ -2956,52 +3018,7 @@ // accepted, at the cost of giving up the security guarantee of verified repeatable // downloads for all modules. A better way to bypass the checksum database // for specific modules is to use the GOPRIVATE or GONOSUMDB environment -// variables. See 'go help module-private' for details. -// -// The 'go env -w' command (see 'go help env') can be used to set these variables -// for future go command invocations. -// -// -// Module configuration for non-public modules -// -// The go command defaults to downloading modules from the public Go module -// mirror at proxy.golang.org. It also defaults to validating downloaded modules, -// regardless of source, against the public Go checksum database at sum.golang.org. -// These defaults work well for publicly available source code. -// -// The GOPRIVATE environment variable controls which modules the go command -// considers to be private (not available publicly) and should therefore not use the -// proxy or checksum database. The variable is a comma-separated list of -// glob patterns (in the syntax of Go's path.Match) of module path prefixes. -// For example, -// -// GOPRIVATE=*.corp.example.com,rsc.io/private -// -// causes the go command to treat as private any module with a path prefix -// matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private, -// and rsc.io/private/quux. -// -// The GOPRIVATE environment variable may be used by other tools as well to -// identify non-public modules. For example, an editor could use GOPRIVATE -// to decide whether to hyperlink a package import to a godoc.org page. -// -// For fine-grained control over module download and validation, the GONOPROXY -// and GONOSUMDB environment variables accept the same kind of glob list -// and override GOPRIVATE for the specific decision of whether to use the proxy -// and checksum database, respectively. -// -// For example, if a company ran a module proxy serving private modules, -// users would configure go using: -// -// GOPRIVATE=*.corp.example.com -// GOPROXY=proxy.example.com -// GONOPROXY=none -// -// This would tell the go command and other tools that modules beginning with -// a corp.example.com subdomain are private but that the company proxy should -// be used for downloading both public and private modules, because -// GONOPROXY has been set to a pattern that won't match any modules, -// overriding GOPRIVATE. +// variables. See 'go help private' for details. // // The 'go env -w' command (see 'go help env') can be used to set these variables // for future go command invocations. @@ -3091,6 +3108,56 @@ // by the go tool, as are directories named "testdata". // // +// Configuration for downloading non-public code +// +// The go command defaults to downloading modules from the public Go module +// mirror at proxy.golang.org. It also defaults to validating downloaded modules, +// regardless of source, against the public Go checksum database at sum.golang.org. +// These defaults work well for publicly available source code. +// +// The GOPRIVATE environment variable controls which modules the go command +// considers to be private (not available publicly) and should therefore not use the +// proxy or checksum database. The variable is a comma-separated list of +// glob patterns (in the syntax of Go's path.Match) of module path prefixes. +// For example, +// +// GOPRIVATE=*.corp.example.com,rsc.io/private +// +// causes the go command to treat as private any module with a path prefix +// matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private, +// and rsc.io/private/quux. +// +// The GOPRIVATE environment variable may be used by other tools as well to +// identify non-public modules. For example, an editor could use GOPRIVATE +// to decide whether to hyperlink a package import to a godoc.org page. +// +// For fine-grained control over module download and validation, the GONOPROXY +// and GONOSUMDB environment variables accept the same kind of glob list +// and override GOPRIVATE for the specific decision of whether to use the proxy +// and checksum database, respectively. +// +// For example, if a company ran a module proxy serving private modules, +// users would configure go using: +// +// GOPRIVATE=*.corp.example.com +// GOPROXY=proxy.example.com +// GONOPROXY=none +// +// This would tell the go command and other tools that modules beginning with +// a corp.example.com subdomain are private but that the company proxy should +// be used for downloading both public and private modules, because +// GONOPROXY has been set to a pattern that won't match any modules, +// overriding GOPRIVATE. +// +// The GOPRIVATE variable is also used to define the "public" and "private" +// patterns for the GOVCS variable; see 'go help vcs'. For that usage, +// GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths +// instead of module paths. +// +// The 'go env -w' command (see 'go help env') can be used to set these variables +// for future go command invocations. +// +// // Testing flags // // The 'go test' command takes both flags that apply to 'go test' itself @@ -3383,4 +3450,77 @@ // See the documentation of the testing package for more information. // // +// Controlling version control with GOVCS +// +// The 'go get' command can run version control commands like git +// to download imported code. This functionality is critical to the decentralized +// Go package ecosystem, in which code can be imported from any server, +// but it is also a potential security problem, if a malicious server finds a +// way to cause the invoked version control command to run unintended code. +// +// To balance the functionality and security concerns, the 'go get' command +// by default will only use git and hg to download code from public servers. +// But it will use any known version control system (bzr, fossil, git, hg, svn) +// to download code from private servers, defined as those hosting packages +// matching the GOPRIVATE variable (see 'go help private'). The rationale behind +// allowing only Git and Mercurial is that these two systems have had the most +// attention to issues of being run as clients of untrusted servers. In contrast, +// Bazaar, Fossil, and Subversion have primarily been used in trusted, +// authenticated environments and are not as well scrutinized as attack surfaces. +// +// The version control command restrictions only apply when using direct version +// control access to download code. When downloading modules from a proxy, +// 'go get' uses the proxy protocol instead, which is always permitted. +// By default, the 'go get' command uses the Go module mirror (proxy.golang.org) +// for public packages and only falls back to version control for private +// packages or when the mirror refuses to serve a public package (typically for +// legal reasons). Therefore, clients can still access public code served from +// Bazaar, Fossil, or Subversion repositories by default, because those downloads +// use the Go module mirror, which takes on the security risk of running the +// version control commands, using a custom sandbox. +// +// The GOVCS variable can be used to change the allowed version control systems +// for specific packages (identified by a module or import path). +// The GOVCS variable applies both when using modules and when using GOPATH. +// When using modules, the patterns match against the module path. +// When using GOPATH, the patterns match against the import path +// corresponding to the root of the version control repository. +// +// The general form of the GOVCS setting is a comma-separated list of +// pattern:vcslist rules. The pattern is a glob pattern that must match +// one or more leading elements of the module or import path. The vcslist +// is a pipe-separated list of allowed version control commands, or "all" +// to allow use of any known command, or "off" to allow nothing. +// The earliest matching pattern in the list applies, even if later patterns +// might also match. +// +// For example, consider: +// +// GOVCS=github.com:git,evil.com:off,*:git|hg +// +// With this setting, code with an module or import path beginning with +// github.com/ can only use git; paths on evil.com cannot use any version +// control command, and all other paths (* matches everything) can use +// only git or hg. +// +// The special patterns "public" and "private" match public and private +// module or import paths. A path is private if it matches the GOPRIVATE +// variable; otherwise it is public. +// +// If no rules in the GOVCS variable match a particular module or import path, +// the 'go get' command applies its default rule, which can now be summarized +// in GOVCS notation as 'public:git|hg,private:all'. +// +// To allow unfettered use of any version control system for any package, use: +// +// GOVCS=*:all +// +// To disable all use of version control, use: +// +// GOVCS=*:off +// +// The 'go env -w' command (see 'go help env') can be used to set the GOVCS +// variable for future go command invocations. +// +// package main diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 021930a8a8..c472620db2 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -9,13 +9,14 @@ import ( "debug/elf" "debug/macho" "debug/pe" + "encoding/binary" "flag" "fmt" "go/format" "internal/race" "internal/testenv" "io" - "io/ioutil" + "io/fs" "log" "os" "os/exec" @@ -30,77 +31,42 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/robustio" + "cmd/go/internal/work" "cmd/internal/sys" ) +func init() { + // GOVCS defaults to public:git|hg,private:all, + // which breaks many tests here - they can't use non-git, non-hg VCS at all! + // Change to fully permissive. + // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt. + os.Setenv("GOVCS", "*:all") +} + var ( - canRun = true // whether we can run go or ./testgo canRace = false // whether we can run the race detector canCgo = false // whether we can use cgo canMSan = false // whether we can run the memory sanitizer - - exeSuffix string // ".exe" on Windows - - skipExternal = false // skip external tests ) +var exeSuffix string = func() string { + if runtime.GOOS == "windows" { + return ".exe" + } + return "" +}() + func tooSlow(t *testing.T) { if testing.Short() { // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders. if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") { return } + t.Helper() t.Skip("skipping test in -short mode") } } -func init() { - switch runtime.GOOS { - case "android", "js": - canRun = false - case "darwin": - switch runtime.GOARCH { - case "arm64": - canRun = false - } - case "linux": - switch runtime.GOARCH { - case "arm": - // many linux/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - case "mips", "mipsle", "mips64", "mips64le": - // Also slow. - skipExternal = true - if testenv.Builder() != "" { - // On the builders, skip the cmd/go - // tests. They're too slow and already - // covered by other ports. There's - // nothing os/arch specific in the - // tests. - canRun = false - } - } - case "freebsd": - switch runtime.GOARCH { - case "arm": - // many freebsd/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - canRun = false - } - case "plan9": - switch runtime.GOARCH { - case "arm": - // many plan9/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - } - case "windows": - exeSuffix = ".exe" - } -} - // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary // build from this process's current GOROOT, but run from a different // (temp) directory. @@ -134,7 +100,7 @@ func TestMain(m *testing.M) { // Run with a temporary TMPDIR to check that the tests don't // leave anything behind. - topTmpdir, err := ioutil.TempDir("", "cmd-go-test-") + topTmpdir, err := os.MkdirTemp("", "cmd-go-test-") if err != nil { log.Fatal(err) } @@ -143,7 +109,7 @@ func TestMain(m *testing.M) { } os.Setenv(tempEnvName(), topTmpdir) - dir, err := ioutil.TempDir(topTmpdir, "tmpdir") + dir, err := os.MkdirTemp(topTmpdir, "tmpdir") if err != nil { log.Fatal(err) } @@ -153,7 +119,7 @@ func TestMain(m *testing.M) { } testGOCACHE = cache.DefaultDir() - if canRun { + if testenv.HasGoBuild() { testBin = filepath.Join(testTmpDir, "testbin") if err := os.Mkdir(testBin, 0777); err != nil { log.Fatal(err) @@ -224,7 +190,7 @@ func TestMain(m *testing.M) { cmd.Stderr = new(strings.Builder) if out, err := cmd.Output(); err != nil { fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr) - canRun = false + os.Exit(2) } else { canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out))) if err != nil { @@ -324,10 +290,7 @@ func skipIfGccgo(t *testing.T, msg string) { func testgo(t *testing.T) *testgoData { t.Helper() testenv.MustHaveGoBuild(t) - - if skipExternal { - t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) - } + testenv.SkipIfShortAndSlow(t) return &testgoData{t: t} } @@ -416,9 +379,6 @@ func (tg *testgoData) goTool() string { // returning exit status. func (tg *testgoData) doRun(args []string) error { tg.t.Helper() - if !canRun { - panic("testgoData.doRun called but canRun false") - } if tg.inParallel { for _, arg := range args { if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") { @@ -656,7 +616,7 @@ func (tg *testgoData) makeTempdir() { tg.t.Helper() if tg.tempdir == "" { var err error - tg.tempdir, err = ioutil.TempDir("", "gotest") + tg.tempdir, err = os.MkdirTemp("", "gotest") tg.must(err) } } @@ -673,7 +633,7 @@ func (tg *testgoData) tempFile(path, contents string) { bytes = formatted } } - tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) + tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) } // tempDir adds a temporary directory for a run of testgo. @@ -814,7 +774,7 @@ func (tg *testgoData) cleanup() { func removeAll(dir string) error { // module cache has 0444 directories; // make them writable in order to remove content. - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { // chmod not only directories, but also things that we couldn't even stat // due to permission errors: they may also be unreadable directories. if err != nil || info.IsDir() { @@ -860,8 +820,8 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { } { srcdir := filepath.Join(testGOROOT, copydir) tg.tempDir(filepath.Join("goroot", copydir)) - err := filepath.Walk(srcdir, - func(path string, info os.FileInfo, err error) error { + err := filepath.WalkDir(srcdir, + func(path string, info fs.DirEntry, err error) error { if err != nil { return err } @@ -873,13 +833,13 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { return err } dest := filepath.Join("goroot", copydir, srcrel) - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return err } tg.tempFile(dest, string(data)) - if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil { - return err + if strings.Contains(copydir, filepath.Join("pkg", "tool")) { + os.Chmod(tg.path(dest), 0777) } return nil }) @@ -890,18 +850,18 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { tg.setenv("GOROOT", tg.path("goroot")) addVar := func(name string, idx int) (restore func()) { - data, err := ioutil.ReadFile(name) + data, err := os.ReadFile(name) if err != nil { t.Fatal(err) } old := data data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...) - if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil { + if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil { t.Fatal(err) } tg.sleep() return func() { - if err := ioutil.WriteFile(name, old, 0666); err != nil { + if err := os.WriteFile(name, old, 0666); err != nil { t.Fatal(err) } } @@ -1237,6 +1197,18 @@ func TestGoListExport(t *testing.T) { if _, err := os.Stat(file); err != nil { t.Fatalf("cannot find .Export result %s: %v", file, err) } + + tg.run("list", "-export", "-f", "{{.BuildID}}", "strings") + buildID := strings.TrimSpace(tg.stdout.String()) + if buildID == "" { + t.Fatalf(".BuildID with -export was empty") + } + + tg.run("tool", "buildid", file) + toolBuildID := strings.TrimSpace(tg.stdout.String()) + if buildID != toolBuildID { + t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID) + } } // Issue 4096. Validate the output of unsuccessful go install foo/quxx. @@ -1394,6 +1366,30 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`) } +func TestLdFlagsLongArgumentsIssue42295(t *testing.T) { + // Test the extremely long command line arguments that contain '\n' characters + // get encoded and passed correctly. + skipIfGccgo(t, "gccgo does not support -ldflags -X") + tooSlow(t) + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.tempFile("main.go", `package main + var extern string + func main() { + print(extern) + }`) + testStr := "test test test test test \n\\ " + var buf bytes.Buffer + for buf.Len() < work.ArgLengthForResponseFile+1 { + buf.WriteString(testStr) + } + tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go")) + if tg.stderr.String() != buf.String() { + t.Errorf("strings differ") + } +} + func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { skipIfGccgo(t, "gccgo has no standard packages") tooSlow(t) @@ -1914,6 +1910,18 @@ func TestGoEnv(t *testing.T) { tg.grepStdout("gcc", "CC not found") tg.run("env", "GOGCCFLAGS") tg.grepStdout("-ffaster", "CC arguments not found") + + tg.run("env", "GOVERSION") + envVersion := strings.TrimSpace(tg.stdout.String()) + + tg.run("version") + cmdVersion := strings.TrimSpace(tg.stdout.String()) + + // If 'go version' is "go version <version> <goos>/<goarch>", then + // 'go env GOVERSION' is just "<version>". + if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) { + t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion) + } } const ( @@ -2019,7 +2027,7 @@ func main() { tg.run("build", "-o", exe, "p") } -func copyFile(src, dst string, perm os.FileMode) error { +func copyFile(src, dst string, perm fs.FileMode) error { sf, err := os.Open(src) if err != nil { return err @@ -2058,7 +2066,7 @@ func TestBuildmodePIE(t *testing.T) { platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", "windows/386", "windows/amd64", "windows/arm": @@ -2166,6 +2174,38 @@ func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) { if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 { t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set") } + if useCgo { + // Test that only one symbol is exported (#40795). + // PIE binaries don´t require .edata section but unfortunately + // binutils doesn´t generate a .reloc section unless there is + // at least one symbol exported. + // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011 + section := f.Section(".edata") + if section == nil { + t.Fatalf(".edata section is not present") + } + // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go + type IMAGE_EXPORT_DIRECTORY struct { + _ [2]uint32 + _ [2]uint16 + _ [2]uint32 + NumberOfFunctions uint32 + NumberOfNames uint32 + _ [3]uint32 + } + var e IMAGE_EXPORT_DIRECTORY + if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil { + t.Fatalf("binary.Read failed: %v", err) + } + + // Only _cgo_dummy_export should be exported + if e.NumberOfFunctions != 1 { + t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions) + } + if e.NumberOfNames != 1 { + t.Fatalf("got %d exported names; want 1", e.NumberOfNames) + } + } default: panic("unreachable") } @@ -2658,7 +2698,7 @@ echo $* >>`+tg.path("pkg-config.out")) tg.setenv("GOPATH", tg.path(".")) tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh")) tg.run("build", "x") - out, err := ioutil.ReadFile(tg.path("pkg-config.out")) + out, err := os.ReadFile(tg.path("pkg-config.out")) tg.must(err) out = bytes.TrimSpace(out) want := "--cflags --static --static -- a a\n--libs --static --static -- a a" diff --git a/src/cmd/go/go_windows_test.go b/src/cmd/go/go_windows_test.go index 3999166ed9..3094212bae 100644 --- a/src/cmd/go/go_windows_test.go +++ b/src/cmd/go/go_windows_test.go @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package main_test import ( - "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -17,16 +15,18 @@ import ( ) func TestAbsolutePath(t *testing.T) { - t.Parallel() + tg := testgo(t) + defer tg.cleanup() + tg.parallel() - tmp, err := ioutil.TempDir("", "TestAbsolutePath") + tmp, err := os.MkdirTemp("", "TestAbsolutePath") if err != nil { t.Fatal(err) } defer robustio.RemoveAll(tmp) file := filepath.Join(tmp, "a.go") - err = ioutil.WriteFile(file, []byte{}, 0644) + err = os.WriteFile(file, []byte{}, 0644) if err != nil { t.Fatal(err) } @@ -38,7 +38,7 @@ func TestAbsolutePath(t *testing.T) { noVolume := file[len(filepath.VolumeName(file)):] wrongPath := filepath.Join(dir, noVolume) - cmd := exec.Command(testenv.GoToolPath(t), "build", noVolume) + cmd := exec.Command(tg.goTool(), "build", noVolume) cmd.Dir = dir output, err := cmd.CombinedOutput() if err == nil { diff --git a/src/cmd/go/help_test.go b/src/cmd/go/help_test.go index 78d63ff05e..abfc3db993 100644 --- a/src/cmd/go/help_test.go +++ b/src/cmd/go/help_test.go @@ -6,7 +6,7 @@ package main_test import ( "bytes" - "io/ioutil" + "os" "testing" "cmd/go/internal/help" @@ -23,7 +23,7 @@ func TestDocsUpToDate(t *testing.T) { buf := new(bytes.Buffer) // Match the command in mkalldocs.sh that generates alldocs.go. help.Help(buf, []string{"documentation"}) - data, err := ioutil.ReadFile("alldocs.go") + data, err := os.ReadFile("alldocs.go") if err != nil { t.Fatalf("error reading alldocs.go: %v", err) } diff --git a/src/cmd/go/init_test.go b/src/cmd/go/init_test.go index ed90a77841..5a5cbe5293 100644 --- a/src/cmd/go/init_test.go +++ b/src/cmd/go/init_test.go @@ -7,6 +7,7 @@ package main_test import ( "internal/testenv" "os/exec" + "sync/atomic" "testing" ) @@ -15,20 +16,27 @@ import ( // the benchmark if any changes were done. func BenchmarkExecGoEnv(b *testing.B) { testenv.MustHaveExec(b) - b.StopTimer() gotool, err := testenv.GoTool() if err != nil { b.Fatal(err) } - for i := 0; i < b.N; i++ { - cmd := exec.Command(gotool, "env", "GOARCH") - b.StartTimer() - err := cmd.Run() - b.StopTimer() + // We collect extra metrics. + var n, userTime, systemTime int64 - if err != nil { - b.Fatal(err) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + cmd := exec.Command(gotool, "env", "GOARCH") + + if err := cmd.Run(); err != nil { + b.Fatal(err) + } + atomic.AddInt64(&n, 1) + atomic.AddInt64(&userTime, int64(cmd.ProcessState.UserTime())) + atomic.AddInt64(&systemTime, int64(cmd.ProcessState.SystemTime())) } - } + }) + b.ReportMetric(float64(userTime)/float64(n), "user-ns/op") + b.ReportMetric(float64(systemTime)/float64(n), "sys-ns/op") } diff --git a/src/cmd/go/internal/auth/netrc.go b/src/cmd/go/internal/auth/netrc.go index 7a9bdbb72c..0107f20d7a 100644 --- a/src/cmd/go/internal/auth/netrc.go +++ b/src/cmd/go/internal/auth/netrc.go @@ -5,7 +5,6 @@ package auth import ( - "io/ioutil" "os" "path/filepath" "runtime" @@ -99,7 +98,7 @@ func readNetrc() { return } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { if !os.IsNotExist(err) { netrcErr = err diff --git a/src/cmd/go/internal/base/base.go b/src/cmd/go/internal/base/base.go index db3ebef933..004588c732 100644 --- a/src/cmd/go/internal/base/base.go +++ b/src/cmd/go/internal/base/base.go @@ -56,6 +56,20 @@ var Go = &Command{ // Commands initialized in package main } +// hasFlag reports whether a command or any of its subcommands contain the given +// flag. +func hasFlag(c *Command, name string) bool { + if f := c.Flag.Lookup(name); f != nil { + return true + } + for _, sub := range c.Commands { + if hasFlag(sub, name) { + return true + } + } + return false +} + // LongName returns the command's long name: all the words in the usage line between "go" and a flag or argument, func (c *Command) LongName() string { name := c.UsageLine diff --git a/src/cmd/go/internal/base/flag.go b/src/cmd/go/internal/base/flag.go index 6727196816..677f819682 100644 --- a/src/cmd/go/internal/base/flag.go +++ b/src/cmd/go/internal/base/flag.go @@ -8,6 +8,7 @@ import ( "flag" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/str" ) @@ -28,13 +29,43 @@ func (v *StringsFlag) String() string { return "<StringsFlag>" } +// explicitStringFlag is like a regular string flag, but it also tracks whether +// the string was set explicitly to a non-empty value. +type explicitStringFlag struct { + value *string + explicit *bool +} + +func (f explicitStringFlag) String() string { + if f.value == nil { + return "" + } + return *f.value +} + +func (f explicitStringFlag) Set(v string) error { + *f.value = v + if v != "" { + *f.explicit = true + } + return nil +} + // AddBuildFlagsNX adds the -n and -x build flags to the flag set. func AddBuildFlagsNX(flags *flag.FlagSet) { flags.BoolVar(&cfg.BuildN, "n", false, "") flags.BoolVar(&cfg.BuildX, "x", false, "") } -// AddLoadFlags adds the -mod build flag to the flag set. -func AddLoadFlags(flags *flag.FlagSet) { - flags.StringVar(&cfg.BuildMod, "mod", "", "") +// AddModFlag adds the -mod build flag to the flag set. +func AddModFlag(flags *flag.FlagSet) { + flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "") +} + +// AddModCommonFlags adds the module-related flags common to build commands +// and 'go mod' subcommands. +func AddModCommonFlags(flags *flag.FlagSet) { + flags.BoolVar(&cfg.ModCacheRW, "modcacherw", false, "") + flags.StringVar(&cfg.ModFile, "modfile", "", "") + flags.StringVar(&fsys.OverlayFile, "overlay", "", "") } diff --git a/src/cmd/go/internal/base/goflags.go b/src/cmd/go/internal/base/goflags.go index 34766134b0..267006be7a 100644 --- a/src/cmd/go/internal/base/goflags.go +++ b/src/cmd/go/internal/base/goflags.go @@ -13,15 +13,7 @@ import ( "cmd/go/internal/cfg" ) -var ( - goflags []string // cached $GOFLAGS list; can be -x or --x form - knownFlag = make(map[string]bool) // flags allowed to appear in $GOFLAGS; no leading dashes -) - -// AddKnownFlag adds name to the list of known flags for use in $GOFLAGS. -func AddKnownFlag(name string) { - knownFlag[name] = true -} +var goflags []string // cached $GOFLAGS list; can be -x or --x form // GOFLAGS returns the flags from $GOFLAGS. // The list can be assumed to contain one string per flag, @@ -38,22 +30,12 @@ func InitGOFLAGS() { return } - // Build list of all flags for all commands. - // If no command has that flag, then we report the problem. - // This catches typos while still letting users record flags in GOFLAGS - // that only apply to a subset of go commands. - // Commands using CustomFlags can report their flag names - // by calling AddKnownFlag instead. - var walkFlags func(*Command) - walkFlags = func(cmd *Command) { - for _, sub := range cmd.Commands { - walkFlags(sub) - } - cmd.Flag.VisitAll(func(f *flag.Flag) { - knownFlag[f.Name] = true - }) + goflags = strings.Fields(cfg.Getenv("GOFLAGS")) + if len(goflags) == 0 { + // nothing to do; avoid work on later InitGOFLAGS call + goflags = []string{} + return } - walkFlags(Go) // Ignore bad flag in go env and go bug, because // they are what people reach for when debugging @@ -61,11 +43,6 @@ func InitGOFLAGS() { // (Both will show the GOFLAGS setting if let succeed.) hideErrors := cfg.CmdName == "env" || cfg.CmdName == "bug" - goflags = strings.Fields(cfg.Getenv("GOFLAGS")) - if goflags == nil { - goflags = []string{} // avoid work on later InitGOFLAGS call - } - // Each of the words returned by strings.Fields must be its own flag. // To set flag arguments use -x=value instead of -x value. // For boolean flags, -x is fine instead of -x=true. @@ -85,7 +62,7 @@ func InitGOFLAGS() { if i := strings.Index(name, "="); i >= 0 { name = name[:i] } - if !knownFlag[name] { + if !hasFlag(Go, name) { if hideErrors { continue } @@ -115,7 +92,11 @@ func SetFromGOFLAGS(flags *flag.FlagSet) { } for _, goflag := range goflags { name, value, hasValue := goflag, "", false - if i := strings.Index(goflag, "="); i >= 0 { + // Ignore invalid flags like '=' or '=value'. + // If it is not reported in InitGOFlags it means we don't want to report it. + if i := strings.Index(goflag, "="); i == 0 { + continue + } else if i > 0 { name, value, hasValue = goflag[:i], goflag[i+1:], true } if strings.HasPrefix(name, "--") { @@ -153,3 +134,20 @@ func SetFromGOFLAGS(flags *flag.FlagSet) { } } } + +// InGOFLAGS returns whether GOFLAGS contains the given flag, such as "-mod". +func InGOFLAGS(flag string) bool { + for _, goflag := range GOFLAGS() { + name := goflag + if strings.HasPrefix(name, "--") { + name = name[1:] + } + if i := strings.Index(name, "="); i >= 0 { + name = name[:i] + } + if name == flag { + return true + } + } + return false +} diff --git a/src/cmd/go/internal/base/signal.go b/src/cmd/go/internal/base/signal.go index 54d11876d0..05befcf7f0 100644 --- a/src/cmd/go/internal/base/signal.go +++ b/src/cmd/go/internal/base/signal.go @@ -15,7 +15,7 @@ var Interrupted = make(chan struct{}) // processSignals setups signal handler. func processSignals() { - sig := make(chan os.Signal) + sig := make(chan os.Signal, 1) signal.Notify(sig, signalsToIgnore...) go func() { <-sig diff --git a/src/cmd/go/internal/bug/bug.go b/src/cmd/go/internal/bug/bug.go index 52bd40f2fb..1085feaaee 100644 --- a/src/cmd/go/internal/bug/bug.go +++ b/src/cmd/go/internal/bug/bug.go @@ -10,7 +10,6 @@ import ( "context" "fmt" "io" - "io/ioutil" urlpkg "net/url" "os" "os/exec" @@ -105,7 +104,7 @@ func printGoDetails(w io.Writer) { func printOSDetails(w io.Writer) { switch runtime.GOOS { - case "darwin": + case "darwin", "ios": printCmdOut(w, "uname -v: ", "uname", "-v") printCmdOut(w, "", "sw_vers") case "linux": @@ -117,7 +116,7 @@ func printOSDetails(w io.Writer) { case "illumos", "solaris": // Be sure to use the OS-supplied uname, in "/usr/bin": printCmdOut(w, "uname -srv: ", "/usr/bin/uname", "-srv") - out, err := ioutil.ReadFile("/etc/release") + out, err := os.ReadFile("/etc/release") if err == nil { fmt.Fprintf(w, "/etc/release: %s\n", out) } else { @@ -177,7 +176,7 @@ func printGlibcVersion(w io.Writer) { src := []byte(`int main() {}`) srcfile := filepath.Join(tempdir, "go-bug.c") outfile := filepath.Join(tempdir, "go-bug") - err := ioutil.WriteFile(srcfile, src, 0644) + err := os.WriteFile(srcfile, src, 0644) if err != nil { return } diff --git a/src/cmd/go/internal/cache/cache.go b/src/cmd/go/internal/cache/cache.go index 15545ac31f..41f921641d 100644 --- a/src/cmd/go/internal/cache/cache.go +++ b/src/cmd/go/internal/cache/cache.go @@ -12,7 +12,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "strconv" @@ -54,7 +54,7 @@ func Open(dir string) (*Cache, error) { return nil, err } if !info.IsDir() { - return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} + return nil, &fs.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} } for i := 0; i < 256; i++ { name := filepath.Join(dir, fmt.Sprintf("%02x", i)) @@ -238,7 +238,7 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { if err != nil { return nil, entry, err } - data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) + data, _ := os.ReadFile(c.OutputFile(entry.OutputID)) if sha256.Sum256(data) != entry.OutputID { return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} } @@ -377,7 +377,7 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify // Truncate the file only *after* writing it. // (This should be a no-op, but truncate just in case of previous corruption.) // - // This differs from ioutil.WriteFile, which truncates to 0 *before* writing + // This differs from os.WriteFile, which truncates to 0 *before* writing // via os.O_TRUNC. Truncating only after writing ensures that a second write // of the same content to the same file is idempotent, and does not — even // temporarily! — undo the effect of the first write. diff --git a/src/cmd/go/internal/cache/cache_test.go b/src/cmd/go/internal/cache/cache_test.go index 1988c34502..a865b97018 100644 --- a/src/cmd/go/internal/cache/cache_test.go +++ b/src/cmd/go/internal/cache/cache_test.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/binary" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -20,7 +19,7 @@ func init() { } func TestBasic(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -65,7 +64,7 @@ func TestBasic(t *testing.T) { } func TestGrowth(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -118,7 +117,7 @@ func TestVerifyPanic(t *testing.T) { t.Fatal("initEnv did not set verify") } - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -151,7 +150,7 @@ func dummyID(x int) [HashSize]byte { } func TestCacheTrim(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -207,7 +206,7 @@ func TestCacheTrim(t *testing.T) { t.Fatal(err) } c.OutputFile(entry.OutputID) - data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt")) + data, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } @@ -220,7 +219,7 @@ func TestCacheTrim(t *testing.T) { t.Fatal(err) } c.OutputFile(entry.OutputID) - data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt")) + data2, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/cache/default.go b/src/cmd/go/internal/cache/default.go index 9f8dd8af4b..0b1c1e0c20 100644 --- a/src/cmd/go/internal/cache/default.go +++ b/src/cmd/go/internal/cache/default.go @@ -6,7 +6,6 @@ package cache import ( "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -49,7 +48,7 @@ func initDefaultCache() { } if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { // Best effort. - ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) + os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) } c, err := Open(dir) diff --git a/src/cmd/go/internal/cache/hash_test.go b/src/cmd/go/internal/cache/hash_test.go index 3bf7143039..a0356771ca 100644 --- a/src/cmd/go/internal/cache/hash_test.go +++ b/src/cmd/go/internal/cache/hash_test.go @@ -6,7 +6,6 @@ package cache import ( "fmt" - "io/ioutil" "os" "testing" ) @@ -28,7 +27,7 @@ func TestHash(t *testing.T) { } func TestHashFile(t *testing.T) { - f, err := ioutil.TempFile("", "cmd-go-test-") + f, err := os.CreateTemp("", "cmd-go-test-") if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index f9bbcd9180..c48904eacc 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -11,13 +11,15 @@ import ( "fmt" "go/build" "internal/cfg" - "io/ioutil" + "io" "os" "path/filepath" "runtime" "strings" "sync" + "cmd/go/internal/fsys" + "cmd/internal/objabi" ) @@ -27,7 +29,8 @@ var ( BuildBuildmode string // -buildmode flag BuildContext = defaultContext() BuildMod string // -mod flag - BuildModReason string // reason -mod flag is set, if set by default + BuildModExplicit bool // whether -mod was set explicitly + BuildModReason string // reason -mod was set, if set by default BuildI bool // -i flag BuildLinkshared bool // -linkshared flag BuildMSan bool // -msan flag @@ -48,6 +51,8 @@ var ( ModCacheRW bool // -modcacherw flag ModFile string // -modfile flag + Insecure bool // -insecure flag + CmdName string // "build", "install", "list", "mod tidy", etc. DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable) @@ -101,6 +106,15 @@ func defaultContext() build.Context { // Nothing to do here. } + ctxt.OpenFile = func(path string) (io.ReadCloser, error) { + return fsys.Open(path) + } + ctxt.ReadDir = fsys.ReadDir + ctxt.IsDir = func(path string) bool { + isDir, err := fsys.IsDir(path) + return err == nil && isDir + } + return ctxt } @@ -172,7 +186,7 @@ func initEnvCache() { if file == "" { return } - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return } @@ -253,6 +267,7 @@ var ( GONOPROXY = envOr("GONOPROXY", GOPRIVATE) GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE) GOINSECURE = Getenv("GOINSECURE") + GOVCS = Getenv("GOVCS") ) var SumdbDir = gopathDir("pkg/sumdb") diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go index 6bfd7ae21e..b1d40feb27 100644 --- a/src/cmd/go/internal/clean/clean.go +++ b/src/cmd/go/internal/clean/clean.go @@ -8,7 +8,7 @@ package clean import ( "context" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strconv" @@ -172,7 +172,7 @@ func runClean(ctx context.Context, cmd *base.Command, args []string) { f, err := lockedfile.Edit(filepath.Join(dir, "testexpire.txt")) if err == nil { now := time.Now().UnixNano() - buf, _ := ioutil.ReadAll(f) + buf, _ := io.ReadAll(f) prev, _ := strconv.ParseInt(strings.TrimSpace(string(buf)), 10, 64) if now > prev { if err = f.Truncate(0); err == nil { @@ -243,7 +243,7 @@ func clean(p *load.Package) { base.Errorf("%v", p.Error) return } - dirs, err := ioutil.ReadDir(p.Dir) + dirs, err := os.ReadDir(p.Dir) if err != nil { base.Errorf("go clean %s: %v", p.Dir, err) return @@ -275,6 +275,8 @@ func clean(p *load.Package) { allRemove = append(allRemove, elem, elem+".exe", + p.DefaultExecName(), + p.DefaultExecName()+".exe", ) } @@ -282,16 +284,28 @@ func clean(p *load.Package) { allRemove = append(allRemove, elem+".test", elem+".test.exe", + p.DefaultExecName()+".test", + p.DefaultExecName()+".test.exe", ) - // Remove a potential executable for each .go file in the directory that + // Remove a potential executable, test executable for each .go file in the directory that // is not part of the directory's package. for _, dir := range dirs { name := dir.Name() if packageFile[name] { continue } - if !dir.IsDir() && strings.HasSuffix(name, ".go") { + + if dir.IsDir() { + continue + } + + if strings.HasSuffix(name, "_test.go") { + base := name[:len(name)-len("_test.go")] + allRemove = append(allRemove, base+".test", base+".test.exe") + } + + if strings.HasSuffix(name, ".go") { // TODO(adg,rsc): check that this .go file is actually // in "package main", and therefore capable of building // to an executable file. diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go index 7bd75f7305..6937187522 100644 --- a/src/cmd/go/internal/envcmd/env.go +++ b/src/cmd/go/internal/envcmd/env.go @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "go/build" - "io/ioutil" "os" "path/filepath" "runtime" @@ -21,6 +20,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cache" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/modload" "cmd/go/internal/work" @@ -86,6 +86,8 @@ func MkEnv() []cfg.EnvVar { {Name: "GOSUMDB", Value: cfg.GOSUMDB}, {Name: "GOTMPDIR", Value: cfg.Getenv("GOTMPDIR")}, {Name: "GOTOOLDIR", Value: base.ToolDir}, + {Name: "GOVCS", Value: cfg.GOVCS}, + {Name: "GOVERSION", Value: runtime.Version()}, } if work.GccgoBin != "" { @@ -197,12 +199,26 @@ func runEnv(ctx context.Context, cmd *base.Command, args []string) { env := cfg.CmdEnv env = append(env, ExtraEnvVars()...) + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } + // Do we need to call ExtraEnvVarsCostly, which is a bit expensive? - // Only if we're listing all environment variables ("go env") - // or the variables being requested are in the extra list. - needCostly := true - if len(args) > 0 { + needCostly := false + if *envU || *envW { + // We're overwriting or removing default settings, + // so it doesn't really matter what the existing settings are. + // + // Moreover, we haven't validated the new settings yet, so it is + // important that we NOT perform any actions based on them, + // such as initializing the builder to compute other variables. + } else if len(args) == 0 { + // We're listing all environment variables ("go env"), + // including the expensive ones. + needCostly = true + } else { needCostly = false + checkCostly: for _, arg := range args { switch argKey(arg) { case "CGO_CFLAGS", @@ -213,6 +229,7 @@ func runEnv(ctx context.Context, cmd *base.Command, args []string) { "PKG_CONFIG", "GOGCCFLAGS": needCostly = true + break checkCostly } } } @@ -264,6 +281,13 @@ func runEnv(ctx context.Context, cmd *base.Command, args []string) { } } + gotmp, okGOTMP := add["GOTMPDIR"] + if okGOTMP { + if !filepath.IsAbs(gotmp) && gotmp != "" { + base.Fatalf("go env -w: GOTMPDIR must be an absolute path") + } + } + updateEnvFile(add, nil) return } @@ -375,7 +399,7 @@ func getOrigEnv(key string) string { func checkEnvWrite(key, val string) error { switch key { - case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR": + case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR", "GOVERSION": return fmt.Errorf("%s cannot be modified", key) case "GOENV": return fmt.Errorf("%s can only be set using the OS environment", key) @@ -403,6 +427,11 @@ func checkEnvWrite(key, val string) error { if !filepath.IsAbs(val) && val != "" { return fmt.Errorf("GOPATH entry is relative; must be absolute path: %q", val) } + // Make sure CC and CXX are absolute paths + case "CC", "CXX": + if !filepath.IsAbs(val) && val != "" && val != filepath.Base(val) { + return fmt.Errorf("%s entry is relative; must be absolute path: %q", key, val) + } } if !utf8.ValidString(val) { @@ -422,7 +451,7 @@ func updateEnvFile(add map[string]string, del map[string]bool) { if file == "" { base.Fatalf("go env: cannot find go env config: %v", err) } - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil && (!os.IsNotExist(err) || len(add) == 0) { base.Fatalf("go env: reading go env config: %v", err) } @@ -476,11 +505,11 @@ func updateEnvFile(add map[string]string, del map[string]bool) { } data = []byte(strings.Join(lines, "")) - err = ioutil.WriteFile(file, data, 0666) + err = os.WriteFile(file, data, 0666) if err != nil { // Try creating directory. os.MkdirAll(filepath.Dir(file), 0777) - err = ioutil.WriteFile(file, data, 0666) + err = os.WriteFile(file, data, 0666) if err != nil { base.Fatalf("go env: writing go env config: %v", err) } @@ -497,7 +526,10 @@ func lineToKey(line string) string { } // sortKeyValues sorts a sequence of lines by key. -// It differs from sort.Strings in that GO386= sorts after GO=. +// It differs from sort.Strings in that keys which are GOx where x is an ASCII +// character smaller than = sort after GO=. +// (There are no such keys currently. It used to matter for GO386 which was +// removed in Go 1.16.) func sortKeyValues(lines []string) { sort.Slice(lines, func(i, j int) bool { return lineToKey(lines[i]) < lineToKey(lines[j]) diff --git a/src/cmd/go/internal/fmtcmd/fmt.go b/src/cmd/go/internal/fmtcmd/fmt.go index f96cff429c..b0c1c59b40 100644 --- a/src/cmd/go/internal/fmtcmd/fmt.go +++ b/src/cmd/go/internal/fmtcmd/fmt.go @@ -23,7 +23,8 @@ import ( func init() { base.AddBuildFlagsNX(&CmdFmt.Flag) - base.AddLoadFlags(&CmdFmt.Flag) + base.AddModFlag(&CmdFmt.Flag) + base.AddModCommonFlags(&CmdFmt.Flag) } var CmdFmt = &base.Command{ diff --git a/src/cmd/go/internal/fsys/fsys.go b/src/cmd/go/internal/fsys/fsys.go new file mode 100644 index 0000000000..7b06c3c7f3 --- /dev/null +++ b/src/cmd/go/internal/fsys/fsys.go @@ -0,0 +1,689 @@ +// Package fsys is an abstraction for reading files that +// allows for virtual overlays on top of the files on disk. +package fsys + +import ( + "encoding/json" + "errors" + "fmt" + "io/fs" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "sort" + "strings" + "time" +) + +// OverlayFile is the path to a text file in the OverlayJSON format. +// It is the value of the -overlay flag. +var OverlayFile string + +// OverlayJSON is the format overlay files are expected to be in. +// The Replace map maps from overlaid paths to replacement paths: +// the Go command will forward all reads trying to open +// each overlaid path to its replacement path, or consider the overlaid +// path not to exist if the replacement path is empty. +type OverlayJSON struct { + Replace map[string]string +} + +type node struct { + actualFilePath string // empty if a directory + children map[string]*node // path element → file or directory +} + +func (n *node) isDir() bool { + return n.actualFilePath == "" && n.children != nil +} + +func (n *node) isDeleted() bool { + return n.actualFilePath == "" && n.children == nil +} + +// TODO(matloob): encapsulate these in an io/fs-like interface +var overlay map[string]*node // path -> file or directory node +var cwd string // copy of base.Cwd to avoid dependency + +// Canonicalize a path for looking it up in the overlay. +// Important: filepath.Join(cwd, path) doesn't always produce +// the correct absolute path if path is relative, because on +// Windows producing the correct absolute path requires making +// a syscall. So this should only be used when looking up paths +// in the overlay, or canonicalizing the paths in the overlay. +func canonicalize(path string) string { + if path == "" { + return "" + } + if filepath.IsAbs(path) { + return filepath.Clean(path) + } + + if v := filepath.VolumeName(cwd); v != "" && path[0] == filepath.Separator { + // On Windows filepath.Join(cwd, path) doesn't always work. In general + // filepath.Abs needs to make a syscall on Windows. Elsewhere in cmd/go + // use filepath.Join(cwd, path), but cmd/go specifically supports Windows + // paths that start with "\" which implies the path is relative to the + // volume of the working directory. See golang.org/issue/8130. + return filepath.Join(v, path) + } + + // Make the path absolute. + return filepath.Join(cwd, path) +} + +// Init initializes the overlay, if one is being used. +func Init(wd string) error { + if overlay != nil { + // already initialized + return nil + } + + cwd = wd + + if OverlayFile == "" { + return nil + } + + b, err := os.ReadFile(OverlayFile) + if err != nil { + return fmt.Errorf("reading overlay file: %v", err) + } + + var overlayJSON OverlayJSON + if err := json.Unmarshal(b, &overlayJSON); err != nil { + return fmt.Errorf("parsing overlay JSON: %v", err) + } + + return initFromJSON(overlayJSON) +} + +func initFromJSON(overlayJSON OverlayJSON) error { + // Canonicalize the paths in in the overlay map. + // Use reverseCanonicalized to check for collisions: + // no two 'from' paths should canonicalize to the same path. + overlay = make(map[string]*node) + reverseCanonicalized := make(map[string]string) // inverse of canonicalize operation, to check for duplicates + // Build a table of file and directory nodes from the replacement map. + + // Remove any potential non-determinism from iterating over map by sorting it. + replaceFrom := make([]string, 0, len(overlayJSON.Replace)) + for k := range overlayJSON.Replace { + replaceFrom = append(replaceFrom, k) + } + sort.Strings(replaceFrom) + + for _, from := range replaceFrom { + to := overlayJSON.Replace[from] + // Canonicalize paths and check for a collision. + if from == "" { + return fmt.Errorf("empty string key in overlay file Replace map") + } + cfrom := canonicalize(from) + if to != "" { + // Don't canonicalize "", meaning to delete a file, because then it will turn into ".". + to = canonicalize(to) + } + if otherFrom, seen := reverseCanonicalized[cfrom]; seen { + return fmt.Errorf( + "paths %q and %q both canonicalize to %q in overlay file Replace map", otherFrom, from, cfrom) + } + reverseCanonicalized[cfrom] = from + from = cfrom + + // Create node for overlaid file. + dir, base := filepath.Dir(from), filepath.Base(from) + if n, ok := overlay[from]; ok { + // All 'from' paths in the overlay are file paths. Since the from paths + // are in a map, they are unique, so if the node already exists we added + // it below when we create parent directory nodes. That is, that + // both a file and a path to one of its parent directories exist as keys + // in the Replace map. + // + // This only applies if the overlay directory has any files or directories + // in it: placeholder directories that only contain deleted files don't + // count. They are safe to be overwritten with actual files. + for _, f := range n.children { + if !f.isDeleted() { + return fmt.Errorf("invalid overlay: path %v is used as both file and directory", from) + } + } + } + overlay[from] = &node{actualFilePath: to} + + // Add parent directory nodes to overlay structure. + childNode := overlay[from] + for { + dirNode := overlay[dir] + if dirNode == nil || dirNode.isDeleted() { + dirNode = &node{children: make(map[string]*node)} + overlay[dir] = dirNode + } + if childNode.isDeleted() { + // Only create one parent for a deleted file: + // the directory only conditionally exists if + // there are any non-deleted children, so + // we don't create their parents. + if dirNode.isDir() { + dirNode.children[base] = childNode + } + break + } + if !dirNode.isDir() { + // This path already exists as a file, so it can't be a parent + // directory. See comment at error above. + return fmt.Errorf("invalid overlay: path %v is used as both file and directory", dir) + } + dirNode.children[base] = childNode + parent := filepath.Dir(dir) + if parent == dir { + break // reached the top; there is no parent + } + dir, base = parent, filepath.Base(dir) + childNode = dirNode + } + } + + return nil +} + +// IsDir returns true if path is a directory on disk or in the +// overlay. +func IsDir(path string) (bool, error) { + path = canonicalize(path) + + if _, ok := parentIsOverlayFile(path); ok { + return false, nil + } + + if n, ok := overlay[path]; ok { + return n.isDir(), nil + } + + fi, err := os.Stat(path) + if err != nil { + return false, err + } + + return fi.IsDir(), nil +} + +// parentIsOverlayFile returns whether name or any of +// its parents are files in the overlay, and the first parent found, +// including name itself, that's a file in the overlay. +func parentIsOverlayFile(name string) (string, bool) { + if overlay != nil { + // Check if name can't possibly be a directory because + // it or one of its parents is overlaid with a file. + // TODO(matloob): Maybe save this to avoid doing it every time? + prefix := name + for { + node := overlay[prefix] + if node != nil && !node.isDir() { + return prefix, true + } + parent := filepath.Dir(prefix) + if parent == prefix { + break + } + prefix = parent + } + } + + return "", false +} + +// errNotDir is used to communicate from ReadDir to IsDirWithGoFiles +// that the argument is not a directory, so that IsDirWithGoFiles doesn't +// return an error. +var errNotDir = errors.New("not a directory") + +// readDir reads a dir on disk, returning an error that is errNotDir if the dir is not a directory. +// Unfortunately, the error returned by ioutil.ReadDir if dir is not a directory +// can vary depending on the OS (Linux, Mac, Windows return ENOTDIR; BSD returns EINVAL). +func readDir(dir string) ([]fs.FileInfo, error) { + fis, err := ioutil.ReadDir(dir) + if err == nil { + return fis, nil + } + + if os.IsNotExist(err) { + return nil, err + } + if dirfi, staterr := os.Stat(dir); staterr == nil && !dirfi.IsDir() { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir} + } + return nil, err +} + +// ReadDir provides a slice of fs.FileInfo entries corresponding +// to the overlaid files in the directory. +func ReadDir(dir string) ([]fs.FileInfo, error) { + dir = canonicalize(dir) + if _, ok := parentIsOverlayFile(dir); ok { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir} + } + + dirNode := overlay[dir] + if dirNode == nil { + return readDir(dir) + } + if dirNode.isDeleted() { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: fs.ErrNotExist} + } + diskfis, err := readDir(dir) + if err != nil && !os.IsNotExist(err) && !errors.Is(err, errNotDir) { + return nil, err + } + + // Stat files in overlay to make composite list of fileinfos + files := make(map[string]fs.FileInfo) + for _, f := range diskfis { + files[f.Name()] = f + } + for name, to := range dirNode.children { + switch { + case to.isDir(): + files[name] = fakeDir(name) + case to.isDeleted(): + delete(files, name) + default: + // This is a regular file. + f, err := os.Lstat(to.actualFilePath) + if err != nil { + files[name] = missingFile(name) + continue + } else if f.IsDir() { + return nil, fmt.Errorf("for overlay of %q to %q: overlay Replace entries can't point to dirctories", + filepath.Join(dir, name), to.actualFilePath) + } + // Add a fileinfo for the overlaid file, so that it has + // the original file's name, but the overlaid file's metadata. + files[name] = fakeFile{name, f} + } + } + sortedFiles := diskfis[:0] + for _, f := range files { + sortedFiles = append(sortedFiles, f) + } + sort.Slice(sortedFiles, func(i, j int) bool { return sortedFiles[i].Name() < sortedFiles[j].Name() }) + return sortedFiles, nil +} + +// OverlayPath returns the path to the overlaid contents of the +// file, the empty string if the overlay deletes the file, or path +// itself if the file is not in the overlay, the file is a directory +// in the overlay, or there is no overlay. +// It returns true if the path is overlaid with a regular file +// or deleted, and false otherwise. +func OverlayPath(path string) (string, bool) { + if p, ok := overlay[canonicalize(path)]; ok && !p.isDir() { + return p.actualFilePath, ok + } + + return path, false +} + +// Open opens the file at or overlaid on the given path. +func Open(path string) (*os.File, error) { + return OpenFile(path, os.O_RDONLY, 0) +} + +// OpenFile opens the file at or overlaid on the given path with the flag and perm. +func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) { + cpath := canonicalize(path) + if node, ok := overlay[cpath]; ok { + // Opening a file in the overlay. + if node.isDir() { + return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("fsys.OpenFile doesn't support opening directories yet")} + } + // We can't open overlaid paths for write. + if perm != os.FileMode(os.O_RDONLY) { + return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("overlaid files can't be opened for write")} + } + return os.OpenFile(node.actualFilePath, flag, perm) + } + if parent, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok { + // The file is deleted explicitly in the Replace map, + // or implicitly because one of its parent directories was + // replaced by a file. + return nil, &fs.PathError{ + Op: "Open", + Path: path, + Err: fmt.Errorf("file %s does not exist: parent directory %s is replaced by a file in overlay", path, parent), + } + } + return os.OpenFile(cpath, flag, perm) +} + +// IsDirWithGoFiles reports whether dir is a directory containing Go files +// either on disk or in the overlay. +func IsDirWithGoFiles(dir string) (bool, error) { + fis, err := ReadDir(dir) + if os.IsNotExist(err) || errors.Is(err, errNotDir) { + return false, nil + } + if err != nil { + return false, err + } + + var firstErr error + for _, fi := range fis { + if fi.IsDir() { + continue + } + + // TODO(matloob): this enforces that the "from" in the map + // has a .go suffix, but the actual destination file + // doesn't need to have a .go suffix. Is this okay with the + // compiler? + if !strings.HasSuffix(fi.Name(), ".go") { + continue + } + if fi.Mode().IsRegular() { + return true, nil + } + + // fi is the result of an Lstat, so it doesn't follow symlinks. + // But it's okay if the file is a symlink pointing to a regular + // file, so use os.Stat to follow symlinks and check that. + actualFilePath, _ := OverlayPath(filepath.Join(dir, fi.Name())) + fi, err := os.Stat(actualFilePath) + if err == nil && fi.Mode().IsRegular() { + return true, nil + } + if err != nil && firstErr == nil { + firstErr = err + } + } + + // No go files found in directory. + return false, firstErr +} + +// walk recursively descends path, calling walkFn. Copied, with some +// modifications from path/filepath.walk. +func walk(path string, info fs.FileInfo, walkFn filepath.WalkFunc) error { + if !info.IsDir() { + return walkFn(path, info, nil) + } + + fis, readErr := ReadDir(path) + walkErr := walkFn(path, info, readErr) + // If readErr != nil, walk can't walk into this directory. + // walkErr != nil means walkFn want walk to skip this directory or stop walking. + // Therefore, if one of readErr and walkErr isn't nil, walk will return. + if readErr != nil || walkErr != nil { + // The caller's behavior is controlled by the return value, which is decided + // by walkFn. walkFn may ignore readErr and return nil. + // If walkFn returns SkipDir, it will be handled by the caller. + // So walk should return whatever walkFn returns. + return walkErr + } + + for _, fi := range fis { + filename := filepath.Join(path, fi.Name()) + if walkErr = walk(filename, fi, walkFn); walkErr != nil { + if !fi.IsDir() || walkErr != filepath.SkipDir { + return walkErr + } + } + } + return nil +} + +// Walk walks the file tree rooted at root, calling walkFn for each file or +// directory in the tree, including root. +func Walk(root string, walkFn filepath.WalkFunc) error { + info, err := Lstat(root) + if err != nil { + err = walkFn(root, nil, err) + } else { + err = walk(root, info, walkFn) + } + if err == filepath.SkipDir { + return nil + } + return err +} + +// lstat implements a version of os.Lstat that operates on the overlay filesystem. +func Lstat(path string) (fs.FileInfo, error) { + return overlayStat(path, os.Lstat, "lstat") +} + +// Stat implements a version of os.Stat that operates on the overlay filesystem. +func Stat(path string) (fs.FileInfo, error) { + return overlayStat(path, os.Stat, "stat") +} + +// overlayStat implements lstat or Stat (depending on whether os.Lstat or os.Stat is passed in). +func overlayStat(path string, osStat func(string) (fs.FileInfo, error), opName string) (fs.FileInfo, error) { + cpath := canonicalize(path) + + if _, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok { + return nil, &fs.PathError{Op: opName, Path: cpath, Err: fs.ErrNotExist} + } + + node, ok := overlay[cpath] + if !ok { + // The file or directory is not overlaid. + return osStat(path) + } + + switch { + case node.isDeleted(): + return nil, &fs.PathError{Op: "lstat", Path: cpath, Err: fs.ErrNotExist} + case node.isDir(): + return fakeDir(filepath.Base(path)), nil + default: + fi, err := osStat(node.actualFilePath) + if err != nil { + return nil, err + } + return fakeFile{name: filepath.Base(path), real: fi}, nil + } +} + +// fakeFile provides an fs.FileInfo implementation for an overlaid file, +// so that the file has the name of the overlaid file, but takes all +// other characteristics of the replacement file. +type fakeFile struct { + name string + real fs.FileInfo +} + +func (f fakeFile) Name() string { return f.name } +func (f fakeFile) Size() int64 { return f.real.Size() } +func (f fakeFile) Mode() fs.FileMode { return f.real.Mode() } +func (f fakeFile) ModTime() time.Time { return f.real.ModTime() } +func (f fakeFile) IsDir() bool { return f.real.IsDir() } +func (f fakeFile) Sys() interface{} { return f.real.Sys() } + +// missingFile provides an fs.FileInfo for an overlaid file where the +// destination file in the overlay doesn't exist. It returns zero values +// for the fileInfo methods other than Name, set to the file's name, and Mode +// set to ModeIrregular. +type missingFile string + +func (f missingFile) Name() string { return string(f) } +func (f missingFile) Size() int64 { return 0 } +func (f missingFile) Mode() fs.FileMode { return fs.ModeIrregular } +func (f missingFile) ModTime() time.Time { return time.Unix(0, 0) } +func (f missingFile) IsDir() bool { return false } +func (f missingFile) Sys() interface{} { return nil } + +// fakeDir provides an fs.FileInfo implementation for directories that are +// implicitly created by overlaid files. Each directory in the +// path of an overlaid file is considered to exist in the overlay filesystem. +type fakeDir string + +func (f fakeDir) Name() string { return string(f) } +func (f fakeDir) Size() int64 { return 0 } +func (f fakeDir) Mode() fs.FileMode { return fs.ModeDir | 0500 } +func (f fakeDir) ModTime() time.Time { return time.Unix(0, 0) } +func (f fakeDir) IsDir() bool { return true } +func (f fakeDir) Sys() interface{} { return nil } + +// Glob is like filepath.Glob but uses the overlay file system. +func Glob(pattern string) (matches []string, err error) { + // Check pattern is well-formed. + if _, err := filepath.Match(pattern, ""); err != nil { + return nil, err + } + if !hasMeta(pattern) { + if _, err = Lstat(pattern); err != nil { + return nil, nil + } + return []string{pattern}, nil + } + + dir, file := filepath.Split(pattern) + volumeLen := 0 + if runtime.GOOS == "windows" { + volumeLen, dir = cleanGlobPathWindows(dir) + } else { + dir = cleanGlobPath(dir) + } + + if !hasMeta(dir[volumeLen:]) { + return glob(dir, file, nil) + } + + // Prevent infinite recursion. See issue 15879. + if dir == pattern { + return nil, filepath.ErrBadPattern + } + + var m []string + m, err = Glob(dir) + if err != nil { + return + } + for _, d := range m { + matches, err = glob(d, file, matches) + if err != nil { + return + } + } + return +} + +// cleanGlobPath prepares path for glob matching. +func cleanGlobPath(path string) string { + switch path { + case "": + return "." + case string(filepath.Separator): + // do nothing to the path + return path + default: + return path[0 : len(path)-1] // chop off trailing separator + } +} + +func volumeNameLen(path string) int { + isSlash := func(c uint8) bool { + return c == '\\' || c == '/' + } + if len(path) < 2 { + return 0 + } + // with drive letter + c := path[0] + if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') { + return 2 + } + // is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx + if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) && + !isSlash(path[2]) && path[2] != '.' { + // first, leading `\\` and next shouldn't be `\`. its server name. + for n := 3; n < l-1; n++ { + // second, next '\' shouldn't be repeated. + if isSlash(path[n]) { + n++ + // third, following something characters. its share name. + if !isSlash(path[n]) { + if path[n] == '.' { + break + } + for ; n < l; n++ { + if isSlash(path[n]) { + break + } + } + return n + } + break + } + } + } + return 0 +} + +// cleanGlobPathWindows is windows version of cleanGlobPath. +func cleanGlobPathWindows(path string) (prefixLen int, cleaned string) { + vollen := volumeNameLen(path) + switch { + case path == "": + return 0, "." + case vollen+1 == len(path) && os.IsPathSeparator(path[len(path)-1]): // /, \, C:\ and C:/ + // do nothing to the path + return vollen + 1, path + case vollen == len(path) && len(path) == 2: // C: + return vollen, path + "." // convert C: into C:. + default: + if vollen >= len(path) { + vollen = len(path) - 1 + } + return vollen, path[0 : len(path)-1] // chop off trailing separator + } +} + +// glob searches for files matching pattern in the directory dir +// and appends them to matches. If the directory cannot be +// opened, it returns the existing matches. New matches are +// added in lexicographical order. +func glob(dir, pattern string, matches []string) (m []string, e error) { + m = matches + fi, err := Stat(dir) + if err != nil { + return // ignore I/O error + } + if !fi.IsDir() { + return // ignore I/O error + } + + list, err := ReadDir(dir) + if err != nil { + return // ignore I/O error + } + + var names []string + for _, info := range list { + names = append(names, info.Name()) + } + sort.Strings(names) + + for _, n := range names { + matched, err := filepath.Match(pattern, n) + if err != nil { + return m, err + } + if matched { + m = append(m, filepath.Join(dir, n)) + } + } + return +} + +// hasMeta reports whether path contains any of the magic characters +// recognized by filepath.Match. +func hasMeta(path string) bool { + magicChars := `*?[` + if runtime.GOOS != "windows" { + magicChars = `*?[\` + } + return strings.ContainsAny(path, magicChars) +} diff --git a/src/cmd/go/internal/fsys/fsys_test.go b/src/cmd/go/internal/fsys/fsys_test.go new file mode 100644 index 0000000000..7f175c7031 --- /dev/null +++ b/src/cmd/go/internal/fsys/fsys_test.go @@ -0,0 +1,1094 @@ +package fsys + +import ( + "cmd/go/internal/txtar" + "encoding/json" + "errors" + "fmt" + "internal/testenv" + "io" + "io/fs" + "os" + "path/filepath" + "reflect" + "testing" +) + +// initOverlay resets the overlay state to reflect the config. +// config should be a text archive string. The comment is the overlay config +// json, and the files, in the archive are laid out in a temp directory +// that cwd is set to. +func initOverlay(t *testing.T, config string) { + t.Helper() + + // Create a temporary directory and chdir to it. + prevwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + cwd = filepath.Join(t.TempDir(), "root") + if err := os.Mkdir(cwd, 0777); err != nil { + t.Fatal(err) + } + if err := os.Chdir(cwd); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + overlay = nil + if err := os.Chdir(prevwd); err != nil { + t.Fatal(err) + } + }) + + a := txtar.Parse([]byte(config)) + for _, f := range a.Files { + name := filepath.Join(cwd, f.Name) + if err := os.MkdirAll(filepath.Dir(name), 0777); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(name, f.Data, 0666); err != nil { + t.Fatal(err) + } + } + + var overlayJSON OverlayJSON + if err := json.Unmarshal(a.Comment, &overlayJSON); err != nil { + t.Fatal(fmt.Errorf("parsing overlay JSON: %v", err)) + } + + initFromJSON(overlayJSON) +} + +func TestIsDir(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir4": "overlayfiles/subdir4", + "subdir3/file3b.txt": "overlayfiles/subdir3_file3b.txt", + "subdir5": "", + "subdir6": "" + } +} +-- subdir1/file1.txt -- + +-- subdir3/file3a.txt -- +33 +-- subdir4/file4.txt -- +444 +-- overlayfiles/subdir2_file2.txt -- +2 +-- overlayfiles/subdir3_file3b.txt -- +66666 +-- overlayfiles/subdir4 -- +x +-- subdir6/file6.txt -- +six +`) + + testCases := []struct { + path string + want, wantErr bool + }{ + {"", true, true}, + {".", true, false}, + {cwd, true, false}, + {cwd + string(filepath.Separator), true, false}, + // subdir1 is only on disk + {filepath.Join(cwd, "subdir1"), true, false}, + {"subdir1", true, false}, + {"subdir1" + string(filepath.Separator), true, false}, + {"subdir1/file1.txt", false, false}, + {"subdir1/doesntexist.txt", false, true}, + {"doesntexist", false, true}, + // subdir2 is only in overlay + {filepath.Join(cwd, "subdir2"), true, false}, + {"subdir2", true, false}, + {"subdir2" + string(filepath.Separator), true, false}, + {"subdir2/file2.txt", false, false}, + {"subdir2/doesntexist.txt", false, true}, + // subdir3 has files on disk and in overlay + {filepath.Join(cwd, "subdir3"), true, false}, + {"subdir3", true, false}, + {"subdir3" + string(filepath.Separator), true, false}, + {"subdir3/file3a.txt", false, false}, + {"subdir3/file3b.txt", false, false}, + {"subdir3/doesntexist.txt", false, true}, + // subdir4 is overlaid with a file + {filepath.Join(cwd, "subdir4"), false, false}, + {"subdir4", false, false}, + {"subdir4" + string(filepath.Separator), false, false}, + {"subdir4/file4.txt", false, false}, + {"subdir4/doesntexist.txt", false, false}, + // subdir5 doesn't exist, and is overlaid with a "delete" entry + {filepath.Join(cwd, "subdir5"), false, false}, + {"subdir5", false, false}, + {"subdir5" + string(filepath.Separator), false, false}, + {"subdir5/file5.txt", false, false}, + {"subdir5/doesntexist.txt", false, false}, + // subdir6 does exist, and is overlaid with a "delete" entry + {filepath.Join(cwd, "subdir6"), false, false}, + {"subdir6", false, false}, + {"subdir6" + string(filepath.Separator), false, false}, + {"subdir6/file6.txt", false, false}, + {"subdir6/doesntexist.txt", false, false}, + } + + for _, tc := range testCases { + got, err := IsDir(tc.path) + if err != nil { + if !tc.wantErr { + t.Errorf("IsDir(%q): got error with string %q, want no error", tc.path, err.Error()) + } + continue + } + if tc.wantErr { + t.Errorf("IsDir(%q): got no error, want error", tc.path) + } + if tc.want != got { + t.Errorf("IsDir(%q) = %v, want %v", tc.path, got, tc.want) + } + } +} + +const readDirOverlay = ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir4": "overlayfiles/subdir4", + "subdir3/file3b.txt": "overlayfiles/subdir3_file3b.txt", + "subdir5": "", + "subdir6/asubsubdir/afile.txt": "overlayfiles/subdir6_asubsubdir_afile.txt", + "subdir6/asubsubdir/zfile.txt": "overlayfiles/subdir6_asubsubdir_zfile.txt", + "subdir6/zsubsubdir/file.txt": "overlayfiles/subdir6_zsubsubdir_file.txt", + "subdir7/asubsubdir/file.txt": "overlayfiles/subdir7_asubsubdir_file.txt", + "subdir7/zsubsubdir/file.txt": "overlayfiles/subdir7_zsubsubdir_file.txt", + "subdir8/doesntexist": "this_file_doesnt_exist_anywhere", + "other/pointstodir": "overlayfiles/this_is_a_directory", + "parentoverwritten/subdir1": "overlayfiles/parentoverwritten_subdir1", + "subdir9/this_file_is_overlaid.txt": "overlayfiles/subdir9_this_file_is_overlaid.txt", + "subdir10/only_deleted_file.txt": "", + "subdir11/deleted.txt": "", + "subdir11": "overlayfiles/subdir11", + "textfile.txt/file.go": "overlayfiles/textfile_txt_file.go" + } +} +-- subdir1/file1.txt -- + +-- subdir3/file3a.txt -- +33 +-- subdir4/file4.txt -- +444 +-- subdir6/file.txt -- +-- subdir6/asubsubdir/file.txt -- +-- subdir6/anothersubsubdir/file.txt -- +-- subdir9/this_file_is_overlaid.txt -- +-- subdir10/only_deleted_file.txt -- +this will be deleted in overlay +-- subdir11/deleted.txt -- +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- textfile.txt -- +this will be overridden by textfile.txt/file.go +-- overlayfiles/subdir2_file2.txt -- +2 +-- overlayfiles/subdir3_file3b.txt -- +66666 +-- overlayfiles/subdir4 -- +x +-- overlayfiles/subdir6_asubsubdir_afile.txt -- +-- overlayfiles/subdir6_asubsubdir_zfile.txt -- +-- overlayfiles/subdir6_zsubsubdir_file.txt -- +-- overlayfiles/subdir7_asubsubdir_file.txt -- +-- overlayfiles/subdir7_zsubsubdir_file.txt -- +-- overlayfiles/parentoverwritten_subdir1 -- +x +-- overlayfiles/subdir9_this_file_is_overlaid.txt -- +99999999 +-- overlayfiles/subdir11 -- +-- overlayfiles/this_is_a_directory/file.txt -- +-- overlayfiles/textfile_txt_file.go -- +x +` + +func TestReadDir(t *testing.T) { + initOverlay(t, readDirOverlay) + + type entry struct { + name string + size int64 + isDir bool + } + + testCases := []struct { + dir string + want []entry + }{ + { + ".", []entry{ + {"other", 0, true}, + {"overlayfiles", 0, true}, + {"parentoverwritten", 0, true}, + {"subdir1", 0, true}, + {"subdir10", 0, true}, + {"subdir11", 0, false}, + {"subdir2", 0, true}, + {"subdir3", 0, true}, + {"subdir4", 2, false}, + // no subdir5. + {"subdir6", 0, true}, + {"subdir7", 0, true}, + {"subdir8", 0, true}, + {"subdir9", 0, true}, + {"textfile.txt", 0, true}, + }, + }, + { + "subdir1", []entry{ + {"file1.txt", 1, false}, + }, + }, + { + "subdir2", []entry{ + {"file2.txt", 2, false}, + }, + }, + { + "subdir3", []entry{ + {"file3a.txt", 3, false}, + {"file3b.txt", 6, false}, + }, + }, + { + "subdir6", []entry{ + {"anothersubsubdir", 0, true}, + {"asubsubdir", 0, true}, + {"file.txt", 0, false}, + {"zsubsubdir", 0, true}, + }, + }, + { + "subdir6/asubsubdir", []entry{ + {"afile.txt", 0, false}, + {"file.txt", 0, false}, + {"zfile.txt", 0, false}, + }, + }, + { + "subdir8", []entry{ + {"doesntexist", 0, false}, // entry is returned even if destination file doesn't exist + }, + }, + { + // check that read dir actually redirects files that already exist + // the original this_file_is_overlaid.txt is empty + "subdir9", []entry{ + {"this_file_is_overlaid.txt", 9, false}, + }, + }, + { + "subdir10", []entry{}, + }, + { + "parentoverwritten", []entry{ + {"subdir1", 2, false}, + }, + }, + { + "textfile.txt", []entry{ + {"file.go", 2, false}, + }, + }, + } + + for _, tc := range testCases { + dir, want := tc.dir, tc.want + infos, err := ReadDir(dir) + if err != nil { + t.Errorf("ReadDir(%q): %v", dir, err) + continue + } + // Sorted diff of want and infos. + for len(infos) > 0 || len(want) > 0 { + switch { + case len(want) == 0 || len(infos) > 0 && infos[0].Name() < want[0].name: + t.Errorf("ReadDir(%q): unexpected entry: %s IsDir=%v Size=%v", dir, infos[0].Name(), infos[0].IsDir(), infos[0].Size()) + infos = infos[1:] + case len(infos) == 0 || len(want) > 0 && want[0].name < infos[0].Name(): + t.Errorf("ReadDir(%q): missing entry: %s IsDir=%v Size=%v", dir, want[0].name, want[0].isDir, want[0].size) + want = want[1:] + default: + infoSize := infos[0].Size() + if want[0].isDir { + infoSize = 0 + } + if infos[0].IsDir() != want[0].isDir || want[0].isDir && infoSize != want[0].size { + t.Errorf("ReadDir(%q): %s: IsDir=%v Size=%v, want IsDir=%v Size=%v", dir, want[0].name, infos[0].IsDir(), infoSize, want[0].isDir, want[0].size) + } + infos = infos[1:] + want = want[1:] + } + } + } + + errCases := []string{ + "subdir1/file1.txt", // regular file on disk + "subdir2/file2.txt", // regular file in overlay + "subdir4", // directory overlaid with regular file + "subdir5", // directory deleted in overlay + "parentoverwritten/subdir1/subdir2/subdir3", // parentoverwritten/subdir1 overlaid with regular file + "parentoverwritten/subdir1/subdir2", // parentoverwritten/subdir1 overlaid with regular file + "subdir11", // directory with deleted child, overlaid with regular file + "other/pointstodir", + } + + for _, dir := range errCases { + _, err := ReadDir(dir) + if _, ok := err.(*fs.PathError); !ok { + t.Errorf("ReadDir(%q): err = %T (%v), want fs.PathError", dir, err, err) + } + } +} + +func TestGlob(t *testing.T) { + initOverlay(t, readDirOverlay) + + testCases := []struct { + pattern string + match []string + }{ + { + "*o*", + []string{ + "other", + "overlayfiles", + "parentoverwritten", + }, + }, + { + "subdir2/file2.txt", + []string{ + "subdir2/file2.txt", + }, + }, + { + "*/*.txt", + []string{ + "overlayfiles/subdir2_file2.txt", + "overlayfiles/subdir3_file3b.txt", + "overlayfiles/subdir6_asubsubdir_afile.txt", + "overlayfiles/subdir6_asubsubdir_zfile.txt", + "overlayfiles/subdir6_zsubsubdir_file.txt", + "overlayfiles/subdir7_asubsubdir_file.txt", + "overlayfiles/subdir7_zsubsubdir_file.txt", + "overlayfiles/subdir9_this_file_is_overlaid.txt", + "subdir1/file1.txt", + "subdir2/file2.txt", + "subdir3/file3a.txt", + "subdir3/file3b.txt", + "subdir6/file.txt", + "subdir9/this_file_is_overlaid.txt", + }, + }, + } + + for _, tc := range testCases { + pattern := tc.pattern + match, err := Glob(pattern) + if err != nil { + t.Errorf("Glob(%q): %v", pattern, err) + continue + } + want := tc.match + for i, name := range want { + if name != tc.pattern { + want[i] = filepath.FromSlash(name) + } + } + for len(match) > 0 || len(want) > 0 { + switch { + case len(match) == 0 || len(want) > 0 && want[0] < match[0]: + t.Errorf("Glob(%q): missing match: %s", pattern, want[0]) + want = want[1:] + case len(want) == 0 || len(match) > 0 && match[0] < want[0]: + t.Errorf("Glob(%q): extra match: %s", pattern, match[0]) + match = match[1:] + default: + want = want[1:] + match = match[1:] + } + } + } +} + +func TestOverlayPath(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir3/doesntexist": "this_file_doesnt_exist_anywhere", + "subdir4/this_file_is_overlaid.txt": "overlayfiles/subdir4_this_file_is_overlaid.txt", + "subdir5/deleted.txt": "", + "parentoverwritten/subdir1": "" + } +} +-- subdir1/file1.txt -- +file 1 +-- subdir4/this_file_is_overlaid.txt -- +these contents are replaced by the overlay +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- subdir5/deleted.txt -- +deleted +-- overlayfiles/subdir2_file2.txt -- +file 2 +-- overlayfiles/subdir4_this_file_is_overlaid.txt -- +99999999 +`) + + testCases := []struct { + path string + wantPath string + wantOK bool + }{ + {"subdir1/file1.txt", "subdir1/file1.txt", false}, + // OverlayPath returns false for directories + {"subdir2", "subdir2", false}, + {"subdir2/file2.txt", filepath.Join(cwd, "overlayfiles/subdir2_file2.txt"), true}, + // OverlayPath doesn't stat a file to see if it exists, so it happily returns + // the 'to' path and true even if the 'to' path doesn't exist on disk. + {"subdir3/doesntexist", filepath.Join(cwd, "this_file_doesnt_exist_anywhere"), true}, + // Like the subdir2/file2.txt case above, but subdir4 exists on disk, but subdir2 does not. + {"subdir4/this_file_is_overlaid.txt", filepath.Join(cwd, "overlayfiles/subdir4_this_file_is_overlaid.txt"), true}, + {"subdir5", "subdir5", false}, + {"subdir5/deleted.txt", "", true}, + } + + for _, tc := range testCases { + gotPath, gotOK := OverlayPath(tc.path) + if gotPath != tc.wantPath || gotOK != tc.wantOK { + t.Errorf("OverlayPath(%q): got %v, %v; want %v, %v", + tc.path, gotPath, gotOK, tc.wantPath, tc.wantOK) + } + } +} + +func TestOpen(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir3/doesntexist": "this_file_doesnt_exist_anywhere", + "subdir4/this_file_is_overlaid.txt": "overlayfiles/subdir4_this_file_is_overlaid.txt", + "subdir5/deleted.txt": "", + "parentoverwritten/subdir1": "", + "childoverlay/subdir1.txt/child.txt": "overlayfiles/child.txt", + "subdir11/deleted.txt": "", + "subdir11": "overlayfiles/subdir11", + "parentdeleted": "", + "parentdeleted/file.txt": "overlayfiles/parentdeleted_file.txt" + } +} +-- subdir11/deleted.txt -- +-- subdir1/file1.txt -- +file 1 +-- subdir4/this_file_is_overlaid.txt -- +these contents are replaced by the overlay +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- childoverlay/subdir1.txt -- +this file doesn't exist because the path +childoverlay/subdir1.txt/child.txt is in the overlay +-- subdir5/deleted.txt -- +deleted +-- parentdeleted -- +this will be deleted so that parentdeleted/file.txt can exist +-- overlayfiles/subdir2_file2.txt -- +file 2 +-- overlayfiles/subdir4_this_file_is_overlaid.txt -- +99999999 +-- overlayfiles/child.txt -- +-- overlayfiles/subdir11 -- +11 +-- overlayfiles/parentdeleted_file.txt -- +this can exist because the parent directory is deleted +`) + + testCases := []struct { + path string + wantContents string + isErr bool + }{ + {"subdir1/file1.txt", "file 1\n", false}, + {"subdir2/file2.txt", "file 2\n", false}, + {"subdir3/doesntexist", "", true}, + {"subdir4/this_file_is_overlaid.txt", "99999999\n", false}, + {"subdir5/deleted.txt", "", true}, + {"parentoverwritten/subdir1/subdir2/subdir3/file.txt", "", true}, + {"childoverlay/subdir1.txt", "", true}, + {"subdir11", "11\n", false}, + {"parentdeleted/file.txt", "this can exist because the parent directory is deleted\n", false}, + } + + for _, tc := range testCases { + f, err := Open(tc.path) + if tc.isErr { + if err == nil { + f.Close() + t.Errorf("Open(%q): got no error, but want error", tc.path) + } + continue + } + if err != nil { + t.Errorf("Open(%q): got error %v, want nil", tc.path, err) + continue + } + contents, err := io.ReadAll(f) + if err != nil { + t.Errorf("unexpected error reading contents of file: %v", err) + } + if string(contents) != tc.wantContents { + t.Errorf("contents of file opened with Open(%q): got %q, want %q", + tc.path, contents, tc.wantContents) + } + f.Close() + } +} + +func TestIsDirWithGoFiles(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "goinoverlay/file.go": "dummy", + "directory/removed/by/file": "dummy", + "directory_with_go_dir/dir.go/file.txt": "dummy", + "otherdirectory/deleted.go": "", + "nonexistentdirectory/deleted.go": "", + "textfile.txt/file.go": "dummy" + } +} +-- dummy -- +a destination file for the overlay entries to point to +contents don't matter for this test +-- nogo/file.txt -- +-- goondisk/file.go -- +-- goinoverlay/file.txt -- +-- directory/removed/by/file/in/overlay/file.go -- +-- otherdirectory/deleted.go -- +-- textfile.txt -- +`) + + testCases := []struct { + dir string + want bool + wantErr bool + }{ + {"nogo", false, false}, + {"goondisk", true, false}, + {"goinoverlay", true, false}, + {"directory/removed/by/file/in/overlay", false, false}, + {"directory_with_go_dir", false, false}, + {"otherdirectory", false, false}, + {"nonexistentdirectory", false, false}, + {"textfile.txt", true, false}, + } + + for _, tc := range testCases { + got, gotErr := IsDirWithGoFiles(tc.dir) + if tc.wantErr { + if gotErr == nil { + t.Errorf("IsDirWithGoFiles(%q): got %v, %v; want non-nil error", tc.dir, got, gotErr) + } + continue + } + if gotErr != nil { + t.Errorf("IsDirWithGoFiles(%q): got %v, %v; want nil error", tc.dir, got, gotErr) + } + if got != tc.want { + t.Errorf("IsDirWithGoFiles(%q) = %v; want %v", tc.dir, got, tc.want) + } + } +} + +func TestWalk(t *testing.T) { + // The root of the walk must be a name with an actual basename, not just ".". + // Walk uses Lstat to obtain the name of the root, and Lstat on platforms + // other than Plan 9 reports the name "." instead of the actual base name of + // the directory. (See https://golang.org/issue/42115.) + + type file struct { + path string + name string + size int64 + mode fs.FileMode + isDir bool + } + testCases := []struct { + name string + overlay string + root string + wantFiles []file + }{ + {"no overlay", ` +{} +-- dir/file.txt -- +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0700, true}, + {"dir/file.txt", "file.txt", 0, 0600, false}, + }, + }, + {"overlay with different file", ` +{ + "Replace": { + "dir/file.txt": "dir/other.txt" + } +} +-- dir/file.txt -- +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/file.txt", "file.txt", 23, 0600, false}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + }, + }, + {"overlay with new file", ` +{ + "Replace": { + "dir/file.txt": "dir/other.txt" + } +} +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/file.txt", "file.txt", 23, 0600, false}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + }, + }, + {"overlay with new directory", ` +{ + "Replace": { + "dir/subdir/file.txt": "dir/other.txt" + } +} +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + {"dir/subdir", "subdir", 0, fs.ModeDir | 0500, true}, + {"dir/subdir/file.txt", "file.txt", 23, 0600, false}, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + + var got []file + Walk(tc.root, func(path string, info fs.FileInfo, err error) error { + got = append(got, file{path, info.Name(), info.Size(), info.Mode(), info.IsDir()}) + return nil + }) + + if len(got) != len(tc.wantFiles) { + t.Errorf("Walk: saw %#v in walk; want %#v", got, tc.wantFiles) + } + for i := 0; i < len(got) && i < len(tc.wantFiles); i++ { + wantPath := filepath.FromSlash(tc.wantFiles[i].path) + if got[i].path != wantPath { + t.Errorf("path of file #%v in walk, got %q, want %q", i, got[i].path, wantPath) + } + if got[i].name != tc.wantFiles[i].name { + t.Errorf("name of file #%v in walk, got %q, want %q", i, got[i].name, tc.wantFiles[i].name) + } + if got[i].mode&(fs.ModeDir|0700) != tc.wantFiles[i].mode { + t.Errorf("mode&(fs.ModeDir|0700) for mode of file #%v in walk, got %v, want %v", i, got[i].mode&(fs.ModeDir|0700), tc.wantFiles[i].mode) + } + if got[i].isDir != tc.wantFiles[i].isDir { + t.Errorf("isDir for file #%v in walk, got %v, want %v", i, got[i].isDir, tc.wantFiles[i].isDir) + } + if tc.wantFiles[i].isDir { + continue // don't check size for directories + } + if got[i].size != tc.wantFiles[i].size { + t.Errorf("size of file #%v in walk, got %v, want %v", i, got[i].size, tc.wantFiles[i].size) + } + } + }) + } +} + +func TestWalkSkipDir(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "dir/skip/file.go": "dummy.txt", + "dir/dontskip/file.go": "dummy.txt", + "dir/dontskip/skip/file.go": "dummy.txt" + } +} +-- dummy.txt -- +`) + + var seen []string + Walk("dir", func(path string, info fs.FileInfo, err error) error { + seen = append(seen, filepath.ToSlash(path)) + if info.Name() == "skip" { + return filepath.SkipDir + } + return nil + }) + + wantSeen := []string{"dir", "dir/dontskip", "dir/dontskip/file.go", "dir/dontskip/skip", "dir/skip"} + + if len(seen) != len(wantSeen) { + t.Errorf("paths seen in walk: got %v entries; want %v entries", len(seen), len(wantSeen)) + } + + for i := 0; i < len(seen) && i < len(wantSeen); i++ { + if seen[i] != wantSeen[i] { + t.Errorf("path #%v seen walking tree: want %q, got %q", i, seen[i], wantSeen[i]) + } + } +} + +func TestWalkError(t *testing.T) { + initOverlay(t, "{}") + + alreadyCalled := false + err := Walk("foo", func(path string, info fs.FileInfo, err error) error { + if alreadyCalled { + t.Fatal("expected walk function to be called exactly once, but it was called more than once") + } + alreadyCalled = true + return errors.New("returned from function") + }) + if !alreadyCalled { + t.Fatal("expected walk function to be called exactly once, but it was never called") + + } + if err == nil { + t.Fatalf("Walk: got no error, want error") + } + if err.Error() != "returned from function" { + t.Fatalf("Walk: got error %v, want \"returned from function\" error", err) + } +} + +func TestWalkSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + initOverlay(t, `{ + "Replace": {"overlay_symlink": "symlink"} +} +-- dir/file --`) + + // Create symlink + if err := os.Symlink("dir", "symlink"); err != nil { + t.Error(err) + } + + testCases := []struct { + name string + dir string + wantFiles []string + }{ + {"control", "dir", []string{"dir", "dir" + string(filepath.Separator) + "file"}}, + // ensure Walk doesn't walk into the directory pointed to by the symlink + // (because it's supposed to use Lstat instead of Stat). + {"symlink_to_dir", "symlink", []string{"symlink"}}, + {"overlay_to_symlink_to_dir", "overlay_symlink", []string{"overlay_symlink"}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var got []string + + err := Walk(tc.dir, func(path string, info fs.FileInfo, err error) error { + got = append(got, path) + if err != nil { + t.Errorf("walkfn: got non nil err argument: %v, want nil err argument", err) + } + return nil + }) + if err != nil { + t.Errorf("Walk: got error %q, want nil", err) + } + + if !reflect.DeepEqual(got, tc.wantFiles) { + t.Errorf("files examined by walk: got %v, want %v", got, tc.wantFiles) + } + }) + } + +} + +func TestLstat(t *testing.T) { + type file struct { + name string + size int64 + mode fs.FileMode // mode & (fs.ModeDir|0x700): only check 'user' permissions + isDir bool + } + + testCases := []struct { + name string + overlay string + path string + + want file + wantErr bool + }{ + { + "regular_file", + `{} +-- file.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "new_file_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_replaced_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- file.txt -- +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_cant_exist", + `{"Replace": {"deleted": "dummy.txt"}} +-- deleted/file.txt -- +-- dummy.txt -- +`, + "deleted/file.txt", + file{}, + true, + }, + { + "deleted", + `{"Replace": {"deleted": ""}} +-- deleted -- +`, + "deleted", + file{}, + true, + }, + { + "dir_on_disk", + `{} +-- dir/foo.txt -- +`, + "dir", + file{"dir", 0, 0700 | fs.ModeDir, true}, + false, + }, + { + "dir_in_overlay", + `{"Replace": {"dir/file.txt": "dummy.txt"}} +-- dummy.txt -- +`, + "dir", + file{"dir", 0, 0500 | fs.ModeDir, true}, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + got, err := Lstat(tc.path) + if tc.wantErr { + if err == nil { + t.Errorf("lstat(%q): got no error, want error", tc.path) + } + return + } + if err != nil { + t.Fatalf("lstat(%q): got error %v, want no error", tc.path, err) + } + if got.Name() != tc.want.name { + t.Errorf("lstat(%q).Name(): got %q, want %q", tc.path, got.Name(), tc.want.name) + } + if got.Mode()&(fs.ModeDir|0700) != tc.want.mode { + t.Errorf("lstat(%q).Mode()&(fs.ModeDir|0700): got %v, want %v", tc.path, got.Mode()&(fs.ModeDir|0700), tc.want.mode) + } + if got.IsDir() != tc.want.isDir { + t.Errorf("lstat(%q).IsDir(): got %v, want %v", tc.path, got.IsDir(), tc.want.isDir) + } + if tc.want.isDir { + return // don't check size for directories + } + if got.Size() != tc.want.size { + t.Errorf("lstat(%q).Size(): got %v, want %v", tc.path, got.Size(), tc.want.size) + } + }) + } +} + +func TestStat(t *testing.T) { + testenv.MustHaveSymlink(t) + + type file struct { + name string + size int64 + mode os.FileMode // mode & (os.ModeDir|0x700): only check 'user' permissions + isDir bool + } + + testCases := []struct { + name string + overlay string + path string + + want file + wantErr bool + }{ + { + "regular_file", + `{} +-- file.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "new_file_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_replaced_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- file.txt -- +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_cant_exist", + `{"Replace": {"deleted": "dummy.txt"}} +-- deleted/file.txt -- +-- dummy.txt -- +`, + "deleted/file.txt", + file{}, + true, + }, + { + "deleted", + `{"Replace": {"deleted": ""}} +-- deleted -- +`, + "deleted", + file{}, + true, + }, + { + "dir_on_disk", + `{} +-- dir/foo.txt -- +`, + "dir", + file{"dir", 0, 0700 | os.ModeDir, true}, + false, + }, + { + "dir_in_overlay", + `{"Replace": {"dir/file.txt": "dummy.txt"}} +-- dummy.txt -- +`, + "dir", + file{"dir", 0, 0500 | os.ModeDir, true}, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + got, err := Stat(tc.path) + if tc.wantErr { + if err == nil { + t.Errorf("Stat(%q): got no error, want error", tc.path) + } + return + } + if err != nil { + t.Fatalf("Stat(%q): got error %v, want no error", tc.path, err) + } + if got.Name() != tc.want.name { + t.Errorf("Stat(%q).Name(): got %q, want %q", tc.path, got.Name(), tc.want.name) + } + if got.Mode()&(os.ModeDir|0700) != tc.want.mode { + t.Errorf("Stat(%q).Mode()&(os.ModeDir|0700): got %v, want %v", tc.path, got.Mode()&(os.ModeDir|0700), tc.want.mode) + } + if got.IsDir() != tc.want.isDir { + t.Errorf("Stat(%q).IsDir(): got %v, want %v", tc.path, got.IsDir(), tc.want.isDir) + } + if tc.want.isDir { + return // don't check size for directories + } + if got.Size() != tc.want.size { + t.Errorf("Stat(%q).Size(): got %v, want %v", tc.path, got.Size(), tc.want.size) + } + }) + } +} + +func TestStatSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + initOverlay(t, `{ + "Replace": {"file.go": "symlink"} +} +-- to.go -- +0123456789 +`) + + // Create symlink + if err := os.Symlink("to.go", "symlink"); err != nil { + t.Error(err) + } + + f := "file.go" + fi, err := Stat(f) + if err != nil { + t.Errorf("Stat(%q): got error %q, want nil error", f, err) + } + + if !fi.Mode().IsRegular() { + t.Errorf("Stat(%q).Mode(): got %v, want regular mode", f, fi.Mode()) + } + + if fi.Size() != 11 { + t.Errorf("Stat(%q).Size(): got %v, want 11", f, fi.Size()) + } +} diff --git a/src/cmd/go/internal/generate/generate.go b/src/cmd/go/internal/generate/generate.go index 98c17bba8c..c7401948b8 100644 --- a/src/cmd/go/internal/generate/generate.go +++ b/src/cmd/go/internal/generate/generate.go @@ -13,7 +13,6 @@ import ( "go/parser" "go/token" "io" - "io/ioutil" "log" "os" "os/exec" @@ -201,7 +200,7 @@ func runGenerate(ctx context.Context, cmd *base.Command, args []string) { // generate runs the generation directives for a single file. func generate(absFile string) bool { - src, err := ioutil.ReadFile(absFile) + src, err := os.ReadFile(absFile) if err != nil { log.Fatalf("generate: %s", err) } diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go index d0be3fe1e7..268962eca8 100644 --- a/src/cmd/go/internal/get/get.go +++ b/src/cmd/go/internal/get/get.go @@ -18,6 +18,7 @@ import ( "cmd/go/internal/load" "cmd/go/internal/search" "cmd/go/internal/str" + "cmd/go/internal/vcs" "cmd/go/internal/web" "cmd/go/internal/work" @@ -43,10 +44,11 @@ The -fix flag instructs get to run the fix tool on the downloaded packages before resolving dependencies or building the code. The -insecure flag permits fetching from repositories and resolving -custom domains using insecure schemes such as HTTP. Use with caution. The -GOINSECURE environment variable is usually a better alternative, since it -provides control over which modules may be retrieved using an insecure scheme. -See 'go help environment' for details. +custom domains using insecure schemes such as HTTP. Use with caution. +This flag is deprecated and will be removed in a future version of go. +The GOINSECURE environment variable should be used instead, since it +provides control over which packages may be retrieved using an insecure +scheme. See 'go help environment' for details. The -t flag instructs get to also download the packages required to build the tests for the specified packages. @@ -108,14 +110,12 @@ var ( getT = CmdGet.Flag.Bool("t", false, "") getU = CmdGet.Flag.Bool("u", false, "") getFix = CmdGet.Flag.Bool("fix", false, "") - - Insecure bool ) func init() { work.AddBuildFlags(CmdGet, work.OmitModFlag|work.OmitModCommonFlags) CmdGet.Run = runGet // break init loop - CmdGet.Flag.BoolVar(&Insecure, "insecure", Insecure, "") + CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "") } func runGet(ctx context.Context, cmd *base.Command, args []string) { @@ -129,6 +129,9 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) { if *getF && !*getU { base.Fatalf("go get: cannot use -f flag without -u") } + if cfg.Insecure { + fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n") + } // Disable any prompting for passwords by Git. // Only has an effect for 2.3.0 or later, but avoiding @@ -408,7 +411,7 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) // to make the first copy of or update a copy of the given package. func downloadPackage(p *load.Package) error { var ( - vcs *vcsCmd + vcsCmd *vcs.Cmd repo, rootPath string err error blindRepo bool // set if the repo has unusual configuration @@ -431,22 +434,22 @@ func downloadPackage(p *load.Package) error { return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err) } security := web.SecureOnly - if Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, importPrefix) { + if cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, importPrefix) { security = web.Insecure } if p.Internal.Build.SrcRoot != "" { // Directory exists. Look for checkout along path to src. - vcs, rootPath, err = vcsFromDir(p.Dir, p.Internal.Build.SrcRoot) + vcsCmd, rootPath, err = vcs.FromDir(p.Dir, p.Internal.Build.SrcRoot) if err != nil { return err } repo = "<local>" // should be unused; make distinctive // Double-check where it came from. - if *getU && vcs.remoteRepo != nil { + if *getU && vcsCmd.RemoteRepo != nil { dir := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath)) - remote, err := vcs.remoteRepo(vcs, dir) + remote, err := vcsCmd.RemoteRepo(vcsCmd, dir) if err != nil { // Proceed anyway. The package is present; we likely just don't understand // the repo configuration (e.g. unusual remote protocol). @@ -454,10 +457,10 @@ func downloadPackage(p *load.Package) error { } repo = remote if !*getF && err == nil { - if rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security); err == nil { + if rr, err := vcs.RepoRootForImportPath(importPrefix, vcs.IgnoreMod, security); err == nil { repo := rr.Repo - if rr.vcs.resolveRepo != nil { - resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo) + if rr.VCS.ResolveRepo != nil { + resolved, err := rr.VCS.ResolveRepo(rr.VCS, dir, repo) if err == nil { repo = resolved } @@ -471,13 +474,13 @@ func downloadPackage(p *load.Package) error { } else { // Analyze the import path to determine the version control system, // repository, and the import path for the root of the repository. - rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security) + rr, err := vcs.RepoRootForImportPath(importPrefix, vcs.IgnoreMod, security) if err != nil { return err } - vcs, repo, rootPath = rr.vcs, rr.Repo, rr.Root + vcsCmd, repo, rootPath = rr.VCS, rr.Repo, rr.Root } - if !blindRepo && !vcs.isSecure(repo) && security != web.Insecure { + if !blindRepo && !vcsCmd.IsSecure(repo) && security != web.Insecure { return fmt.Errorf("cannot download, %v uses insecure protocol", repo) } @@ -500,7 +503,7 @@ func downloadPackage(p *load.Package) error { } root := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath)) - if err := checkNestedVCS(vcs, root, p.Internal.Build.SrcRoot); err != nil { + if err := vcs.CheckNested(vcsCmd, root, p.Internal.Build.SrcRoot); err != nil { return err } @@ -516,7 +519,7 @@ func downloadPackage(p *load.Package) error { // Check that this is an appropriate place for the repo to be checked out. // The target directory must either not exist or have a repo checked out already. - meta := filepath.Join(root, "."+vcs.cmd) + meta := filepath.Join(root, "."+vcsCmd.Cmd) if _, err := os.Stat(meta); err != nil { // Metadata file or directory does not exist. Prepare to checkout new copy. // Some version control tools require the target directory not to exist. @@ -537,12 +540,12 @@ func downloadPackage(p *load.Package) error { fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.Internal.Build.Root) } - if err = vcs.create(root, repo); err != nil { + if err = vcsCmd.Create(root, repo); err != nil { return err } } else { // Metadata directory does exist; download incremental updates. - if err = vcs.download(root); err != nil { + if err = vcsCmd.Download(root); err != nil { return err } } @@ -551,12 +554,12 @@ func downloadPackage(p *load.Package) error { // Do not show tag sync in -n; it's noise more than anything, // and since we're not running commands, no tag will be found. // But avoid printing nothing. - fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd) + fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcsCmd.Cmd) return nil } // Select and sync to appropriate version of the repository. - tags, err := vcs.tags(root) + tags, err := vcsCmd.Tags(root) if err != nil { return err } @@ -564,7 +567,7 @@ func downloadPackage(p *load.Package) error { if i := strings.Index(vers, " "); i >= 0 { vers = vers[:i] } - if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil { + if err := vcsCmd.TagSync(root, selectTag(vers, tags)); err != nil { return err } diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go index e1f0521ea4..98f58441b4 100644 --- a/src/cmd/go/internal/help/helpdoc.go +++ b/src/cmd/go/internal/help/helpdoc.go @@ -526,7 +526,7 @@ General-purpose environment variables: Comma-separated list of glob patterns (in the syntax of Go's path.Match) of module path prefixes that should always be fetched directly or that should not be compared against the checksum database. - See 'go help module-private'. + See 'go help private'. GOROOT The root of the go tree. GOSUMDB @@ -582,8 +582,8 @@ Architecture-specific environment variables: For GOARCH=arm, the ARM architecture for which to compile. Valid values are 5, 6, 7. GO386 - For GOARCH=386, the floating point instruction set. - Valid values are 387, sse2. + For GOARCH=386, how to implement floating point instructions. + Valid values are sse2 (default), softfloat. GOMIPS For GOARCH=mips{,le}, whether to use floating point instructions. Valid values are hardfloat (default), softfloat. @@ -632,6 +632,8 @@ Additional information available from 'go env' but not read from the environment If module-aware mode is disabled, GOMOD will be the empty string. GOTOOLDIR The directory where the go tools (compile, cover, doc, etc...) are installed. + GOVERSION + The version of the installed Go tree, as reported by runtime.Version. `, } @@ -838,6 +840,9 @@ in addition to android tags and files. Using GOOS=illumos matches build tags and files as for GOOS=solaris in addition to illumos tags and files. +Using GOOS=ios matches build tags and files as for GOOS=darwin +in addition to ios tags and files. + To keep a file from being considered for the build: // +build ignore diff --git a/src/cmd/go/internal/imports/build.go b/src/cmd/go/internal/imports/build.go index eb070eef4c..50aeabc578 100644 --- a/src/cmd/go/internal/imports/build.go +++ b/src/cmd/go/internal/imports/build.go @@ -141,6 +141,9 @@ func matchTag(name string, tags map[string]bool, want bool) bool { if name == "solaris" { have = have || tags["illumos"] } + if name == "darwin" { + have = have || tags["ios"] + } return have == want } @@ -158,6 +161,7 @@ func matchTag(name string, tags map[string]bool, want bool) bool { // Exceptions: // if GOOS=android, then files with GOOS=linux are also matched. // if GOOS=illumos, then files with GOOS=solaris are also matched. +// if GOOS=ios, then files with GOOS=darwin are also matched. // // If tags["*"] is true, then MatchFile will consider all possible // GOOS and GOARCH to be available and will consequently @@ -208,6 +212,7 @@ var KnownOS = map[string]bool{ "freebsd": true, "hurd": true, "illumos": true, + "ios": true, "js": true, "linux": true, "nacl": true, // legacy; don't remove diff --git a/src/cmd/go/internal/imports/read.go b/src/cmd/go/internal/imports/read.go index 58c2abdc29..5e270781d7 100644 --- a/src/cmd/go/internal/imports/read.go +++ b/src/cmd/go/internal/imports/read.go @@ -198,7 +198,7 @@ func (r *importReader) readImport(imports *[]string) { r.readString(imports) } -// ReadComments is like ioutil.ReadAll, except that it only reads the leading +// ReadComments is like io.ReadAll, except that it only reads the leading // block of comments in the file. func ReadComments(f io.Reader) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} @@ -210,7 +210,7 @@ func ReadComments(f io.Reader) ([]byte, error) { return r.buf, r.err } -// ReadImports is like ioutil.ReadAll, except that it expects a Go file as input +// ReadImports is like io.ReadAll, except that it expects a Go file as input // and stops reading the input once the imports have completed. func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} diff --git a/src/cmd/go/internal/imports/scan.go b/src/cmd/go/internal/imports/scan.go index 3d9b6132b1..ee11a8708b 100644 --- a/src/cmd/go/internal/imports/scan.go +++ b/src/cmd/go/internal/imports/scan.go @@ -6,16 +6,17 @@ package imports import ( "fmt" - "io/ioutil" - "os" + "io/fs" "path/filepath" "sort" "strconv" "strings" + + "cmd/go/internal/fsys" ) func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { - infos, err := ioutil.ReadDir(dir) + infos, err := fsys.ReadDir(dir) if err != nil { return nil, nil, err } @@ -25,14 +26,14 @@ func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { // If the directory entry is a symlink, stat it to obtain the info for the // link target instead of the link itself. - if info.Mode()&os.ModeSymlink != 0 { - info, err = os.Stat(filepath.Join(dir, name)) + if info.Mode()&fs.ModeSymlink != 0 { + info, err = fsys.Stat(filepath.Join(dir, name)) if err != nil { continue // Ignore broken symlinks. } } - if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { + if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { files = append(files, filepath.Join(dir, name)) } } @@ -49,7 +50,7 @@ func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]stri numFiles := 0 Files: for _, name := range files { - r, err := os.Open(name) + r, err := fsys.Open(name) if err != nil { return nil, nil, err } diff --git a/src/cmd/go/internal/imports/scan_test.go b/src/cmd/go/internal/imports/scan_test.go index e424656cae..2d245ee787 100644 --- a/src/cmd/go/internal/imports/scan_test.go +++ b/src/cmd/go/internal/imports/scan_test.go @@ -7,7 +7,7 @@ package imports import ( "bytes" "internal/testenv" - "io/ioutil" + "os" "path" "path/filepath" "runtime" @@ -57,7 +57,7 @@ func TestScan(t *testing.T) { func TestScanDir(t *testing.T) { testenv.MustHaveGoBuild(t) - dirs, err := ioutil.ReadDir("testdata") + dirs, err := os.ReadDir("testdata") if err != nil { t.Fatal(err) } @@ -66,7 +66,7 @@ func TestScanDir(t *testing.T) { continue } t.Run(dir.Name(), func(t *testing.T) { - tagsData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt")) + tagsData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt")) if err != nil { t.Fatalf("error reading tags: %v", err) } @@ -75,7 +75,7 @@ func TestScanDir(t *testing.T) { tags[t] = true } - wantData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt")) + wantData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt")) if err != nil { t.Fatalf("error reading want: %v", err) } diff --git a/src/cmd/go/internal/imports/tags.go b/src/cmd/go/internal/imports/tags.go index 14b4e21a02..01b448b914 100644 --- a/src/cmd/go/internal/imports/tags.go +++ b/src/cmd/go/internal/imports/tags.go @@ -4,17 +4,23 @@ package imports -import "cmd/go/internal/cfg" +import ( + "cmd/go/internal/cfg" + "sync" +) -var tags map[string]bool +var ( + tags map[string]bool + tagsOnce sync.Once +) // Tags returns a set of build tags that are true for the target platform. // It includes GOOS, GOARCH, the compiler, possibly "cgo", // release tags like "go1.13", and user-specified build tags. func Tags() map[string]bool { - if tags == nil { + tagsOnce.Do(func() { tags = loadTags() - } + }) return tags } @@ -36,14 +42,17 @@ func loadTags() map[string]bool { return tags } -var anyTags map[string]bool +var ( + anyTags map[string]bool + anyTagsOnce sync.Once +) // AnyTags returns a special set of build tags that satisfy nearly all // build tag expressions. Only "ignore" and malformed build tag requirements // are considered false. func AnyTags() map[string]bool { - if anyTags == nil { + anyTagsOnce.Do(func() { anyTags = map[string]bool{"*": true} - } + }) return anyTags } diff --git a/src/cmd/go/internal/imports/testdata/android/.h.go b/src/cmd/go/internal/imports/testdata/android/.h.go new file mode 100644 index 0000000000..53c529e777 --- /dev/null +++ b/src/cmd/go/internal/imports/testdata/android/.h.go @@ -0,0 +1,3 @@ +package android + +import _ "h" diff --git a/src/cmd/go/internal/imports/testdata/illumos/.h.go b/src/cmd/go/internal/imports/testdata/illumos/.h.go new file mode 100644 index 0000000000..53c529e777 --- /dev/null +++ b/src/cmd/go/internal/imports/testdata/illumos/.h.go @@ -0,0 +1,3 @@ +package android + +import _ "h" diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go index 6d81c1cad1..9af9dbb856 100644 --- a/src/cmd/go/internal/list/list.go +++ b/src/cmd/go/internal/list/list.go @@ -66,26 +66,28 @@ to -f '{{.ImportPath}}'. The struct being passed to the template is: BinaryOnly bool // binary-only package (no longer supported) ForTest string // package is only for use in named test Export string // file containing export data (when using -export) + BuildID string // build ID of the compiled package (when using -export) Module *Module // info about package's containing module, if any (can be nil) Match []string // command-line patterns matching this package DepOnly bool // package is only a dependency, not explicitly listed // Source files - GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string // .go source files that import "C" - CompiledGoFiles []string // .go files presented to compiler (when using -compiled) - IgnoredGoFiles []string // .go source files ignored due to build constraints - CFiles []string // .c source files - CXXFiles []string // .cc, .cxx and .cpp source files - MFiles []string // .m source files - HFiles []string // .h, .hh, .hpp and .hxx source files - FFiles []string // .f, .F, .for and .f90 Fortran source files - SFiles []string // .s source files - SwigFiles []string // .swig files - SwigCXXFiles []string // .swigcxx files - SysoFiles []string // .syso object files to add to archive - TestGoFiles []string // _test.go files in package - XTestGoFiles []string // _test.go files outside package + GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string // .go source files that import "C" + CompiledGoFiles []string // .go files presented to compiler (when using -compiled) + IgnoredGoFiles []string // .go source files ignored due to build constraints + IgnoredOtherFiles []string // non-.go source files ignored due to build constraints + CFiles []string // .c source files + CXXFiles []string // .cc, .cxx and .cpp source files + MFiles []string // .m source files + HFiles []string // .h, .hh, .hpp and .hxx source files + FFiles []string // .f, .F, .for and .f90 Fortran source files + SFiles []string // .s source files + SwigFiles []string // .swig files + SwigCXXFiles []string // .swigcxx files + SysoFiles []string // .syso object files to add to archive + TestGoFiles []string // _test.go files in package + XTestGoFiles []string // _test.go files outside package // Cgo directives CgoCFLAGS []string // cgo: flags for C compiler @@ -325,7 +327,7 @@ var ( var nl = []byte{'\n'} func runList(ctx context.Context, cmd *base.Command, args []string) { - modload.LoadTests = *listTest + load.ModResolveTests = *listTest work.BuildInit() out := newTrackingWriter(os.Stdout) defer out.w.Flush() @@ -413,7 +415,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { base.Fatalf("go list -m: not using modules") } - modload.InitMod(ctx) // Parses go.mod and sets cfg.BuildMod. + modload.LoadModFile(ctx) // Parses go.mod and sets cfg.BuildMod. if cfg.BuildMod == "vendor" { const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)" @@ -437,8 +439,6 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { } } - modload.LoadBuildList(ctx) - mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted) if !*listE { for _, m := range mods { @@ -545,7 +545,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { // Note that -deps is applied after -test, // so that you only get descriptions of tests for the things named // explicitly on the command line, not for all dependencies. - pkgs = load.PackageList(pkgs) + pkgs = loadPackageList(pkgs) } // Do we need to run a build to gather information? @@ -570,6 +570,8 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { // Show vendor-expanded paths in listing p.TestImports = p.Resolve(p.TestImports) p.XTestImports = p.Resolve(p.XTestImports) + p.TestEmbedFiles = p.ResolveEmbed(p.TestEmbedPatterns) + p.XTestEmbedFiles = p.ResolveEmbed(p.XTestEmbedPatterns) p.DepOnly = !cmdline[p] if *listCompiled { @@ -580,7 +582,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { if *listTest { all := pkgs if !*listDeps { - all = load.PackageList(pkgs) + all = loadPackageList(pkgs) } // Update import paths to distinguish the real package p // from p recompiled for q.test. @@ -697,6 +699,23 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { } } +// loadPackageList is like load.PackageList, but prints error messages and exits +// with nonzero status if listE is not set and any package in the expanded list +// has errors. +func loadPackageList(roots []*load.Package) []*load.Package { + pkgs := load.PackageList(roots) + + if !*listE { + for _, pkg := range pkgs { + if pkg.Error != nil { + base.Errorf("%v", pkg.Error) + } + } + } + + return pkgs +} + // TrackingWriter tracks the last byte written on every write so // we can avoid printing a newline if one was already written or // if there is no output at all. diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 71fd9b5538..6f95af4f7e 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -14,8 +14,9 @@ import ( "go/build" "go/scanner" "go/token" - "io/ioutil" + "io/fs" "os" + "path" pathpkg "path" "path/filepath" "runtime" @@ -27,26 +28,14 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/modinfo" + "cmd/go/internal/modload" "cmd/go/internal/par" "cmd/go/internal/search" "cmd/go/internal/str" "cmd/go/internal/trace" -) - -var ( - // module initialization hook; never nil, no-op if module use is disabled - ModInit func() - - // module hooks; nil if module use is disabled - ModBinDir func() string // return effective bin directory - ModLookup func(parentPath string, parentIsStd bool, path string) (dir, realPath string, err error) // lookup effective meaning of import - ModPackageModuleInfo func(path string) *modinfo.ModulePublic // return module info for Package struct - ModImportPaths func(ctx context.Context, args []string) []*search.Match // expand import paths - ModPackageBuildInfo func(main string, deps []string) string // return module info to embed in binary - ModInfoProg func(info string, isgccgo bool) []byte // wrap module info in .go code for binary - ModImportFromFiles func(context.Context, []string) // update go.mod to add modules for imports in these files - ModDirImportPath func(string) string // return effective import path for directory + "cmd/internal/sys" ) var IgnoreImports bool // control whether we ignore imports in packages @@ -72,6 +61,7 @@ type PackagePublic struct { ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory ForTest string `json:",omitempty"` // package is only for use in named test Export string `json:",omitempty"` // file containing export data (set by go list -export) + BuildID string `json:",omitempty"` // build ID of the compiled package (set by go list -export) Module *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any Match []string `json:",omitempty"` // command-line patterns matching this package Goroot bool `json:",omitempty"` // is this package found in the Go root? @@ -89,19 +79,24 @@ type PackagePublic struct { // Source files // If you add to this list you MUST add to p.AllFiles (below) too. // Otherwise file name security lists will not apply to any new additions. - GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string `json:",omitempty"` // .go source files that import "C" - CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles - IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints - CFiles []string `json:",omitempty"` // .c source files - CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files - MFiles []string `json:",omitempty"` // .m source files - HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files - FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files - SFiles []string `json:",omitempty"` // .s source files - SwigFiles []string `json:",omitempty"` // .swig files - SwigCXXFiles []string `json:",omitempty"` // .swigcxx files - SysoFiles []string `json:",omitempty"` // .syso system object files added to package + GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string `json:",omitempty"` // .go source files that import "C" + CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles + IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints + IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints + CFiles []string `json:",omitempty"` // .c source files + CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files + MFiles []string `json:",omitempty"` // .m source files + HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files + FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files + SFiles []string `json:",omitempty"` // .s source files + SwigFiles []string `json:",omitempty"` // .swig files + SwigCXXFiles []string `json:",omitempty"` // .swigcxx files + SysoFiles []string `json:",omitempty"` // .syso system object files added to package + + // Embedded files + EmbedPatterns []string `json:",omitempty"` // //go:embed patterns + EmbedFiles []string `json:",omitempty"` // files and directories matched by EmbedPatterns // Cgo directives CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler @@ -124,10 +119,14 @@ type PackagePublic struct { // Test information // If you add to this list you MUST add to p.AllFiles (below) too. // Otherwise file name security lists will not apply to any new additions. - TestGoFiles []string `json:",omitempty"` // _test.go files in package - TestImports []string `json:",omitempty"` // imports from TestGoFiles - XTestGoFiles []string `json:",omitempty"` // _test.go files outside package - XTestImports []string `json:",omitempty"` // imports from XTestGoFiles + TestGoFiles []string `json:",omitempty"` // _test.go files in package + TestImports []string `json:",omitempty"` // imports from TestGoFiles + TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns + TestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns + XTestGoFiles []string `json:",omitempty"` // _test.go files outside package + XTestImports []string `json:",omitempty"` // imports from XTestGoFiles + XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns + XTestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns } // AllFiles returns the names of all the files considered for the package. @@ -136,11 +135,12 @@ type PackagePublic struct { // The go/build package filtered others out (like foo_wrongGOARCH.s) // and that's OK. func (p *Package) AllFiles() []string { - return str.StringList( + files := str.StringList( p.GoFiles, p.CgoFiles, // no p.CompiledGoFiles, because they are from GoFiles or generated by us p.IgnoredGoFiles, + p.IgnoredOtherFiles, p.CFiles, p.CXXFiles, p.MFiles, @@ -153,6 +153,27 @@ func (p *Package) AllFiles() []string { p.TestGoFiles, p.XTestGoFiles, ) + + // EmbedFiles may overlap with the other files. + // Dedup, but delay building the map as long as possible. + // Only files in the current directory (no slash in name) + // need to be checked against the files variable above. + var have map[string]bool + for _, file := range p.EmbedFiles { + if !strings.Contains(file, "/") { + if have == nil { + have = make(map[string]bool) + for _, file := range files { + have[file] = true + } + } + if have[file] { + continue + } + } + files = append(files, file) + } + return files } // Desc returns the package "description", for use in b.showOutput. @@ -182,6 +203,7 @@ type PackageInternal struct { GobinSubdir bool // install target would be subdir of GOBIN BuildInfo string // add this info to package main TestmainGo *[]byte // content for _testmain.go + Embed map[string][]string // //go:embed comment mapping Asmflags []string // -asmflags for this package Gcflags []string // -gcflags for this package @@ -199,7 +221,7 @@ type NoGoError struct { } func (e *NoGoError) Error() string { - if len(e.Package.constraintIgnoredGoFiles()) > 0 { + if len(e.Package.IgnoredGoFiles) > 0 { // Go files exist, but they were ignored due to build constraints. return "build constraints exclude all Go files in " + e.Package.Dir } @@ -262,8 +284,8 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta // package's source files themselves (scanner errors). // // TODO(matloob): Perhaps make each of those the errors in the first group - // (including modload.ImportMissingError, and the corresponding - // "cannot find package %q in any of" GOPATH-mode error + // (including modload.ImportMissingError, ImportMissingSumError, and the + // corresponding "cannot find package %q in any of" GOPATH-mode error // produced in build.(*Context).Import; modload.AmbiguousImportError, // and modload.PackageNotInModuleError; and the malformed module path errors // produced in golang.org/x/mod/module.CheckMod) implement an interface @@ -344,6 +366,7 @@ func (p *Package) copyBuild(pp *build.Package) { p.GoFiles = pp.GoFiles p.CgoFiles = pp.CgoFiles p.IgnoredGoFiles = pp.IgnoredGoFiles + p.IgnoredOtherFiles = pp.IgnoredOtherFiles p.CFiles = pp.CFiles p.CXXFiles = pp.CXXFiles p.MFiles = pp.MFiles @@ -373,6 +396,9 @@ func (p *Package) copyBuild(pp *build.Package) { p.TestImports = nil p.XTestImports = nil } + p.EmbedPatterns = pp.EmbedPatterns + p.TestEmbedPatterns = pp.TestEmbedPatterns + p.XTestEmbedPatterns = pp.XTestEmbedPatterns } // A PackageError describes an error loading information about a package. @@ -434,13 +460,17 @@ type ImportPathError interface { ImportPath() string } +var ( + _ ImportPathError = (*importError)(nil) + _ ImportPathError = (*modload.ImportMissingError)(nil) + _ ImportPathError = (*modload.ImportMissingSumError)(nil) +) + type importError struct { importPath string err error // created with fmt.Errorf } -var _ ImportPathError = (*importError)(nil) - func ImportErrorf(path, format string, args ...interface{}) ImportPathError { err := &importError{importPath: path, err: fmt.Errorf(format, args...)} if errStr := err.Error(); !strings.Contains(errStr, path) { @@ -753,7 +783,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd // For vendored imports, it is the expanded form. // // Note that when modules are enabled, local import paths are normally - // canonicalized by modload.ImportPaths before now. However, if there's an + // canonicalized by modload.LoadPackages before now. However, if there's an // error resolving a local path, it will be returned untransformed // so that 'go list -e' reports something useful. importKey := importSpec{ @@ -770,7 +800,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd r.dir = filepath.Join(parentDir, path) r.path = dirToImportPath(r.dir) } else if cfg.ModulesEnabled { - r.dir, r.path, r.err = ModLookup(parentPath, parentIsStd, path) + r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path) } else if mode&ResolveImport != 0 { // We do our own path resolution, because we want to // find out the key to use in packageCache without the @@ -801,7 +831,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd } data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode) if data.p.Root == "" && cfg.ModulesEnabled { - if info := ModPackageModuleInfo(path); info != nil { + if info := modload.PackageModuleInfo(path); info != nil { data.p.Root = info.Dir } } @@ -827,7 +857,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd if cfg.GOBIN != "" { data.p.BinDir = cfg.GOBIN } else if cfg.ModulesEnabled { - data.p.BinDir = ModBinDir() + data.p.BinDir = modload.BinDir() } } @@ -895,8 +925,8 @@ var preloadWorkerCount = runtime.GOMAXPROCS(0) // to ensure preload goroutines are no longer active. This is necessary // because of global mutable state that cannot safely be read and written // concurrently. In particular, packageDataCache may be cleared by "go get" -// in GOPATH mode, and modload.loaded (accessed via ModLookup) may be -// modified by modload.ImportPaths (ModImportPaths). +// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be +// modified by modload.LoadPackages. type preload struct { cancel chan struct{} sema chan struct{} @@ -963,6 +993,12 @@ func (pre *preload) preloadImports(imports []string, parent *build.Package) { // loadPackageData have completed. The preloader will not make any new calls // to loadPackageData. func (pre *preload) flush() { + // flush is usually deferred. + // Don't hang program waiting for workers on panic. + if v := recover(); v != nil { + panic(v) + } + close(pre.cancel) for i := 0; i < preloadWorkerCount; i++ { pre.sema <- struct{}{} @@ -982,7 +1018,7 @@ var isDirCache par.Cache func isDir(path string) bool { return isDirCache.Do(path, func() interface{} { - fi, err := os.Stat(path) + fi, err := fsys.Stat(path) return err == nil && fi.IsDir() }).(bool) } @@ -1006,7 +1042,7 @@ func ResolveImportPath(parent *Package, path string) (found string) { func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) { if cfg.ModulesEnabled { - if _, p, e := ModLookup(parentPath, parentIsStd, path); e == nil { + if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil { return p } return path @@ -1110,7 +1146,7 @@ var ( // goModPath returns the module path in the go.mod in dir, if any. func goModPath(dir string) (path string) { return goModPathCache.Do(dir, func() interface{} { - data, err := ioutil.ReadFile(filepath.Join(dir, "go.mod")) + data, err := os.ReadFile(filepath.Join(dir, "go.mod")) if err != nil { return "" } @@ -1259,9 +1295,9 @@ HaveGoMod: // Otherwise it is not possible to vendor just a/b/c and still import the // non-vendored a/b. See golang.org/issue/13832. func hasGoFiles(dir string) bool { - fis, _ := ioutil.ReadDir(dir) - for _, fi := range fis { - if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") { + files, _ := os.ReadDir(dir) + for _, f := range files { + if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") { return true } } @@ -1369,7 +1405,7 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * // directory containing them. // If the directory is outside the main module, this will resolve to ".", // which is not a prefix of any valid module. - importerPath = ModDirImportPath(importer.Dir) + importerPath = modload.DirImportPath(importer.Dir) } parentOfInternal := p.ImportPath[:i] if str.HasPathPrefix(importerPath, parentOfInternal) { @@ -1627,6 +1663,11 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor p.setLoadPackageDataError(err, path, stk, importPos) } + p.EmbedFiles, p.Internal.Embed, err = p.resolveEmbed(p.EmbedPatterns) + if err != nil { + setError(err) + } + useBindir := p.Name == "main" if !p.Standard { switch cfg.BuildBuildmode { @@ -1652,7 +1693,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor elem = full } if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled { - p.Internal.Build.BinDir = ModBinDir() + p.Internal.Build.BinDir = modload.BinDir() } if p.Internal.Build.BinDir != "" { // Install to GOBIN or bin of GOPATH entry. @@ -1686,7 +1727,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor // not work for any package that lacks a Target — such as a non-main // package in module mode. We should probably fix that. shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname" - shlib, err := ioutil.ReadFile(shlibnamefile) + shlib, err := os.ReadFile(shlibnamefile) if err != nil && !os.IsNotExist(err) { base.Fatalf("reading shlibname: %v", err) } @@ -1861,13 +1902,169 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor if p.Internal.CmdlineFiles { mainPath = "command-line-arguments" } - p.Module = ModPackageModuleInfo(mainPath) + p.Module = modload.PackageModuleInfo(mainPath) if p.Name == "main" && len(p.DepsErrors) == 0 { - p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps) + p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps) } } } +// ResolveEmbed resolves //go:embed patterns and returns only the file list. +// For use by go list to compute p.TestEmbedFiles and p.XTestEmbedFiles. +func (p *Package) ResolveEmbed(patterns []string) []string { + files, _, _ := p.resolveEmbed(patterns) + return files +} + +// resolveEmbed resolves //go:embed patterns to precise file lists. +// It sets files to the list of unique files matched (for go list), +// and it sets pmap to the more precise mapping from +// patterns to files. +// TODO(rsc): All these messages need position information for better error reports. +func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[string][]string, err error) { + pmap = make(map[string][]string) + have := make(map[string]int) + dirOK := make(map[string]bool) + pid := 0 // pattern ID, to allow reuse of have map + for _, pattern := range patterns { + pid++ + + // Check pattern is valid for //go:embed. + if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) { + return nil, nil, fmt.Errorf("pattern %s: invalid pattern syntax", pattern) + } + + // Glob to find matches. + match, err := fsys.Glob(p.Dir + string(filepath.Separator) + filepath.FromSlash(pattern)) + if err != nil { + return nil, nil, fmt.Errorf("pattern %s: %v", pattern, err) + } + + // Filter list of matches down to the ones that will still exist when + // the directory is packaged up as a module. (If p.Dir is in the module cache, + // only those files exist already, but if p.Dir is in the current module, + // then there may be other things lying around, like symbolic links or .git directories.) + var list []string + for _, file := range match { + rel := filepath.ToSlash(file[len(p.Dir)+1:]) // file, relative to p.Dir + + what := "file" + info, err := fsys.Lstat(file) + if err != nil { + return nil, nil, err + } + if info.IsDir() { + what = "directory" + } + + // Check that directories along path do not begin a new module + // (do not contain a go.mod). + for dir := file; len(dir) > len(p.Dir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) { + if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in different module", pattern, what, rel) + } + if dir != file { + if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in non-directory %s", pattern, what, rel, dir[len(p.Dir)+1:]) + } + } + dirOK[dir] = true + if elem := filepath.Base(dir); isBadEmbedName(elem) { + if dir == file { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: invalid name %s", pattern, what, rel, elem) + } else { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in invalid directory %s", pattern, what, rel, elem) + } + } + } + + switch { + default: + return nil, nil, fmt.Errorf("pattern %s: cannot embed irregular file %s", pattern, rel) + + case info.Mode().IsRegular(): + if have[rel] != pid { + have[rel] = pid + list = append(list, rel) + } + + case info.IsDir(): + // Gather all files in the named directory, stopping at module boundaries + // and ignoring files that wouldn't be packaged into a module. + count := 0 + err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + rel := filepath.ToSlash(path[len(p.Dir)+1:]) + name := info.Name() + if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') { + // Ignore bad names, assuming they won't go into modules. + // Also avoid hidden files that user may not know about. + // See golang.org/issue/42328. + if info.IsDir() { + return fs.SkipDir + } + return nil + } + if info.IsDir() { + if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil { + return filepath.SkipDir + } + return nil + } + if !info.Mode().IsRegular() { + return nil + } + count++ + if have[rel] != pid { + have[rel] = pid + list = append(list, rel) + } + return nil + }) + if err != nil { + return nil, nil, err + } + if count == 0 { + return nil, nil, fmt.Errorf("pattern %s: cannot embed directory %s: contains no embeddable files", pattern, rel) + } + } + } + + if len(list) == 0 { + return nil, nil, fmt.Errorf("pattern %s: no matching files found", pattern) + } + sort.Strings(list) + pmap[pattern] = list + } + + for file := range have { + files = append(files, file) + } + sort.Strings(files) + return files, pmap, nil +} + +func validEmbedPattern(pattern string) bool { + return pattern != "." && fs.ValidPath(pattern) +} + +// isBadEmbedName reports whether name is the base name of a file that +// can't or won't be included in modules and therefore shouldn't be treated +// as existing for embedding. +func isBadEmbedName(name string) bool { + switch name { + // Empty string should be impossible but make it bad. + case "": + return true + // Version control directories won't be present in module. + case ".bzr", ".hg", ".git", ".svn": + return true + } + return false +} + // collectDeps populates p.Deps and p.DepsErrors by iterating over // p.Internal.Imports. // @@ -1955,37 +2152,40 @@ func LinkerDeps(p *Package) []string { // externalLinkingForced reports whether external linking is being // forced even for programs that do not use cgo. func externalLinkingForced(p *Package) bool { + if !cfg.BuildContext.CgoEnabled { + return false + } + // Some targets must use external linking even inside GOROOT. switch cfg.BuildContext.GOOS { case "android": if cfg.BuildContext.GOARCH != "arm64" { return true } - case "darwin": - if cfg.BuildContext.GOARCH == "arm64" { - return true - } + case "ios": + return true } - if !cfg.BuildContext.CgoEnabled { - return false - } // Currently build modes c-shared, pie (on systems that do not // support PIE with internal linking mode (currently all // systems: issue #18968)), plugin, and -linkshared force // external linking mode, as of course does // -ldflags=-linkmode=external. External linking mode forces // an import of runtime/cgo. - pieCgo := cfg.BuildBuildmode == "pie" + // If there are multiple -linkmode options, the last one wins. + pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH) linkmodeExternal := false if p != nil { ldflags := BuildLdflags.For(p) - for i, a := range ldflags { - if a == "-linkmode=external" { - linkmodeExternal = true - } - if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { + for i := len(ldflags) - 1; i >= 0; i-- { + a := ldflags[i] + if a == "-linkmode=external" || + a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { linkmodeExternal = true + break + } else if a == "-linkmode=internal" || + a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" { + break } } } @@ -2020,22 +2220,7 @@ func (p *Package) InternalXGoFiles() []string { // using absolute paths. "Possibly relevant" means that files are not excluded // due to build tags, but files with names beginning with . or _ are still excluded. func (p *Package) InternalAllGoFiles() []string { - return p.mkAbs(str.StringList(p.constraintIgnoredGoFiles(), p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) -} - -// constraintIgnoredGoFiles returns the list of Go files ignored for reasons -// other than having a name beginning with '.' or '_'. -func (p *Package) constraintIgnoredGoFiles() []string { - if len(p.IgnoredGoFiles) == 0 { - return nil - } - files := make([]string, 0, len(p.IgnoredGoFiles)) - for _, f := range p.IgnoredGoFiles { - if f != "" && f[0] != '.' && f[0] != '_' { - files = append(files, f) - } - } - return files + return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) } // usesSwig reports whether the package needs to run SWIG. @@ -2117,6 +2302,18 @@ func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, return p } +// ModResolveTests indicates whether calls to the module loader should also +// resolve test dependencies of the requested packages. +// +// If ModResolveTests is true, then the module loader needs to resolve test +// dependencies at the same time as packages; otherwise, the test dependencies +// of those packages could be missing, and resolving those missing dependencies +// could change the selected versions of modules that provide other packages. +// +// TODO(#40775): Change this from a global variable to an explicit function +// argument where needed. +var ModResolveTests bool + // Packages returns the packages named by the // command line arguments 'args'. If a named package // cannot be loaded at all (for example, if the directory does not exist), @@ -2152,13 +2349,24 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package { if strings.HasSuffix(p, ".go") { // We need to test whether the path is an actual Go file and not a // package path or pattern ending in '.go' (see golang.org/issue/34653). - if fi, err := os.Stat(p); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() { return []*Package{GoFilesPackage(ctx, patterns)} } } } - matches := ImportPaths(ctx, patterns) + var matches []*search.Match + if modload.Init(); cfg.ModulesEnabled { + loadOpts := modload.PackageOpts{ + ResolveMissingImports: true, + LoadTests: ModResolveTests, + SilenceErrors: true, + } + matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...) + } else { + matches = search.ImportPaths(patterns) + } + var ( pkgs []*Package stk ImportStack @@ -2228,13 +2436,6 @@ func setToolFlags(pkgs ...*Package) { } } -func ImportPaths(ctx context.Context, args []string) []*search.Match { - if ModInit(); cfg.ModulesEnabled { - return ModImportPaths(ctx, args) - } - return search.ImportPaths(args) -} - // PackagesForBuild is like Packages but exits // if any of the packages or their dependencies have errors // (cannot be built). @@ -2282,7 +2483,7 @@ func PackagesForBuild(ctx context.Context, args []string) []*Package { // (typically named on the command line). The target is named p.a for // package p or named after the first Go file for package main. func GoFilesPackage(ctx context.Context, gofiles []string) *Package { - ModInit() + modload.Init() for _, f := range gofiles { if !strings.HasSuffix(f, ".go") { @@ -2305,10 +2506,10 @@ func GoFilesPackage(ctx context.Context, gofiles []string) *Package { // to make it look like this is a standard package or // command directory. So that local imports resolve // consistently, the files must all be in the same directory. - var dirent []os.FileInfo + var dirent []fs.FileInfo var dir string for _, file := range gofiles { - fi, err := os.Stat(file) + fi, err := fsys.Stat(file) if err != nil { base.Fatalf("%s", err) } @@ -2326,10 +2527,10 @@ func GoFilesPackage(ctx context.Context, gofiles []string) *Package { } dirent = append(dirent, fi) } - ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil } + ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil } if cfg.ModulesEnabled { - ModImportFromFiles(ctx, gofiles) + modload.ImportFromFiles(ctx, gofiles) } var err error @@ -2357,7 +2558,7 @@ func GoFilesPackage(ctx context.Context, gofiles []string) *Package { if cfg.GOBIN != "" { pkg.Target = filepath.Join(cfg.GOBIN, exe) } else if cfg.ModulesEnabled { - pkg.Target = filepath.Join(ModBinDir(), exe) + pkg.Target = filepath.Join(modload.BinDir(), exe) } } diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go index d4453846e6..5053ad767b 100644 --- a/src/cmd/go/internal/load/test.go +++ b/src/cmd/go/internal/load/test.go @@ -105,6 +105,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p var ptestErr, pxtestErr *PackageError var imports, ximports []*Package var stk ImportStack + var testEmbed, xtestEmbed map[string][]string stk.Push(p.ImportPath + " (test)") rawTestImports := str.StringList(p.TestImports) for i, path := range p.TestImports { @@ -122,7 +123,16 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p p.TestImports[i] = p1.ImportPath imports = append(imports, p1) } + var err error + p.TestEmbedFiles, testEmbed, err = p.resolveEmbed(p.TestEmbedPatterns) + if err != nil && ptestErr == nil { + ptestErr = &PackageError{ + ImportStack: stk.Copy(), + Err: err, + } + } stk.Pop() + stk.Push(p.ImportPath + "_test") pxtestNeedsPtest := false rawXTestImports := str.StringList(p.XTestImports) @@ -135,6 +145,13 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p } p.XTestImports[i] = p1.ImportPath } + p.XTestEmbedFiles, xtestEmbed, err = p.resolveEmbed(p.XTestEmbedPatterns) + if err != nil && pxtestErr == nil { + pxtestErr = &PackageError{ + ImportStack: stk.Copy(), + Err: err, + } + } stk.Pop() // Test package. @@ -174,6 +191,14 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p m[k] = append(m[k], v...) } ptest.Internal.Build.ImportPos = m + if testEmbed == nil && len(p.Internal.Embed) > 0 { + testEmbed = map[string][]string{} + } + for k, v := range p.Internal.Embed { + testEmbed[k] = v + } + ptest.Internal.Embed = testEmbed + ptest.EmbedFiles = str.StringList(p.EmbedFiles, p.TestEmbedFiles) ptest.collectDeps() } else { ptest = p @@ -193,6 +218,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p ForTest: p.ImportPath, Module: p.Module, Error: pxtestErr, + EmbedFiles: p.XTestEmbedFiles, }, Internal: PackageInternal{ LocalPrefix: p.Internal.LocalPrefix, @@ -206,6 +232,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p Gcflags: p.Internal.Gcflags, Ldflags: p.Internal.Ldflags, Gccgoflags: p.Internal.Gccgoflags, + Embed: xtestEmbed, }, } if pxtestNeedsPtest { diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go index aba3eed776..05f27c321a 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go @@ -9,6 +9,7 @@ package filelock import ( "errors" + "io/fs" "os" ) @@ -24,7 +25,7 @@ type File interface { Fd() uintptr // Stat returns the FileInfo structure describing file. - Stat() (os.FileInfo, error) + Stat() (fs.FileInfo, error) } // Lock places an advisory write lock on the file, blocking until it can be @@ -87,7 +88,7 @@ var ErrNotSupported = errors.New("operation not supported") // underlyingError returns the underlying error for known os error types. func underlyingError(err error) error { switch err := err.(type) { - case *os.PathError: + case *fs.PathError: return err.Err case *os.LinkError: return err.Err diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go index c60a78ed92..1fa4327a89 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix solaris +// +build aix solaris,!illumos // This code implements the filelock API using POSIX 'fcntl' locks, which attach // to an (inode, process) pair rather than a file descriptor. To avoid unlocking @@ -12,17 +12,14 @@ // Most platforms provide some alternative API, such as an 'flock' system call // or an F_OFD_SETLK command for 'fcntl', that allows for better concurrency and // does not require per-inode bookkeeping in the application. -// -// TODO(golang.org/issue/35618): add a syscall.Flock binding for Illumos and -// switch it over to use filelock_unix.go. package filelock import ( "errors" "io" + "io/fs" "math/rand" - "os" "sync" "syscall" "time" @@ -64,7 +61,7 @@ func lock(f File, lt lockType) (err error) { mu.Lock() if i, dup := inodes[f]; dup && i != ino { mu.Unlock() - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: errors.New("inode for file changed since last Lock or RLock"), @@ -155,7 +152,7 @@ func lock(f File, lt lockType) (err error) { if err != nil { unlock(f) - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go index 107611e1ce..bc480343fc 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go @@ -6,7 +6,7 @@ package filelock -import "os" +import "io/fs" type lockType int8 @@ -16,7 +16,7 @@ const ( ) func lock(f File, lt lockType) error { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: ErrNotSupported, @@ -24,7 +24,7 @@ func lock(f File, lt lockType) error { } func unlock(f File) error { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: ErrNotSupported, diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go index afdffe323f..0798ee469a 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go @@ -6,9 +6,7 @@ package filelock -import ( - "os" -) +import "io/fs" type lockType int8 @@ -18,7 +16,7 @@ const ( ) func lock(f File, lt lockType) error { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: ErrNotSupported, @@ -26,7 +24,7 @@ func lock(f File, lt lockType) error { } func unlock(f File) error { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: ErrNotSupported, diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go index faf73446f7..2ac2052b8f 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go @@ -9,7 +9,6 @@ package filelock_test import ( "fmt" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -51,9 +50,9 @@ func mustTempFile(t *testing.T) (f *os.File, remove func()) { t.Helper() base := filepath.Base(t.Name()) - f, err := ioutil.TempFile("", base) + f, err := os.CreateTemp("", base) if err != nil { - t.Fatalf(`ioutil.TempFile("", %q) = %v`, base, err) + t.Fatalf(`os.CreateTemp("", %q) = %v`, base, err) } t.Logf("fd %d = %s", f.Fd(), f.Name()) @@ -161,7 +160,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { doUnlockTF := false switch runtime.GOOS { - case "aix", "illumos", "solaris": + case "aix", "solaris": // When using POSIX locks (as on Solaris), we can't safely read-lock the // same inode through two different descriptors at the same time: when the // first descriptor is closed, the second descriptor would still be open but diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go index 00c4262832..ed07bac608 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd +// +build darwin dragonfly freebsd illumos linux netbsd openbsd package filelock import ( - "os" + "io/fs" "syscall" ) @@ -26,7 +26,7 @@ func lock(f File, lt lockType) (err error) { } } if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go index 43e85e450e..19de27eb9b 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go @@ -8,7 +8,7 @@ package filelock import ( "internal/syscall/windows" - "os" + "io/fs" "syscall" ) @@ -34,7 +34,7 @@ func lock(f File, lt lockType) error { err := windows.LockFileEx(syscall.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol) if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, @@ -47,7 +47,7 @@ func unlock(f File) error { ol := new(syscall.Overlapped) err := windows.UnlockFileEx(syscall.Handle(f.Fd()), reserved, allBytes, allBytes, ol) if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: err, diff --git a/src/cmd/go/internal/lockedfile/lockedfile.go b/src/cmd/go/internal/lockedfile/lockedfile.go index 59b2dba44c..82e1a89675 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile.go +++ b/src/cmd/go/internal/lockedfile/lockedfile.go @@ -9,7 +9,7 @@ package lockedfile import ( "fmt" "io" - "io/ioutil" + "io/fs" "os" "runtime" ) @@ -35,7 +35,7 @@ type osFile struct { // OpenFile is like os.OpenFile, but returns a locked file. // If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked; // otherwise, it is read-locked. -func OpenFile(name string, flag int, perm os.FileMode) (*File, error) { +func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { var ( f = new(File) err error @@ -82,10 +82,10 @@ func Edit(name string) (*File, error) { // non-nil error. func (f *File) Close() error { if f.closed { - return &os.PathError{ + return &fs.PathError{ Op: "close", Path: f.Name(), - Err: os.ErrClosed, + Err: fs.ErrClosed, } } f.closed = true @@ -103,12 +103,12 @@ func Read(name string) ([]byte, error) { } defer f.Close() - return ioutil.ReadAll(f) + return io.ReadAll(f) } // Write opens the named file (creating it with the given permissions if needed), // then write-locks it and overwrites it with the given content. -func Write(name string, content io.Reader, perm os.FileMode) (err error) { +func Write(name string, content io.Reader, perm fs.FileMode) (err error) { f, err := OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err @@ -135,7 +135,7 @@ func Transform(name string, t func([]byte) ([]byte, error)) (err error) { } defer f.Close() - old, err := ioutil.ReadAll(f) + old, err := io.ReadAll(f) if err != nil { return err } diff --git a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go index f63dd8664b..efc66461ed 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile_filelock.go +++ b/src/cmd/go/internal/lockedfile/lockedfile_filelock.go @@ -7,18 +7,20 @@ package lockedfile import ( + "io/fs" "os" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile/internal/filelock" ) -func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { +func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile // call instead of locking separately, but we have to support separate locking // calls for Linux and Windows anyway, so it's simpler to use that approach // consistently. - f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm) + f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm) if err != nil { return nil, err } diff --git a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go index 4a52c94976..70d6eddf2d 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile_plan9.go +++ b/src/cmd/go/internal/lockedfile/lockedfile_plan9.go @@ -7,10 +7,13 @@ package lockedfile import ( + "io/fs" "math/rand" "os" "strings" "time" + + "cmd/go/internal/fsys" ) // Opening an exclusive-use file returns an error. @@ -41,7 +44,7 @@ func isLocked(err error) bool { return false } -func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { +func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // Plan 9 uses a mode bit instead of explicit lock/unlock syscalls. // // Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open @@ -55,9 +58,9 @@ func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { // If the file was unpacked or created by some other program, it might not // have the ModeExclusive bit set. Set it before we call OpenFile, so that we // can be confident that a successful OpenFile implies exclusive use. - if fi, err := os.Stat(name); err == nil { - if fi.Mode()&os.ModeExclusive == 0 { - if err := os.Chmod(name, fi.Mode()|os.ModeExclusive); err != nil { + if fi, err := fsys.Stat(name); err == nil { + if fi.Mode()&fs.ModeExclusive == 0 { + if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil { return nil, err } } @@ -68,7 +71,7 @@ func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { nextSleep := 1 * time.Millisecond const maxSleep = 500 * time.Millisecond for { - f, err := os.OpenFile(name, flag, perm|os.ModeExclusive) + f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive) if err == nil { return f, nil } diff --git a/src/cmd/go/internal/lockedfile/lockedfile_test.go b/src/cmd/go/internal/lockedfile/lockedfile_test.go index 416c69d83b..34327dd841 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile_test.go +++ b/src/cmd/go/internal/lockedfile/lockedfile_test.go @@ -10,7 +10,6 @@ package lockedfile_test import ( "fmt" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -23,7 +22,7 @@ import ( func mustTempDir(t *testing.T) (dir string, remove func()) { t.Helper() - dir, err := ioutil.TempDir("", filepath.Base(t.Name())) + dir, err := os.MkdirTemp("", filepath.Base(t.Name())) if err != nil { t.Fatal(err) } @@ -155,8 +154,8 @@ func TestCanLockExistingFile(t *testing.T) { defer remove() path := filepath.Join(dir, "existing.txt") - if err := ioutil.WriteFile(path, []byte("ok"), 0777); err != nil { - t.Fatalf("ioutil.WriteFile: %v", err) + if err := os.WriteFile(path, []byte("ok"), 0777); err != nil { + t.Fatalf("os.WriteFile: %v", err) } f, err := lockedfile.Edit(path) @@ -201,7 +200,7 @@ func TestSpuriousEDEADLK(t *testing.T) { } defer b.Close() - if err := ioutil.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go index 41f294d475..ef1ad780c8 100644 --- a/src/cmd/go/internal/modcmd/download.go +++ b/src/cmd/go/internal/modcmd/download.go @@ -14,7 +14,6 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -64,7 +63,7 @@ func init() { // TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands. cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "") - work.AddModCommonFlags(cmdDownload) + base.AddModCommonFlags(&cmdDownload.Flag) } type moduleJSON struct { @@ -81,22 +80,19 @@ type moduleJSON struct { func runDownload(ctx context.Context, cmd *base.Command, args []string) { // Check whether modules are enabled and whether we're in a module. - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } + modload.ForceUseModules = true if !modload.HasModRoot() && len(args) == 0 { base.Fatalf("go mod download: no modules specified (see 'go help mod download')") } if len(args) == 0 { args = []string{"all"} } else if modload.HasModRoot() { - modload.InitMod(ctx) // to fill Target - targetAtLatest := modload.Target.Path + "@latest" + modload.LoadModFile(ctx) // to fill Target targetAtUpgrade := modload.Target.Path + "@upgrade" targetAtPatch := modload.Target.Path + "@patch" for _, arg := range args { switch arg { - case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch: + case modload.Target.Path, targetAtUpgrade, targetAtPatch: os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n") } } @@ -173,7 +169,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { for _, m := range mods { b, err := json.MarshalIndent(m, "", "\t") if err != nil { - base.Fatalf("%v", err) + base.Fatalf("go mod download: %v", err) } os.Stdout.Write(append(b, '\n')) if m.Error != "" { @@ -183,9 +179,12 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { } else { for _, m := range mods { if m.Error != "" { - base.Errorf("%s", m.Error) + base.Errorf("go mod download: %v", m.Error) } } base.ExitIfErrors() } + + // Update go.mod and especially go.sum if needed. + modload.WriteGoMod() } diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go index 18bdd34cd0..b203a8a2b0 100644 --- a/src/cmd/go/internal/modcmd/edit.go +++ b/src/cmd/go/internal/modcmd/edit.go @@ -19,7 +19,6 @@ import ( "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/modfile" "golang.org/x/mod/module" @@ -70,7 +69,7 @@ a version on the left side is dropped. The -retract=version and -dropretract=version flags add and drop a retraction on the given version. The version may be a single version -like "v1.2.3" or a closed interval like "[v1.1.0-v1.1.9]". Note that +like "v1.2.3" or a closed interval like "[v1.1.0,v1.1.9]". Note that -retract=version is a no-op if that retraction already exists. The -require, -droprequire, -exclude, -dropexclude, -replace, @@ -154,7 +153,7 @@ func init() { cmdEdit.Flag.Var(flagFunc(flagRetract), "retract", "") cmdEdit.Flag.Var(flagFunc(flagDropRetract), "dropretract", "") - work.AddModCommonFlags(cmdEdit) + base.AddModCommonFlags(&cmdEdit.Flag) base.AddBuildFlagsNX(&cmdEdit.Flag) } diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go index 6da12b9cab..3277548c23 100644 --- a/src/cmd/go/internal/modcmd/graph.go +++ b/src/cmd/go/internal/modcmd/graph.go @@ -13,9 +13,7 @@ import ( "sort" "cmd/go/internal/base" - "cmd/go/internal/cfg" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -33,22 +31,16 @@ path@version, except for the main module, which has no @version suffix. } func init() { - work.AddModCommonFlags(cmdGraph) + base.AddModCommonFlags(&cmdGraph.Flag) } func runGraph(ctx context.Context, cmd *base.Command, args []string) { if len(args) > 0 { base.Fatalf("go mod graph: graph takes no arguments") } - // Checks go mod expected behavior - if !modload.Enabled() { - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } else { - base.Fatalf("go: cannot find main module; see 'go help modules'") - } - } - modload.LoadBuildList(ctx) + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + modload.LoadAllModules(ctx) reqs := modload.MinReqs() format := func(m module.Version) string { diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go index b6cffd332d..c081bb547d 100644 --- a/src/cmd/go/internal/modcmd/init.go +++ b/src/cmd/go/internal/modcmd/init.go @@ -9,48 +9,41 @@ package modcmd import ( "cmd/go/internal/base" "cmd/go/internal/modload" - "cmd/go/internal/work" "context" - "os" - "strings" ) var cmdInit = &base.Command{ UsageLine: "go mod init [module]", Short: "initialize new module in current directory", Long: ` -Init initializes and writes a new go.mod to the current directory, -in effect creating a new module rooted at the current directory. -The file go.mod must not already exist. -If possible, init will guess the module path from import comments -(see 'go help importpath') or from version control configuration. -To override this guess, supply the module path as an argument. - `, +Init initializes and writes a new go.mod file in the current directory, in +effect creating a new module rooted at the current directory. The go.mod file +must not already exist. + +Init accepts one optional argument, the module path for the new module. If the +module path argument is omitted, init will attempt to infer the module path +using import comments in .go files, vendoring tool configuration files (like +Gopkg.lock), and the current directory (if in GOPATH). + +If a configuration file for a vendoring tool is present, init will attempt to +import module requirements from it. +`, Run: runInit, } func init() { - work.AddModCommonFlags(cmdInit) + base.AddModCommonFlags(&cmdInit.Flag) } func runInit(ctx context.Context, cmd *base.Command, args []string) { - modload.CmdModInit = true if len(args) > 1 { base.Fatalf("go mod init: too many arguments") } + var modPath string if len(args) == 1 { - modload.CmdModModule = args[0] - } - if os.Getenv("GO111MODULE") == "off" { - base.Fatalf("go mod init: modules disabled by GO111MODULE=off; see 'go help modules'") + modPath = args[0] } - modFilePath := modload.ModFilePath() - if _, err := os.Stat(modFilePath); err == nil { - base.Fatalf("go mod init: go.mod already exists") - } - if strings.Contains(modload.CmdModModule, "@") { - base.Fatalf("go mod init: module path must not contain '@'") - } - modload.InitMod(ctx) // does all the hard work - modload.WriteGoMod() + + modload.ForceUseModules = true + modload.CreateModFile(ctx, modPath) // does all the hard work } diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go index c7c53d7c0c..fb43e33ec5 100644 --- a/src/cmd/go/internal/modcmd/tidy.go +++ b/src/cmd/go/internal/modcmd/tidy.go @@ -9,13 +9,13 @@ package modcmd import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" "context" ) var cmdTidy = &base.Command{ - UsageLine: "go mod tidy [-v]", + UsageLine: "go mod tidy [-e] [-v]", Short: "add missing and remove unused modules", Long: ` Tidy makes sure go.mod matches the source code in the module. @@ -26,13 +26,19 @@ to go.sum and removes any unnecessary ones. The -v flag causes tidy to print information about removed modules to standard error. + +The -e flag causes tidy to attempt to proceed despite errors +encountered while loading packages. `, + Run: runTidy, } +var tidyE bool // if true, report errors but proceed anyway. + func init() { - cmdTidy.Run = runTidy // break init cycle cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "") - work.AddModCommonFlags(cmdTidy) + cmdTidy.Flag.BoolVar(&tidyE, "e", false, "") + base.AddModCommonFlags(&cmdTidy.Flag) } func runTidy(ctx context.Context, cmd *base.Command, args []string) { @@ -40,7 +46,26 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) { base.Fatalf("go mod tidy: no arguments allowed") } - modload.LoadALL(ctx) + // Tidy aims to make 'go test' reproducible for any package in 'all', so we + // need to include test dependencies. For modules that specify go 1.15 or + // earlier this is a no-op (because 'all' saturates transitive test + // dependencies). + // + // However, with lazy loading (go 1.16+) 'all' includes only the packages that + // are transitively imported by the main module, not the test dependencies of + // those packages. In order to make 'go test' reproducible for the packages + // that are in 'all' but outside of the main module, we must explicitly + // request that their test dependencies be included. + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + modload.LoadPackages(ctx, modload.PackageOpts{ + Tags: imports.AnyTags(), + ResolveMissingImports: true, + LoadTests: true, + AllowErrors: tidyE, + }, "all") + modload.TidyBuildList() modload.TrimGoSum() modload.WriteGoMod() diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go index e5353b5c7f..1bbb57d353 100644 --- a/src/cmd/go/internal/modcmd/vendor.go +++ b/src/cmd/go/internal/modcmd/vendor.go @@ -9,7 +9,7 @@ import ( "context" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -17,16 +17,16 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" "golang.org/x/mod/semver" ) var cmdVendor = &base.Command{ - UsageLine: "go mod vendor [-v]", + UsageLine: "go mod vendor [-e] [-v]", Short: "make vendored copy of dependencies", Long: ` Vendor resets the main module's vendor directory to include all packages @@ -35,20 +35,35 @@ It does not include test code for vendored packages. The -v flag causes vendor to print the names of vendored modules and packages to standard error. + +The -e flag causes vendor to attempt to proceed despite errors +encountered while loading packages. `, Run: runVendor, } +var vendorE bool // if true, report errors but proceed anyway + func init() { cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "") - work.AddModCommonFlags(cmdVendor) + cmdVendor.Flag.BoolVar(&vendorE, "e", false, "") + base.AddModCommonFlags(&cmdVendor.Flag) } func runVendor(ctx context.Context, cmd *base.Command, args []string) { if len(args) != 0 { base.Fatalf("go mod vendor: vendor takes no arguments") } - pkgs := modload.LoadVendor(ctx) + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + loadOpts := modload.PackageOpts{ + Tags: imports.AnyTags(), + ResolveMissingImports: true, + UseVendorAll: true, + AllowErrors: vendorE, + } + _, pkgs := modload.LoadPackages(ctx, loadOpts, "all") vdir := filepath.Join(modload.ModRoot(), "vendor") if err := os.RemoveAll(vdir); err != nil { @@ -58,7 +73,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) { modpkgs := make(map[module.Version][]string) for _, pkg := range pkgs { m := modload.PackageModule(pkg) - if m == modload.Target { + if m.Path == "" || m == modload.Target { continue } modpkgs[m] = append(modpkgs[m], pkg) @@ -76,28 +91,38 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) { includeAllReplacements = true } + var vendorMods []module.Version + for m := range isExplicit { + vendorMods = append(vendorMods, m) + } + for m := range modpkgs { + if !isExplicit[m] { + vendorMods = append(vendorMods, m) + } + } + module.Sort(vendorMods) + var buf bytes.Buffer - for _, m := range modload.BuildList()[1:] { - if pkgs := modpkgs[m]; len(pkgs) > 0 || isExplicit[m] { - line := moduleLine(m, modload.Replacement(m)) - buf.WriteString(line) + for _, m := range vendorMods { + line := moduleLine(m, modload.Replacement(m)) + buf.WriteString(line) + if cfg.BuildV { + os.Stderr.WriteString(line) + } + if isExplicit[m] { + buf.WriteString("## explicit\n") if cfg.BuildV { - os.Stderr.WriteString(line) + os.Stderr.WriteString("## explicit\n") } - if isExplicit[m] { - buf.WriteString("## explicit\n") - if cfg.BuildV { - os.Stderr.WriteString("## explicit\n") - } - } - sort.Strings(pkgs) - for _, pkg := range pkgs { - fmt.Fprintf(&buf, "%s\n", pkg) - if cfg.BuildV { - fmt.Fprintf(os.Stderr, "%s\n", pkg) - } - vendorPkg(vdir, pkg) + } + pkgs := modpkgs[m] + sort.Strings(pkgs) + for _, pkg := range pkgs { + fmt.Fprintf(&buf, "%s\n", pkg) + if cfg.BuildV { + fmt.Fprintf(os.Stderr, "%s\n", pkg) } + vendorPkg(vdir, pkg) } } @@ -129,7 +154,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) { base.Fatalf("go mod vendor: %v", err) } - if err := ioutil.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil { + if err := os.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil { base.Fatalf("go mod vendor: %v", err) } } @@ -218,7 +243,7 @@ var metaPrefixes = []string{ } // matchMetadata reports whether info is a metadata file. -func matchMetadata(dir string, info os.FileInfo) bool { +func matchMetadata(dir string, info fs.DirEntry) bool { name := info.Name() for _, p := range metaPrefixes { if strings.HasPrefix(name, p) { @@ -229,12 +254,12 @@ func matchMetadata(dir string, info os.FileInfo) bool { } // matchPotentialSourceFile reports whether info may be relevant to a build operation. -func matchPotentialSourceFile(dir string, info os.FileInfo) bool { +func matchPotentialSourceFile(dir string, info fs.DirEntry) bool { if strings.HasSuffix(info.Name(), "_test.go") { return false } if strings.HasSuffix(info.Name(), ".go") { - f, err := os.Open(filepath.Join(dir, info.Name())) + f, err := fsys.Open(filepath.Join(dir, info.Name())) if err != nil { base.Fatalf("go mod vendor: %v", err) } @@ -255,8 +280,8 @@ func matchPotentialSourceFile(dir string, info os.FileInfo) bool { } // copyDir copies all regular files satisfying match(info) from src to dst. -func copyDir(dst, src string, match func(dir string, info os.FileInfo) bool) { - files, err := ioutil.ReadDir(src) +func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) { + files, err := os.ReadDir(src) if err != nil { base.Fatalf("go mod vendor: %v", err) } @@ -264,7 +289,7 @@ func copyDir(dst, src string, match func(dir string, info os.FileInfo) bool) { base.Fatalf("go mod vendor: %v", err) } for _, file := range files { - if file.IsDir() || !file.Mode().IsRegular() || !match(src, file) { + if file.IsDir() || !file.Type().IsRegular() || !match(src, file) { continue } r, err := os.Open(filepath.Join(src, file.Name())) diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go index 73ab714d10..c83e70076a 100644 --- a/src/cmd/go/internal/modcmd/verify.go +++ b/src/cmd/go/internal/modcmd/verify.go @@ -9,15 +9,13 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "io/fs" "os" "runtime" "cmd/go/internal/base" - "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" "golang.org/x/mod/sumdb/dirhash" @@ -38,7 +36,7 @@ non-zero status. } func init() { - work.AddModCommonFlags(cmdVerify) + base.AddModCommonFlags(&cmdVerify.Flag) } func runVerify(ctx context.Context, cmd *base.Command, args []string) { @@ -46,21 +44,15 @@ func runVerify(ctx context.Context, cmd *base.Command, args []string) { // NOTE(rsc): Could take a module pattern. base.Fatalf("go mod verify: verify takes no arguments") } - // Checks go mod expected behavior - if !modload.Enabled() || !modload.HasModRoot() { - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } else { - base.Fatalf("go: cannot find main module; see 'go help modules'") - } - } + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot // Only verify up to GOMAXPROCS zips at once. type token struct{} sem := make(chan token, runtime.GOMAXPROCS(0)) // Use a slice of result channels, so that the output is deterministic. - mods := modload.LoadBuildList(ctx)[1:] + mods := modload.LoadAllModules(ctx)[1:] errsChans := make([]<-chan []error, len(mods)) for i, mod := range mods { @@ -94,10 +86,10 @@ func verifyMod(mod module.Version) []error { _, zipErr = os.Stat(zip) } dir, dirErr := modfetch.DownloadDir(mod) - data, err := ioutil.ReadFile(zip + "hash") + data, err := os.ReadFile(zip + "hash") if err != nil { - if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) && - dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { + if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) && + dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) { // Nothing downloaded yet. Nothing to verify. return nil } @@ -106,7 +98,7 @@ func verifyMod(mod module.Version) []error { } h := string(bytes.TrimSpace(data)) - if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) { + if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) { // ok } else { hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash) @@ -117,7 +109,7 @@ func verifyMod(mod module.Version) []error { errs = append(errs, fmt.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip)) } } - if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { + if dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) { // ok } else { hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash) diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go index b16887d318..e287c88060 100644 --- a/src/cmd/go/internal/modcmd/why.go +++ b/src/cmd/go/internal/modcmd/why.go @@ -10,8 +10,8 @@ import ( "strings" "cmd/go/internal/base" + "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -58,14 +58,20 @@ var ( func init() { cmdWhy.Run = runWhy // break init cycle - work.AddModCommonFlags(cmdWhy) + base.AddModCommonFlags(&cmdWhy.Flag) } func runWhy(ctx context.Context, cmd *base.Command, args []string) { - loadALL := modload.LoadALL - if *whyVendor { - loadALL = modload.LoadVendor + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + loadOpts := modload.PackageOpts{ + Tags: imports.AnyTags(), + LoadTests: !*whyVendor, + SilenceErrors: true, + UseVendorAll: *whyVendor, } + if *whyM { listU := false listVersions := false @@ -77,7 +83,8 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) { } mods := modload.ListModules(ctx, args, listU, listVersions, listRetractions) byModule := make(map[module.Version][]string) - for _, path := range loadALL(ctx) { + _, pkgs := modload.LoadPackages(ctx, loadOpts, "all") + for _, path := range pkgs { m := modload.PackageModule(path) if m.Path != "" { byModule[m] = append(byModule[m], path) @@ -106,8 +113,11 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) { sep = "\n" } } else { - matches := modload.ImportPaths(ctx, args) // resolve to packages - loadALL(ctx) // rebuild graph, from main module (not from named packages) + // Resolve to packages. + matches, _ := modload.LoadPackages(ctx, loadOpts, args...) + + modload.LoadPackages(ctx, loadOpts, "all") // rebuild graph, from main module (not from named packages) + sep := "" for _, m := range matches { for _, path := range m.Pkgs { diff --git a/src/cmd/go/internal/modconv/convert_test.go b/src/cmd/go/internal/modconv/convert_test.go index faa2b4c606..66b9ff4f38 100644 --- a/src/cmd/go/internal/modconv/convert_test.go +++ b/src/cmd/go/internal/modconv/convert_test.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "internal/testenv" - "io/ioutil" "log" "os" "os/exec" @@ -37,7 +36,7 @@ func testMain(m *testing.M) int { return 0 } - dir, err := ioutil.TempDir("", "modconv-test-") + dir, err := os.MkdirTemp("", "modconv-test-") if err != nil { log.Fatal(err) } @@ -167,7 +166,7 @@ func TestConvertLegacyConfig(t *testing.T) { for name := range Converters { file := filepath.Join(dir, name) - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err == nil { f := new(modfile.File) f.AddModuleStmt(tt.path) diff --git a/src/cmd/go/internal/modconv/modconv_test.go b/src/cmd/go/internal/modconv/modconv_test.go index ccc4f3d576..750525d404 100644 --- a/src/cmd/go/internal/modconv/modconv_test.go +++ b/src/cmd/go/internal/modconv/modconv_test.go @@ -7,7 +7,7 @@ package modconv import ( "bytes" "fmt" - "io/ioutil" + "os" "path/filepath" "testing" ) @@ -42,7 +42,7 @@ func Test(t *testing.T) { if Converters[extMap[ext]] == nil { t.Fatalf("Converters[%q] == nil", extMap[ext]) } - data, err := ioutil.ReadFile(test) + data, err := os.ReadFile(test) if err != nil { t.Fatal(err) } @@ -50,7 +50,7 @@ func Test(t *testing.T) { if err != nil { t.Fatal(err) } - want, err := ioutil.ReadFile(test[:len(test)-len(ext)] + ".out") + want, err := os.ReadFile(test[:len(test)-len(ext)] + ".out") if err != nil { t.Error(err) } diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go index e3074b775e..3a2ff63721 100644 --- a/src/cmd/go/internal/modfetch/cache.go +++ b/src/cmd/go/internal/modfetch/cache.go @@ -10,10 +10,11 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" @@ -59,7 +60,7 @@ func CachePath(m module.Version, suffix string) (string, error) { // DownloadDir returns the directory to which m should have been downloaded. // An error will be returned if the module path or version cannot be escaped. -// An error satisfying errors.Is(err, os.ErrNotExist) will be returned +// An error satisfying errors.Is(err, fs.ErrNotExist) will be returned // along with the directory if the directory does not exist or if the directory // is not completely populated. func DownloadDir(m module.Version) (string, error) { @@ -106,14 +107,14 @@ func DownloadDir(m module.Version) (string, error) { // DownloadDirPartialError is returned by DownloadDir if a module directory // exists but was not completely populated. // -// DownloadDirPartialError is equivalent to os.ErrNotExist. +// DownloadDirPartialError is equivalent to fs.ErrNotExist. type DownloadDirPartialError struct { Dir string Err error } func (e *DownloadDirPartialError) Error() string { return fmt.Sprintf("%s: %v", e.Dir, e.Err) } -func (e *DownloadDirPartialError) Is(err error) bool { return err == os.ErrNotExist } +func (e *DownloadDirPartialError) Is(err error) bool { return err == fs.ErrNotExist } // lockVersion locks a file within the module cache that guards the downloading // and extraction of the zipfile for the given module version. @@ -155,16 +156,30 @@ func SideLock() (unlock func(), err error) { type cachingRepo struct { path string cache par.Cache // cache for all operations - r Repo + + once sync.Once + initRepo func() (Repo, error) + r Repo } -func newCachingRepo(r Repo) *cachingRepo { +func newCachingRepo(path string, initRepo func() (Repo, error)) *cachingRepo { return &cachingRepo{ - r: r, - path: r.ModulePath(), + path: path, + initRepo: initRepo, } } +func (r *cachingRepo) repo() Repo { + r.once.Do(func() { + var err error + r.r, err = r.initRepo() + if err != nil { + r.r = errRepo{r.path, err} + } + }) + return r.r +} + func (r *cachingRepo) ModulePath() string { return r.path } @@ -175,7 +190,7 @@ func (r *cachingRepo) Versions(prefix string) ([]string, error) { err error } c := r.cache.Do("versions:"+prefix, func() interface{} { - list, err := r.r.Versions(prefix) + list, err := r.repo().Versions(prefix) return cached{list, err} }).(cached) @@ -197,7 +212,7 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { return cachedInfo{info, nil} } - info, err = r.r.Stat(rev) + info, err = r.repo().Stat(rev) if err == nil { // If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78, // then save the information under the proper version, for future use. @@ -224,7 +239,7 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { func (r *cachingRepo) Latest() (*RevInfo, error) { c := r.cache.Do("latest:", func() interface{} { - info, err := r.r.Latest() + info, err := r.repo().Latest() // Save info for likely future Stat call. if err == nil { @@ -258,7 +273,7 @@ func (r *cachingRepo) GoMod(version string) ([]byte, error) { return cached{text, nil} } - text, err = r.r.GoMod(version) + text, err = r.repo().GoMod(version) if err == nil { if err := checkGoMod(r.path, version, text); err != nil { return cached{text, err} @@ -277,26 +292,11 @@ func (r *cachingRepo) GoMod(version string) ([]byte, error) { } func (r *cachingRepo) Zip(dst io.Writer, version string) error { - return r.r.Zip(dst, version) -} - -// Stat is like Lookup(path).Stat(rev) but avoids the -// repository path resolution in Lookup if the result is -// already cached on local disk. -func Stat(proxy, path, rev string) (*RevInfo, error) { - _, info, err := readDiskStat(path, rev) - if err == nil { - return info, nil - } - repo, err := Lookup(proxy, path) - if err != nil { - return nil, err - } - return repo.Stat(rev) + return r.repo().Zip(dst, version) } -// InfoFile is like Stat but returns the name of the file containing -// the cached information. +// InfoFile is like Lookup(path).Stat(version) but returns the name of the file +// containing the cached information. func InfoFile(path, version string) (string, error) { if !semver.IsValid(version) { return "", fmt.Errorf("invalid version %q", version) @@ -307,10 +307,7 @@ func InfoFile(path, version string) (string, error) { } err := TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err == nil { - _, err = repo.Stat(version) - } + _, err := Lookup(proxy, path).Stat(version) return err }) if err != nil { @@ -336,11 +333,7 @@ func GoMod(path, rev string) ([]byte, error) { rev = info.Version } else { err := TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err != nil { - return err - } - info, err := repo.Stat(rev) + info, err := Lookup(proxy, path).Stat(rev) if err == nil { rev = info.Version } @@ -357,11 +350,8 @@ func GoMod(path, rev string) ([]byte, error) { return data, nil } - err = TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err == nil { - data, err = repo.GoMod(rev) - } + err = TryProxies(func(proxy string) (err error) { + data, err = Lookup(proxy, path).GoMod(rev) return err }) return data, err @@ -492,7 +482,7 @@ func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error for _, name := range names { if strings.HasSuffix(name, suffix) { v := strings.TrimSuffix(name, ".info") - if IsPseudoVersion(v) && semver.Max(maxVersion, v) == v { + if IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 { maxVersion = v file, info, err = readDiskStat(path, strings.TrimSuffix(name, ".info")) } @@ -607,7 +597,7 @@ func rewriteVersionList(dir string) { } defer unlock() - infos, err := ioutil.ReadDir(dir) + infos, err := os.ReadDir(dir) if err != nil { return } diff --git a/src/cmd/go/internal/modfetch/cache_test.go b/src/cmd/go/internal/modfetch/cache_test.go index 241c800e69..722c984e37 100644 --- a/src/cmd/go/internal/modfetch/cache_test.go +++ b/src/cmd/go/internal/modfetch/cache_test.go @@ -5,14 +5,13 @@ package modfetch import ( - "io/ioutil" "os" "path/filepath" "testing" ) func TestWriteDiskCache(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "go-writeCache-test-") + tmpdir, err := os.MkdirTemp("", "go-writeCache-test-") if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go index d85eddf767..86c1c14d4a 100644 --- a/src/cmd/go/internal/modfetch/codehost/codehost.go +++ b/src/cmd/go/internal/modfetch/codehost/codehost.go @@ -11,7 +11,7 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" + "io/fs" "os" "os/exec" "path/filepath" @@ -79,9 +79,8 @@ type Repo interface { ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) // RecentTag returns the most recent tag on rev or one of its predecessors - // with the given prefix and major version. - // An empty major string matches any major version. - RecentTag(rev, prefix, major string) (tag string, err error) + // with the given prefix. allowed may be used to filter out unwanted versions. + RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) // DescendsFrom reports whether rev or any of its ancestors has the given tag. // @@ -106,7 +105,7 @@ type FileRev struct { Err error // error if any; os.IsNotExist(Err)==true if rev exists but file does not exist in that rev } -// UnknownRevisionError is an error equivalent to os.ErrNotExist, but for a +// UnknownRevisionError is an error equivalent to fs.ErrNotExist, but for a // revision rather than a file. type UnknownRevisionError struct { Rev string @@ -116,10 +115,10 @@ func (e *UnknownRevisionError) Error() string { return "unknown revision " + e.Rev } func (UnknownRevisionError) Is(err error) bool { - return err == os.ErrNotExist + return err == fs.ErrNotExist } -// ErrNoCommits is an error equivalent to os.ErrNotExist indicating that a given +// ErrNoCommits is an error equivalent to fs.ErrNotExist indicating that a given // repository or module contains no commits. var ErrNoCommits error = noCommitsError{} @@ -129,7 +128,7 @@ func (noCommitsError) Error() string { return "no commits" } func (noCommitsError) Is(err error) bool { - return err == os.ErrNotExist + return err == fs.ErrNotExist } // AllHex reports whether the revision rev is entirely lower-case hexadecimal digits. @@ -189,7 +188,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) { } defer unlock() - data, err := ioutil.ReadFile(dir + ".info") + data, err := os.ReadFile(dir + ".info") info, err2 := os.Stat(dir) if err == nil && err2 == nil && info.IsDir() { // Info file and directory both already exist: reuse. @@ -211,7 +210,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) { if err := os.MkdirAll(dir, 0777); err != nil { return "", "", err } - if err := ioutil.WriteFile(dir+".info", []byte(key), 0666); err != nil { + if err := os.WriteFile(dir+".info", []byte(key), 0666); err != nil { os.RemoveAll(dir) return "", "", err } @@ -264,6 +263,9 @@ func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, } cmd := str.StringList(cmdline...) + if os.Getenv("TESTGOVCS") == "panic" { + panic(fmt.Sprintf("use of vcs: %v", cmd)) + } if cfg.BuildX { text := new(strings.Builder) if dir != "" { diff --git a/src/cmd/go/internal/modfetch/codehost/git.go b/src/cmd/go/internal/modfetch/codehost/git.go index 31921324a7..8abc039e7f 100644 --- a/src/cmd/go/internal/modfetch/codehost/git.go +++ b/src/cmd/go/internal/modfetch/codehost/git.go @@ -9,7 +9,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" "os" "os/exec" @@ -34,13 +34,13 @@ func LocalGitRepo(remote string) (Repo, error) { } // A notExistError wraps another error to retain its original text -// but makes it opaquely equivalent to os.ErrNotExist. +// but makes it opaquely equivalent to fs.ErrNotExist. type notExistError struct { err error } func (e notExistError) Error() string { return e.err.Error() } -func (notExistError) Is(err error) bool { return err == os.ErrNotExist } +func (notExistError) Is(err error) bool { return err == fs.ErrNotExist } const gitWorkDirType = "git3" @@ -188,7 +188,7 @@ func (r *gitRepo) loadRefs() { // For HTTP and HTTPS, that's easy to detect: we'll try to fetch the URL // ourselves and see what code it serves. if u, err := url.Parse(r.remoteURL); err == nil && (u.Scheme == "http" || u.Scheme == "https") { - if _, err := web.GetBytes(u); errors.Is(err, os.ErrNotExist) { + if _, err := web.GetBytes(u); errors.Is(err, fs.ErrNotExist) { gitErr = notExistError{gitErr} } } @@ -505,7 +505,7 @@ func (r *gitRepo) ReadFile(rev, file string, maxSize int64) ([]byte, error) { } out, err := Run(r.dir, "git", "cat-file", "blob", info.Name+":"+file) if err != nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return out, nil } @@ -629,9 +629,9 @@ func (r *gitRepo) readFileRevs(tags []string, file string, fileMap map[string]*F case "tag", "commit": switch fileType { default: - f.Err = &os.PathError{Path: tag + ":" + file, Op: "read", Err: fmt.Errorf("unexpected non-blob type %q", fileType)} + f.Err = &fs.PathError{Path: tag + ":" + file, Op: "read", Err: fmt.Errorf("unexpected non-blob type %q", fileType)} case "missing": - f.Err = &os.PathError{Path: tag + ":" + file, Op: "read", Err: os.ErrNotExist} + f.Err = &fs.PathError{Path: tag + ":" + file, Op: "read", Err: fs.ErrNotExist} case "blob": f.Data = fileData } @@ -644,7 +644,7 @@ func (r *gitRepo) readFileRevs(tags []string, file string, fileMap map[string]*F return missing, nil } -func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) { +func (r *gitRepo) RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) { info, err := r.Stat(rev) if err != nil { return "", err @@ -680,7 +680,10 @@ func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) { // NOTE: Do not replace the call to semver.Compare with semver.Max. // We want to return the actual tag, not a canonicalized version of it, // and semver.Max currently canonicalizes (see golang.org/issue/32700). - if c := semver.Canonical(semtag); c != "" && strings.HasPrefix(semtag, c) && (major == "" || semver.Major(c) == major) && semver.Compare(semtag, highest) > 0 { + if c := semver.Canonical(semtag); c == "" || !strings.HasPrefix(semtag, c) || !allowed(semtag) { + continue + } + if semver.Compare(semtag, highest) > 0 { highest = semtag } } @@ -823,12 +826,12 @@ func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, archive, err := Run(r.dir, "git", "-c", "core.autocrlf=input", "-c", "core.eol=lf", "archive", "--format=zip", "--prefix=prefix/", info.Name, args) if err != nil { if bytes.Contains(err.(*RunError).Stderr, []byte("did not match any files")) { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return nil, err } - return ioutil.NopCloser(bytes.NewReader(archive)), nil + return io.NopCloser(bytes.NewReader(archive)), nil } // ensureGitAttributes makes sure export-subst and export-ignore features are @@ -859,7 +862,7 @@ func ensureGitAttributes(repoDir string) (err error) { } }() - b, err := ioutil.ReadAll(f) + b, err := io.ReadAll(f) if err != nil { return err } diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go index ba27c70f5a..89a73baad9 100644 --- a/src/cmd/go/internal/modfetch/codehost/git_test.go +++ b/src/cmd/go/internal/modfetch/codehost/git_test.go @@ -10,7 +10,8 @@ import ( "flag" "fmt" "internal/testenv" - "io/ioutil" + "io" + "io/fs" "log" "os" "os/exec" @@ -52,7 +53,7 @@ func testMain(m *testing.M) int { return 0 } - dir, err := ioutil.TempDir("", "gitrepo-test-") + dir, err := os.MkdirTemp("", "gitrepo-test-") if err != nil { log.Fatal(err) } @@ -210,7 +211,7 @@ var readFileTests = []struct { repo: gitrepo1, rev: "v2.3.4", file: "another.txt", - err: os.ErrNotExist.Error(), + err: fs.ErrNotExist.Error(), }, } @@ -432,7 +433,7 @@ func TestReadZip(t *testing.T) { if tt.err != "" { t.Fatalf("ReadZip: no error, wanted %v", tt.err) } - zipdata, err := ioutil.ReadAll(rc) + zipdata, err := io.ReadAll(rc) if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/modfetch/codehost/shell.go b/src/cmd/go/internal/modfetch/codehost/shell.go index 2762c55720..ce8b501d53 100644 --- a/src/cmd/go/internal/modfetch/codehost/shell.go +++ b/src/cmd/go/internal/modfetch/codehost/shell.go @@ -14,7 +14,7 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" + "io" "log" "os" "strings" @@ -115,7 +115,7 @@ func main() { fmt.Fprintf(os.Stderr, "?%s\n", err) continue } - data, err := ioutil.ReadAll(rc) + data, err := io.ReadAll(rc) rc.Close() if err != nil { fmt.Fprintf(os.Stderr, "?%s\n", err) @@ -123,7 +123,7 @@ func main() { } if f[3] != "-" { - if err := ioutil.WriteFile(f[3], data, 0666); err != nil { + if err := os.WriteFile(f[3], data, 0666); err != nil { fmt.Fprintf(os.Stderr, "?%s\n", err) continue } diff --git a/src/cmd/go/internal/modfetch/codehost/vcs.go b/src/cmd/go/internal/modfetch/codehost/vcs.go index 7284557f4b..c2cca084e3 100644 --- a/src/cmd/go/internal/modfetch/codehost/vcs.go +++ b/src/cmd/go/internal/modfetch/codehost/vcs.go @@ -9,7 +9,7 @@ import ( "fmt" "internal/lazyregexp" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -377,7 +377,7 @@ func (r *vcsRepo) ReadFile(rev, file string, maxSize int64) ([]byte, error) { out, err := Run(r.dir, r.cmd.readFile(rev, file, r.remote)) if err != nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return out, nil } @@ -395,7 +395,7 @@ func (r *vcsRepo) ReadFileRevs(revs []string, file string, maxSize int64) (map[s return nil, vcsErrorf("ReadFileRevs not implemented") } -func (r *vcsRepo) RecentTag(rev, prefix, major string) (tag string, err error) { +func (r *vcsRepo) RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) { // We don't technically need to lock here since we're returning an error // uncondititonally, but doing so anyway will help to avoid baking in // lock-inversion bugs. @@ -432,7 +432,7 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, if rev == "latest" { rev = r.cmd.latest } - f, err := ioutil.TempFile("", "go-readzip-*.zip") + f, err := os.CreateTemp("", "go-readzip-*.zip") if err != nil { return nil, err } @@ -567,7 +567,7 @@ func bzrParseStat(rev, out string) (*RevInfo, error) { func fossilParseStat(rev, out string) (*RevInfo, error) { for _, line := range strings.Split(out, "\n") { - if strings.HasPrefix(line, "uuid:") { + if strings.HasPrefix(line, "uuid:") || strings.HasPrefix(line, "hash:") { f := strings.Fields(line) if len(f) != 5 || len(f[1]) != 40 || f[4] != "UTC" { return nil, vcsErrorf("unexpected response from fossil info: %q", line) diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go index d043903336..2dcbb99b18 100644 --- a/src/cmd/go/internal/modfetch/coderepo.go +++ b/src/cmd/go/internal/modfetch/coderepo.go @@ -10,7 +10,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path" "sort" @@ -419,9 +419,14 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e tagPrefix = r.codeDir + "/" } + isRetracted, err := r.retractedVersions() + if err != nil { + isRetracted = func(string) bool { return false } + } + // tagToVersion returns the version obtained by trimming tagPrefix from tag. - // If the tag is invalid or a pseudo-version, tagToVersion returns an empty - // version. + // If the tag is invalid, retracted, or a pseudo-version, tagToVersion returns + // an empty version. tagToVersion := func(tag string) (v string, tagIsCanonical bool) { if !strings.HasPrefix(tag, tagPrefix) { return "", false @@ -436,6 +441,9 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e if v == "" || !strings.HasPrefix(trimmed, v) { return "", false // Invalid or incomplete version (just vX or vX.Y). } + if isRetracted(v) { + return "", false + } if v == trimmed { tagIsCanonical = true } @@ -500,15 +508,24 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e return checkGoMod() } + // Find the highest tagged version in the revision's history, subject to + // major version and +incompatible constraints. Use that version as the + // pseudo-version base so that the pseudo-version sorts higher. Ignore + // retracted versions. + allowedMajor := func(major string) func(v string) bool { + return func(v string) bool { + return (major == "" || semver.Major(v) == major) && !isRetracted(v) + } + } if pseudoBase == "" { var tag string if r.pseudoMajor != "" || canUseIncompatible() { - tag, _ = r.code.RecentTag(info.Name, tagPrefix, r.pseudoMajor) + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor(r.pseudoMajor)) } else { // Allow either v1 or v0, but not incompatible higher versions. - tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v1") + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v1")) if tag == "" { - tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v0") + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v0")) } } pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid @@ -869,6 +886,57 @@ func (r *codeRepo) modPrefix(rev string) string { return r.modPath + "@" + rev } +func (r *codeRepo) retractedVersions() (func(string) bool, error) { + versions, err := r.Versions("") + if err != nil { + return nil, err + } + + for i, v := range versions { + if strings.HasSuffix(v, "+incompatible") { + versions = versions[:i] + break + } + } + if len(versions) == 0 { + return func(string) bool { return false }, nil + } + + var highest string + for i := len(versions) - 1; i >= 0; i-- { + v := versions[i] + if semver.Prerelease(v) == "" { + highest = v + break + } + } + if highest == "" { + highest = versions[len(versions)-1] + } + + data, err := r.GoMod(highest) + if err != nil { + return nil, err + } + f, err := modfile.ParseLax("go.mod", data, nil) + if err != nil { + return nil, err + } + retractions := make([]modfile.VersionInterval, len(f.Retract)) + for _, r := range f.Retract { + retractions = append(retractions, r.VersionInterval) + } + + return func(v string) bool { + for _, r := range retractions { + if semver.Compare(r.Low, v) <= 0 && semver.Compare(v, r.High) <= 0 { + return true + } + } + return false + }, nil +} + func (r *codeRepo) Zip(dst io.Writer, version string) error { if version != module.CanonicalVersion(version) { return fmt.Errorf("version %s is not canonical", version) @@ -897,7 +965,7 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { subdir = strings.Trim(subdir, "/") // Spool to local file. - f, err := ioutil.TempFile("", "go-codehost-") + f, err := os.CreateTemp("", "go-codehost-") if err != nil { dl.Close() return err @@ -972,7 +1040,7 @@ type zipFile struct { } func (f zipFile) Path() string { return f.name } -func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil } +func (f zipFile) Lstat() (fs.FileInfo, error) { return f.f.FileInfo(), nil } func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() } type dataFile struct { @@ -981,9 +1049,9 @@ type dataFile struct { } func (f dataFile) Path() string { return f.name } -func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil } +func (f dataFile) Lstat() (fs.FileInfo, error) { return dataFileInfo{f}, nil } func (f dataFile) Open() (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(f.data)), nil + return io.NopCloser(bytes.NewReader(f.data)), nil } type dataFileInfo struct { @@ -992,7 +1060,7 @@ type dataFileInfo struct { func (fi dataFileInfo) Name() string { return path.Base(fi.f.name) } func (fi dataFileInfo) Size() int64 { return int64(len(fi.f.data)) } -func (fi dataFileInfo) Mode() os.FileMode { return 0644 } +func (fi dataFileInfo) Mode() fs.FileMode { return 0644 } func (fi dataFileInfo) ModTime() time.Time { return time.Time{} } func (fi dataFileInfo) IsDir() bool { return false } func (fi dataFileInfo) Sys() interface{} { return nil } diff --git a/src/cmd/go/internal/modfetch/coderepo_test.go b/src/cmd/go/internal/modfetch/coderepo_test.go index f69c193b86..02e399f352 100644 --- a/src/cmd/go/internal/modfetch/coderepo_test.go +++ b/src/cmd/go/internal/modfetch/coderepo_test.go @@ -11,7 +11,6 @@ import ( "hash" "internal/testenv" "io" - "io/ioutil" "log" "os" "reflect" @@ -38,7 +37,7 @@ func testMain(m *testing.M) int { // code, bypass the sum database. cfg.GOSUMDB = "off" - dir, err := ioutil.TempDir("", "gitrepo-test-") + dir, err := os.MkdirTemp("", "gitrepo-test-") if err != nil { log.Fatal(err) } @@ -60,7 +59,6 @@ var altVgotests = map[string]string{ type codeRepoTest struct { vcs string path string - lookErr string mpath string rev string err string @@ -332,9 +330,9 @@ var codeRepoTests = []codeRepoTest{ // package in subdirectory - custom domain // In general we can't reject these definitively in Lookup, // but gopkg.in is special. - vcs: "git", - path: "gopkg.in/yaml.v2/abc", - lookErr: "invalid module path \"gopkg.in/yaml.v2/abc\"", + vcs: "git", + path: "gopkg.in/yaml.v2/abc", + err: "invalid module path \"gopkg.in/yaml.v2/abc\"", }, { // package in subdirectory - github @@ -425,7 +423,7 @@ var codeRepoTests = []codeRepoTest{ func TestCodeRepo(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "modfetch-test-") + tmpdir, err := os.MkdirTemp("", "modfetch-test-") if err != nil { t.Fatal(err) } @@ -440,16 +438,7 @@ func TestCodeRepo(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if tt.lookErr != "" { - if err != nil && err.Error() == tt.lookErr { - return - } - t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookErr) - } - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) if tt.mpath == "" { tt.mpath = tt.path @@ -501,9 +490,9 @@ func TestCodeRepo(t *testing.T) { needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "") if tt.zip != nil || tt.zipErr != "" || needHash { - f, err := ioutil.TempFile(tmpdir, tt.version+".zip.") + f, err := os.CreateTemp(tmpdir, tt.version+".zip.") if err != nil { - t.Fatalf("ioutil.TempFile: %v", err) + t.Fatalf("os.CreateTemp: %v", err) } zipfile := f.Name() defer func() { @@ -657,11 +646,6 @@ var codeRepoVersionsTests = []struct { }, { vcs: "git", - path: "gopkg.in/russross/blackfriday.v2", - versions: []string{"v2.0.0", "v2.0.1"}, - }, - { - vcs: "git", path: "gopkg.in/natefinch/lumberjack.v2", versions: []string{"v2.0.0"}, }, @@ -670,7 +654,7 @@ var codeRepoVersionsTests = []struct { func TestCodeRepoVersions(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") + tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-") if err != nil { t.Fatal(err) } @@ -685,10 +669,7 @@ func TestCodeRepoVersions(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) list, err := repo.Versions(tt.prefix) if err != nil { t.Fatalf("Versions(%q): %v", tt.prefix, err) @@ -747,7 +728,7 @@ var latestTests = []struct { func TestLatest(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") + tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-") if err != nil { t.Fatal(err) } @@ -763,10 +744,7 @@ func TestLatest(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) info, err := repo.Latest() if err != nil { if tt.err != "" { diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go index 01d8f007ac..debeb3f319 100644 --- a/src/cmd/go/internal/modfetch/fetch.go +++ b/src/cmd/go/internal/modfetch/fetch.go @@ -11,7 +11,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -63,14 +63,11 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) { ctx, span := trace.StartSpan(ctx, "modfetch.download "+mod.String()) defer span.Done() - // If the directory exists, and no .partial file exists, the module has - // already been completely extracted. .partial files may be created when a - // module zip directory is extracted in place instead of being extracted to a - // temporary directory and renamed. dir, err = DownloadDir(mod) if err == nil { + // The directory has already been completely extracted (no .partial file exists). return dir, nil - } else if dir == "" || !errors.Is(err, os.ErrNotExist) { + } else if dir == "" || !errors.Is(err, fs.ErrNotExist) { return "", err } @@ -88,6 +85,9 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) { } defer unlock() + ctx, span = trace.StartSpan(ctx, "unzip "+zipfile) + defer span.Done() + // Check whether the directory was populated while we were waiting on the lock. _, dirErr := DownloadDir(mod) if dirErr == nil { @@ -95,10 +95,11 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) { } _, dirExists := dirErr.(*DownloadDirPartialError) - // Clean up any remaining temporary directories from previous runs, as well - // as partially extracted diectories created by future versions of cmd/go. - // This is only safe to do because the lock file ensures that their writers - // are no longer active. + // Clean up any remaining temporary directories created by old versions + // (before 1.16), as well as partially extracted directories (indicated by + // DownloadDirPartialError, usually because of a .partial file). This is only + // safe to do because the lock file ensures that their writers are no longer + // active. parentDir := filepath.Dir(dir) tmpPrefix := filepath.Base(dir) + ".tmp-" if old, err := filepath.Glob(filepath.Join(parentDir, tmpPrefix+"*")); err == nil { @@ -116,88 +117,44 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) { if err != nil { return "", err } - if err := os.Remove(partialPath); err != nil && !os.IsNotExist(err) { - return "", err - } - // Extract the module zip directory. + // Extract the module zip directory at its final location. // - // By default, we extract to a temporary directory, then atomically rename to - // its final location. We use the existence of the source directory to signal - // that it has been extracted successfully (see DownloadDir). If someone - // deletes the entire directory (e.g., as an attempt to prune out file - // corruption), the module cache will still be left in a recoverable - // state. + // To prevent other processes from reading the directory if we crash, + // create a .partial file before extracting the directory, and delete + // the .partial file afterward (all while holding the lock). // - // Unfortunately, os.Rename may fail with ERROR_ACCESS_DENIED on Windows if - // another process opens files in the temporary directory. This is partially - // mitigated by using robustio.Rename, which retries os.Rename for a short - // time. + // Before Go 1.16, we extracted to a temporary directory with a random name + // then renamed it into place with os.Rename. On Windows, this failed with + // ERROR_ACCESS_DENIED when another process (usually an anti-virus scanner) + // opened files in the temporary directory. // - // To avoid this error completely, if unzipInPlace is set, we instead create a - // .partial file (indicating the directory isn't fully extracted), then we - // extract the directory at its final location, then we delete the .partial - // file. This is not the default behavior because older versions of Go may - // simply stat the directory to check whether it exists without looking for a - // .partial file. If multiple versions run concurrently, the older version may - // assume a partially extracted directory is complete. - // TODO(golang.org/issue/36568): when these older versions are no longer - // supported, remove the old default behavior and the unzipInPlace flag. + // Go 1.14.2 and higher respect .partial files. Older versions may use + // partially extracted directories. 'go mod verify' can detect this, + // and 'go clean -modcache' can fix it. if err := os.MkdirAll(parentDir, 0777); err != nil { return "", err } - - ctx, span = trace.StartSpan(ctx, "unzip "+zipfile) - if unzipInPlace { - if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil { - return "", err - } - if err := modzip.Unzip(dir, mod, zipfile); err != nil { - fmt.Fprintf(os.Stderr, "-> %s\n", err) - if rmErr := RemoveAll(dir); rmErr == nil { - os.Remove(partialPath) - } - return "", err - } - if err := os.Remove(partialPath); err != nil { - return "", err - } - } else { - tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix) - if err != nil { - return "", err - } - if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil { - fmt.Fprintf(os.Stderr, "-> %s\n", err) - RemoveAll(tmpDir) - return "", err - } - if err := robustio.Rename(tmpDir, dir); err != nil { - RemoveAll(tmpDir) - return "", err + if err := os.WriteFile(partialPath, nil, 0666); err != nil { + return "", err + } + if err := modzip.Unzip(dir, mod, zipfile); err != nil { + fmt.Fprintf(os.Stderr, "-> %s\n", err) + if rmErr := RemoveAll(dir); rmErr == nil { + os.Remove(partialPath) } + return "", err + } + if err := os.Remove(partialPath); err != nil { + return "", err } - defer span.Done() if !cfg.ModCacheRW { - // Make dir read-only only *after* renaming it. - // os.Rename was observed to fail for read-only directories on macOS. makeDirsReadOnly(dir) } return dir, nil } -var unzipInPlace bool - -func init() { - for _, f := range strings.Split(os.Getenv("GODEBUG"), ",") { - if f == "modcacheunzipinplace=1" { - unzipInPlace = true - break - } - } -} - var downloadZipCache par.Cache // DownloadZip downloads the specific module version to the @@ -265,7 +222,7 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e // contents of the file (by hashing it) before we commit it. Because the file // is zip-compressed, we need an actual file — or at least an io.ReaderAt — to // validate it: we can't just tee the stream as we write it. - f, err := ioutil.TempFile(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile))) + f, err := os.CreateTemp(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile))) if err != nil { return err } @@ -276,12 +233,28 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e } }() + var unrecoverableErr error err = TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, mod.Path) + if unrecoverableErr != nil { + return unrecoverableErr + } + repo := Lookup(proxy, mod.Path) + err := repo.Zip(f, mod.Version) if err != nil { - return err + // Zip may have partially written to f before failing. + // (Perhaps the server crashed while sending the file?) + // Since we allow fallback on error in some cases, we need to fix up the + // file to be empty again for the next attempt. + if _, err := f.Seek(0, io.SeekStart); err != nil { + unrecoverableErr = err + return err + } + if err := f.Truncate(0); err != nil { + unrecoverableErr = err + return err + } } - return repo.Zip(f, mod.Version) + return err }) if err != nil { return err @@ -341,12 +314,13 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e func makeDirsReadOnly(dir string) { type pathMode struct { path string - mode os.FileMode + mode fs.FileMode } var dirs []pathMode // in lexical order - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err == nil && info.Mode()&0222 != 0 { - if info.IsDir() { + filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err == nil && d.IsDir() { + info, err := d.Info() + if err == nil && info.Mode()&0222 != 0 { dirs = append(dirs, pathMode{path, info.Mode()}) } } @@ -363,7 +337,7 @@ func makeDirsReadOnly(dir string) { // any permission changes needed to do so. func RemoveAll(dir string) error { // Module cache has 0555 directories; make them writable in order to remove content. - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { if err != nil { return nil // ignore errors walking in file system } @@ -454,6 +428,28 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) error return nil } +// HaveSum returns true if the go.sum file contains an entry for mod. +// The entry's hash must be generated with a known hash algorithm. +// mod.Version may have a "/go.mod" suffix to distinguish sums for +// .mod and .zip files. +func HaveSum(mod module.Version) bool { + goSum.mu.Lock() + defer goSum.mu.Unlock() + inited, err := initGoSum() + if err != nil || !inited { + return false + } + for _, h := range goSum.m[mod] { + if !strings.HasPrefix(h, "h1:") { + continue + } + if !goSum.status[modSum{mod, h}].dirty { + return true + } + } + return false +} + // checkMod checks the given module's checksum. func checkMod(mod module.Version) { if cfg.GOMODCACHE == "" { @@ -468,7 +464,7 @@ func checkMod(mod module.Version) { } data, err := renameio.ReadFile(ziphash) if err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // This can happen if someone does rm -rf GOPATH/src/cache/download. So it goes. return } @@ -487,7 +483,7 @@ func checkMod(mod module.Version) { // goModSum returns the checksum for the go.mod contents. func goModSum(data []byte) (string, error) { return dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(data)), nil + return io.NopCloser(bytes.NewReader(data)), nil }) } @@ -852,16 +848,16 @@ the checksum database is not consulted, and all unrecognized modules are accepted, at the cost of giving up the security guarantee of verified repeatable downloads for all modules. A better way to bypass the checksum database for specific modules is to use the GOPRIVATE or GONOSUMDB environment -variables. See 'go help module-private' for details. +variables. See 'go help private' for details. The 'go env -w' command (see 'go help env') can be used to set these variables for future go command invocations. `, } -var HelpModulePrivate = &base.Command{ - UsageLine: "module-private", - Short: "module configuration for non-public modules", +var HelpPrivate = &base.Command{ + UsageLine: "private", + Short: "configuration for downloading non-public code", Long: ` The go command defaults to downloading modules from the public Go module mirror at proxy.golang.org. It also defaults to validating downloaded modules, @@ -902,6 +898,11 @@ be used for downloading both public and private modules, because GONOPROXY has been set to a pattern that won't match any modules, overriding GOPRIVATE. +The GOPRIVATE variable is also used to define the "public" and "private" +patterns for the GOVCS variable; see 'go help vcs'. For that usage, +GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths +instead of module paths. + The 'go env -w' command (see 'go help env') can be used to set these variables for future go command invocations. `, diff --git a/src/cmd/go/internal/modfetch/insecure.go b/src/cmd/go/internal/modfetch/insecure.go index b692669cba..012d05f29d 100644 --- a/src/cmd/go/internal/modfetch/insecure.go +++ b/src/cmd/go/internal/modfetch/insecure.go @@ -6,12 +6,11 @@ package modfetch import ( "cmd/go/internal/cfg" - "cmd/go/internal/get" "golang.org/x/mod/module" ) // allowInsecure reports whether we are allowed to fetch this path in an insecure manner. func allowInsecure(path string) bool { - return get.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, path) + return cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, path) } diff --git a/src/cmd/go/internal/modfetch/proxy.go b/src/cmd/go/internal/modfetch/proxy.go index 4ac26650a9..d75b4da521 100644 --- a/src/cmd/go/internal/modfetch/proxy.go +++ b/src/cmd/go/internal/modfetch/proxy.go @@ -9,9 +9,8 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" - "os" "path" pathpkg "path" "path/filepath" @@ -186,7 +185,7 @@ func proxyList() ([]proxySpec, error) { // TryProxies iterates f over each configured proxy (including "noproxy" and // "direct" if applicable) until f returns no error or until f returns an -// error that is not equivalent to os.ErrNotExist on a proxy configured +// error that is not equivalent to fs.ErrNotExist on a proxy configured // not to fall back on errors. // // TryProxies then returns that final error. @@ -222,7 +221,7 @@ func TryProxies(f func(proxy string) error) error { if err == nil { return nil } - isNotExistErr := errors.Is(err, os.ErrNotExist) + isNotExistErr := errors.Is(err, fs.ErrNotExist) if proxy.url == "direct" || (proxy.url == "noproxy" && err != errUseProxy) { bestErr = err @@ -305,7 +304,7 @@ func (p *proxyRepo) getBytes(path string) ([]byte, error) { return nil, err } defer body.Close() - return ioutil.ReadAll(body) + return io.ReadAll(body) } func (p *proxyRepo) getBody(path string) (io.ReadCloser, error) { @@ -428,7 +427,7 @@ func (p *proxyRepo) Stat(rev string) (*RevInfo, error) { func (p *proxyRepo) Latest() (*RevInfo, error) { data, err := p.getBytes("@latest") if err != nil { - if !errors.Is(err, os.ErrNotExist) { + if !errors.Is(err, fs.ErrNotExist) { return nil, p.versionError("", err) } return p.latest() diff --git a/src/cmd/go/internal/modfetch/pseudo.go b/src/cmd/go/internal/modfetch/pseudo.go index 20c0b060ab..93eb0fad96 100644 --- a/src/cmd/go/internal/modfetch/pseudo.go +++ b/src/cmd/go/internal/modfetch/pseudo.go @@ -76,6 +76,12 @@ func PseudoVersion(major, older string, t time.Time, rev string) string { return v + incDecimal(patch) + "-0." + segment + build } +// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and +// revision, which may be used as a placeholder. +func ZeroPseudoVersion(major string) string { + return PseudoVersion(major, "", time.Time{}, "000000000000") +} + // incDecimal returns the decimal string incremented by 1. func incDecimal(decimal string) string { // Scan right to left turning 9s to 0s until you find a digit to increment. @@ -120,6 +126,12 @@ func IsPseudoVersion(v string) bool { return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) } +// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, +// timestamp, and revision, as returned by ZeroPseudoVersion. +func IsZeroPseudoVersion(v string) bool { + return v == ZeroPseudoVersion(semver.Major(v)) +} + // PseudoVersionTime returns the time stamp of the pseudo-version v. // It returns an error if v is not a pseudo-version or if the time stamp // embedded in the pseudo-version is not a valid time. diff --git a/src/cmd/go/internal/modfetch/repo.go b/src/cmd/go/internal/modfetch/repo.go index 34f805d58a..af9e24cefd 100644 --- a/src/cmd/go/internal/modfetch/repo.go +++ b/src/cmd/go/internal/modfetch/repo.go @@ -7,15 +7,16 @@ package modfetch import ( "fmt" "io" + "io/fs" "os" "sort" "strconv" "time" "cmd/go/internal/cfg" - "cmd/go/internal/get" "cmd/go/internal/modfetch/codehost" "cmd/go/internal/par" + "cmd/go/internal/vcs" web "cmd/go/internal/web" "golang.org/x/mod/module" @@ -32,8 +33,17 @@ type Repo interface { // Versions lists all known versions with the given prefix. // Pseudo-versions are not included. + // // Versions should be returned sorted in semver order // (implementations can use SortVersions). + // + // Versions returns a non-nil error only if there was a problem + // fetching the list of versions: it may return an empty list + // along with a nil error if the list of matching versions + // is known to be empty. + // + // If the underlying repository does not exist, + // Versions returns an error matching errors.Is(_, os.NotExist). Versions(prefix string) ([]string, error) // Stat returns information about the revision rev. @@ -188,27 +198,26 @@ type lookupCacheKey struct { // // A successful return does not guarantee that the module // has any defined versions. -func Lookup(proxy, path string) (Repo, error) { +func Lookup(proxy, path string) Repo { if traceRepo { defer logCall("Lookup(%q, %q)", proxy, path)() } type cached struct { - r Repo - err error + r Repo } c := lookupCache.Do(lookupCacheKey{proxy, path}, func() interface{} { - r, err := lookup(proxy, path) - if err == nil { - if traceRepo { + r := newCachingRepo(path, func() (Repo, error) { + r, err := lookup(proxy, path) + if err == nil && traceRepo { r = newLoggingRepo(r) } - r = newCachingRepo(r) - } - return cached{r, err} + return r, err + }) + return cached{r} }).(cached) - return c.r, c.err + return c.r } // lookup returns the module with the given module path. @@ -228,7 +237,7 @@ func lookup(proxy, path string) (r Repo, err error) { switch proxy { case "off": - return nil, errProxyOff + return errRepo{path, errProxyOff}, nil case "direct": return lookupDirect(path) case "noproxy": @@ -261,13 +270,13 @@ func lookupDirect(path string) (Repo, error) { if allowInsecure(path) { security = web.Insecure } - rr, err := get.RepoRootForImportPath(path, get.PreferMod, security) + rr, err := vcs.RepoRootForImportPath(path, vcs.PreferMod, security) if err != nil { // We don't know where to find code for a module with this path. return nil, notExistError{err: err} } - if rr.VCS == "mod" { + if rr.VCS.Name == "mod" { // Fetch module from proxy with base URL rr.Repo. return newProxyRepo(rr.Repo, path) } @@ -279,8 +288,8 @@ func lookupDirect(path string) (Repo, error) { return newCodeRepo(code, rr.Root, path) } -func lookupCodeRepo(rr *get.RepoRoot) (codehost.Repo, error) { - code, err := codehost.NewRepo(rr.VCS, rr.Repo) +func lookupCodeRepo(rr *vcs.RepoRoot) (codehost.Repo, error) { + code, err := codehost.NewRepo(rr.VCS.Cmd, rr.Repo) if err != nil { if _, ok := err.(*codehost.VCSError); ok { return nil, err @@ -306,7 +315,7 @@ func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) { if allowInsecure(path) { security = web.Insecure } - rr, err := get.RepoRootForImportPath(path, get.IgnoreMod, security) + rr, err := vcs.RepoRootForImportPath(path, vcs.IgnoreMod, security) if err != nil { return nil, nil, err } @@ -407,7 +416,24 @@ func (l *loggingRepo) Zip(dst io.Writer, version string) error { return l.r.Zip(dst, version) } -// A notExistError is like os.ErrNotExist, but with a custom message +// errRepo is a Repo that returns the same error for all operations. +// +// It is useful in conjunction with caching, since cache hits will not attempt +// the prohibited operations. +type errRepo struct { + modulePath string + err error +} + +func (r errRepo) ModulePath() string { return r.modulePath } + +func (r errRepo) Versions(prefix string) (tags []string, err error) { return nil, r.err } +func (r errRepo) Stat(rev string) (*RevInfo, error) { return nil, r.err } +func (r errRepo) Latest() (*RevInfo, error) { return nil, r.err } +func (r errRepo) GoMod(version string) ([]byte, error) { return nil, r.err } +func (r errRepo) Zip(dst io.Writer, version string) error { return r.err } + +// A notExistError is like fs.ErrNotExist, but with a custom message type notExistError struct { err error } @@ -421,7 +447,7 @@ func (e notExistError) Error() string { } func (notExistError) Is(target error) bool { - return target == os.ErrNotExist + return target == fs.ErrNotExist } func (e notExistError) Unwrap() error { diff --git a/src/cmd/go/internal/modfetch/sumdb.go b/src/cmd/go/internal/modfetch/sumdb.go index 783c4a433b..4fbc54d15c 100644 --- a/src/cmd/go/internal/modfetch/sumdb.go +++ b/src/cmd/go/internal/modfetch/sumdb.go @@ -12,7 +12,8 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "io" + "io/fs" "net/url" "os" "path/filepath" @@ -22,7 +23,6 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/get" "cmd/go/internal/lockedfile" "cmd/go/internal/web" @@ -33,7 +33,7 @@ import ( // useSumDB reports whether to use the Go checksum database for the given module. func useSumDB(mod module.Version) bool { - return cfg.GOSUMDB != "off" && !get.Insecure && !module.MatchPrefixPatterns(cfg.GONOSUMDB, mod.Path) + return cfg.GOSUMDB != "off" && !cfg.Insecure && !module.MatchPrefixPatterns(cfg.GONOSUMDB, mod.Path) } // lookupSumDB returns the Go checksum database's go.sum lines for the given module, @@ -183,7 +183,7 @@ func (c *dbClient) initBase() { return nil } }) - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // No proxies, or all proxies failed (with 404, 410, or were were allowed // to fall back), or we reached an explicit "direct" or "off". c.base = c.direct @@ -204,7 +204,7 @@ func (c *dbClient) ReadConfig(file string) (data []byte, err error) { } targ := filepath.Join(cfg.SumdbDir, file) data, err = lockedfile.Read(targ) - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // Treat non-existent as empty, to bootstrap the "latest" file // the first time we connect to a given database. return []byte{}, nil @@ -228,7 +228,7 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { return err } defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) if err != nil { return err } @@ -258,7 +258,7 @@ func (*dbClient) ReadCache(file string) ([]byte, error) { // during which the empty file can be locked for reading. // Treat observing an empty file as file not found. if err == nil && len(data) == 0 { - err = &os.PathError{Op: "read", Path: targ, Err: os.ErrNotExist} + err = &fs.PathError{Op: "read", Path: targ, Err: fs.ErrNotExist} } return data, err } diff --git a/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go b/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go index 82398ebfed..d9ba8ef2da 100644 --- a/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go +++ b/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go @@ -24,7 +24,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -81,7 +80,7 @@ func TestZipSums(t *testing.T) { if *modCacheDir != "" { cfg.BuildContext.GOPATH = *modCacheDir } else { - tmpDir, err := ioutil.TempDir("", "TestZipSums") + tmpDir, err := os.MkdirTemp("", "TestZipSums") if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go index 4ca7f5b529..e5f55879ee 100644 --- a/src/cmd/go/internal/modget/get.go +++ b/src/cmd/go/internal/modget/get.go @@ -5,26 +5,47 @@ // Package modget implements the module-aware ``go get'' command. package modget +// The arguments to 'go get' are patterns with optional version queries, with +// the version queries defaulting to "upgrade". +// +// The patterns are normally interpreted as package patterns. However, if a +// pattern cannot match a package, it is instead interpreted as a *module* +// pattern. For version queries such as "upgrade" and "patch" that depend on the +// selected version of a module (or of the module containing a package), +// whether a pattern denotes a package or module may change as updates are +// applied (see the example in mod_get_patchmod.txt). +// +// There are a few other ambiguous cases to resolve, too. A package can exist in +// two different modules at the same version: for example, the package +// example.com/foo might be found in module example.com and also in module +// example.com/foo, and those modules may have independent v0.1.0 tags — so the +// input 'example.com/foo@v0.1.0' could syntactically refer to the variant of +// the package loaded from either module! (See mod_get_ambiguous_pkg.txt.) +// If the argument is ambiguous, the user can often disambiguate by specifying +// explicit versions for *all* of the potential module paths involved. + import ( "context" "errors" "fmt" "os" "path/filepath" + "reflect" "runtime" "sort" "strings" "sync" "cmd/go/internal/base" - "cmd/go/internal/get" + "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/load" "cmd/go/internal/modload" - "cmd/go/internal/mvs" + "cmd/go/internal/par" "cmd/go/internal/search" "cmd/go/internal/work" + "golang.org/x/mod/modfile" "golang.org/x/mod/module" "golang.org/x/mod/semver" ) @@ -70,15 +91,15 @@ downgrades the dependency. The version suffix @none indicates that the dependency should be removed entirely, downgrading or removing modules depending on it as needed. -The version suffix @latest explicitly requests the latest minor release of the -module named by the given path. The suffix @upgrade is like @latest but +The version suffix @latest explicitly requests the latest minor release of +the module named by the given path. The suffix @upgrade is like @latest but will not downgrade a module if it is already required at a revision or pre-release version newer than the latest released version. The suffix @patch requests the latest patch release: the latest released version with the same major and minor version numbers as the currently required version. Like @upgrade, @patch will not downgrade a module already required -at a newer version. If the path is not already required, @upgrade and @patch -are equivalent to @latest. +at a newer version. If the path is not already required, @upgrade is +equivalent to @latest, and @patch is disallowed. Although get defaults to using the latest version of the module containing a named package, it does not use the latest version of that module's @@ -115,14 +136,27 @@ require downgrading other dependencies, and 'go get' does this automatically as well. The -insecure flag permits fetching from repositories and resolving -custom domains using insecure schemes such as HTTP. Use with caution. The -GOINSECURE environment variable is usually a better alternative, since it -provides control over which modules may be retrieved using an insecure scheme. -See 'go help environment' for details. +custom domains using insecure schemes such as HTTP, and also bypassess +module sum validation using the checksum database. Use with caution. +This flag is deprecated and will be removed in a future version of go. +To permit the use of insecure schemes, use the GOINSECURE environment +variable instead. To bypass module sum validation, use GOPRIVATE or +GONOSUMDB. See 'go help environment' for details. The second step is to download (if needed), build, and install the named packages. +The -d flag instructs get to skip this step, downloading source code +needed to build the named packages and their dependencies, but not +building or installing. + +Building and installing packages with get is deprecated. In a future release, +the -d flag will be enabled by default, and 'go get' will be only be used to +adjust dependencies of the current module. To install a package using +dependencies from the current module, use 'go install'. To install a package +ignoring the current module, use 'go install' with an @version suffix like +"@latest" after each argument. + If an argument names a module but not a package (because there is no Go source code in the module's root directory), then the install step is skipped for that argument, instead of causing a build failure. @@ -134,10 +168,6 @@ the module versions. For example, 'go get golang.org/x/perf/cmd/...' adds the latest golang.org/x/perf and then installs the commands in that latest version. -The -d flag instructs get to download the source code needed to build -the named packages, including downloading necessary dependencies, -but not to build and install them. - With no package arguments, 'go get' applies to Go package in the current directory, if any. In particular, 'go get -u' and 'go get -u=patch' update all the dependencies of that package. @@ -174,6 +204,82 @@ Usage: ` + CmdGet.UsageLine + ` ` + CmdGet.Long, } +var HelpVCS = &base.Command{ + UsageLine: "vcs", + Short: "controlling version control with GOVCS", + Long: ` +The 'go get' command can run version control commands like git +to download imported code. This functionality is critical to the decentralized +Go package ecosystem, in which code can be imported from any server, +but it is also a potential security problem, if a malicious server finds a +way to cause the invoked version control command to run unintended code. + +To balance the functionality and security concerns, the 'go get' command +by default will only use git and hg to download code from public servers. +But it will use any known version control system (bzr, fossil, git, hg, svn) +to download code from private servers, defined as those hosting packages +matching the GOPRIVATE variable (see 'go help private'). The rationale behind +allowing only Git and Mercurial is that these two systems have had the most +attention to issues of being run as clients of untrusted servers. In contrast, +Bazaar, Fossil, and Subversion have primarily been used in trusted, +authenticated environments and are not as well scrutinized as attack surfaces. + +The version control command restrictions only apply when using direct version +control access to download code. When downloading modules from a proxy, +'go get' uses the proxy protocol instead, which is always permitted. +By default, the 'go get' command uses the Go module mirror (proxy.golang.org) +for public packages and only falls back to version control for private +packages or when the mirror refuses to serve a public package (typically for +legal reasons). Therefore, clients can still access public code served from +Bazaar, Fossil, or Subversion repositories by default, because those downloads +use the Go module mirror, which takes on the security risk of running the +version control commands, using a custom sandbox. + +The GOVCS variable can be used to change the allowed version control systems +for specific packages (identified by a module or import path). +The GOVCS variable applies both when using modules and when using GOPATH. +When using modules, the patterns match against the module path. +When using GOPATH, the patterns match against the import path +corresponding to the root of the version control repository. + +The general form of the GOVCS setting is a comma-separated list of +pattern:vcslist rules. The pattern is a glob pattern that must match +one or more leading elements of the module or import path. The vcslist +is a pipe-separated list of allowed version control commands, or "all" +to allow use of any known command, or "off" to allow nothing. +The earliest matching pattern in the list applies, even if later patterns +might also match. + +For example, consider: + + GOVCS=github.com:git,evil.com:off,*:git|hg + +With this setting, code with an module or import path beginning with +github.com/ can only use git; paths on evil.com cannot use any version +control command, and all other paths (* matches everything) can use +only git or hg. + +The special patterns "public" and "private" match public and private +module or import paths. A path is private if it matches the GOPRIVATE +variable; otherwise it is public. + +If no rules in the GOVCS variable match a particular module or import path, +the 'go get' command applies its default rule, which can now be summarized +in GOVCS notation as 'public:git|hg,private:all'. + +To allow unfettered use of any version control system for any package, use: + + GOVCS=*:all + +To disable all use of version control, use: + + GOVCS=*:off + +The 'go env -w' command (see 'go help env') can be used to set the GOVCS +variable for future go command invocations. +`, +} + var ( getD = CmdGet.Flag.Bool("d", false, "") getF = CmdGet.Flag.Bool("f", false, "") @@ -181,23 +287,29 @@ var ( getM = CmdGet.Flag.Bool("m", false, "") getT = CmdGet.Flag.Bool("t", false, "") getU upgradeFlag - // -insecure is get.Insecure + // -insecure is cfg.Insecure // -v is cfg.BuildV ) // upgradeFlag is a custom flag.Value for -u. -type upgradeFlag string +type upgradeFlag struct { + rawVersion string + version string +} func (*upgradeFlag) IsBoolFlag() bool { return true } // allow -u func (v *upgradeFlag) Set(s string) error { if s == "false" { - s = "" + v.version = "" + v.rawVersion = "" + } else if s == "true" { + v.version = "upgrade" + v.rawVersion = "" + } else { + v.version = s + v.rawVersion = s } - if s == "true" { - s = "upgrade" - } - *v = upgradeFlag(s) return nil } @@ -206,66 +318,16 @@ func (v *upgradeFlag) String() string { return "" } func init() { work.AddBuildFlags(CmdGet, work.OmitModFlag) CmdGet.Run = runGet // break init loop - CmdGet.Flag.BoolVar(&get.Insecure, "insecure", get.Insecure, "") + CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "") CmdGet.Flag.Var(&getU, "u", "") } -// A getArg holds a parsed positional argument for go get (path@vers). -type getArg struct { - // raw is the original argument, to be printed in error messages. - raw string - - // path is the part of the argument before "@" (or the whole argument - // if there is no "@"). path specifies the modules or packages to get. - path string - - // vers is the part of the argument after "@" or an implied - // "upgrade" or "patch" if there is no "@". vers specifies the - // module version to get. - vers string -} - -// querySpec describes a query for a specific module. path may be a -// module path, package path, or package pattern. vers is a version -// query string from a command line argument. -type querySpec struct { - // path is a module path, package path, or package pattern that - // specifies which module to query. - path string - - // vers specifies what version of the module to get. - vers string - - // forceModulePath is true if path should be interpreted as a module path. - // If forceModulePath is true, prevM must be set. - forceModulePath bool - - // prevM is the previous version of the module. prevM is needed - // to determine the minor version number if vers is "patch". It's also - // used to avoid downgrades from prerelease versions newer than - // "latest" and "patch". If prevM is set, forceModulePath must be true. - prevM module.Version -} - -// query holds the state for a query made for a specific module. -// After a query is performed, we know the actual module path and -// version and whether any packages were matched by the query path. -type query struct { - querySpec - - // arg is the command line argument that matched the specified module. - arg string - - // m is the module path and version found by the query. - m module.Version -} - func runGet(ctx context.Context, cmd *base.Command, args []string) { - switch getU { + switch getU.version { case "", "upgrade", "patch": // ok default: - base.Fatalf("go get: unknown upgrade flag -u=%s", getU) + base.Fatalf("go get: unknown upgrade flag -u=%s", getU.rawVersion) } if *getF { fmt.Fprintf(os.Stderr, "go get: -f flag is a no-op when using modules\n") @@ -276,839 +338,1392 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) { if *getM { base.Fatalf("go get: -m flag is no longer supported; consider -d to skip building packages") } - modload.LoadTests = *getT - - buildList := modload.LoadBuildList(ctx) - buildList = buildList[:len(buildList):len(buildList)] // copy on append - versionByPath := make(map[string]string) - for _, m := range buildList { - versionByPath[m.Path] = m.Version + if cfg.Insecure { + fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n") } + load.ModResolveTests = *getT // Do not allow any updating of go.mod until we've applied // all the requested changes and checked that the result matches // what was requested. modload.DisallowWriteGoMod() - // Allow looking up modules for import paths outside of a module. + // Allow looking up modules for import paths when outside of a module. // 'go get' is expected to do this, unlike other commands. modload.AllowMissingModuleImports() - // Parse command-line arguments and report errors. The command-line - // arguments are of the form path@version or simply path, with implicit - // @upgrade. path@none is "downgrade away". - var gets []getArg - var queries []*query - for _, arg := range search.CleanPatterns(args) { - // Argument is path or path@vers. - path := arg - vers := "" - if i := strings.Index(arg, "@"); i >= 0 { - path, vers = arg[:i], arg[i+1:] + modload.LoadModFile(ctx) // Initializes modload.Target. + + queries := parseArgs(ctx, args) + + r := newResolver(ctx, queries) + r.performLocalQueries(ctx) + r.performPathQueries(ctx) + + for { + r.performWildcardQueries(ctx) + r.performPatternAllQueries(ctx) + + if changed := r.resolveCandidates(ctx, queries, nil); changed { + // 'go get' arguments can be (and often are) package patterns rather than + // (just) modules. A package can be provided by any module with a prefix + // of its import path, and a wildcard can even match packages in modules + // with totally different paths. Because of these effects, and because any + // change to the selected version of a module can bring in entirely new + // module paths as dependencies, we need to reissue queries whenever we + // change the build list. + // + // The result of any version query for a given module — even "upgrade" or + // "patch" — is always relative to the build list at the start of + // the 'go get' command, not an intermediate state, and is therefore + // dederministic and therefore cachable, and the constraints on the + // selected version of each module can only narrow as we iterate. + // + // "all" is functionally very similar to a wildcard pattern. The set of + // packages imported by the main module does not change, and the query + // result for the module containing each such package also does not change + // (it is always relative to the initial build list, before applying + // queries). So the only way that the result of an "all" query can change + // is if some matching package moves from one module in the build list + // to another, which should not happen very often. + continue + } + + // When we load imports, we detect the following conditions: + // + // - missing transitive depencies that need to be resolved from outside the + // current build list (note that these may add new matches for existing + // pattern queries!) + // + // - transitive dependencies that didn't match any other query, + // but need to be upgraded due to the -u flag + // + // - ambiguous import errors. + // TODO(#27899): Try to resolve ambiguous import errors automatically. + upgrades := r.findAndUpgradeImports(ctx, queries) + if changed := r.resolveCandidates(ctx, nil, upgrades); changed { + continue + } + + r.findMissingWildcards(ctx) + if changed := r.resolveCandidates(ctx, r.wildcardQueries, nil); changed { + continue } - if strings.Contains(vers, "@") || arg != path && vers == "" { - base.Errorf("go get %s: invalid module version syntax", arg) + + break + } + + r.checkWildcardVersions(ctx) + + var pkgPatterns []string + for _, q := range queries { + if q.matchesPackages { + pkgPatterns = append(pkgPatterns, q.pattern) + } + } + r.checkPackagesAndRetractions(ctx, pkgPatterns) + + // We've already downloaded modules (and identified direct and indirect + // dependencies) by loading packages in findAndUpgradeImports. + // So if -d is set, we're done after the module work. + // + // Otherwise, we need to build and install the packages matched by + // command line arguments. + // Note that 'go get -u' without arguments is equivalent to + // 'go get -u .', so we'll typically build the package in the current + // directory. + if !*getD && len(pkgPatterns) > 0 { + work.BuildInit() + pkgs := load.PackagesForBuild(ctx, pkgPatterns) + work.InstallPackages(ctx, pkgPatterns, pkgs) + // TODO(#40276): After Go 1.16, print a deprecation notice when building + // and installing main packages. 'go install pkg' or + // 'go install pkg@version' should be used instead. + } + + if !modload.HasModRoot() { + return + } + + // Everything succeeded. Update go.mod. + oldReqs := reqsFromGoMod(modload.ModFile()) + + modload.AllowWriteGoMod() + modload.WriteGoMod() + modload.DisallowWriteGoMod() + + newReqs := reqsFromGoMod(modload.ModFile()) + r.reportChanges(oldReqs, newReqs) +} + +// parseArgs parses command-line arguments and reports errors. +// +// The command-line arguments are of the form path@version or simply path, with +// implicit @upgrade. path@none is "downgrade away". +func parseArgs(ctx context.Context, rawArgs []string) []*query { + defer base.ExitIfErrors() + + var queries []*query + for _, arg := range search.CleanPatterns(rawArgs) { + q, err := newQuery(arg) + if err != nil { + base.Errorf("go get: %v", err) continue } + // If there were no arguments, CleanPatterns returns ".". Set the raw + // string back to "" for better errors. + if len(rawArgs) == 0 { + q.raw = "" + } + // Guard against 'go get x.go', a common mistake. // Note that package and module paths may end with '.go', so only print an error // if the argument has no version and either has no slash or refers to an existing file. - if strings.HasSuffix(arg, ".go") && vers == "" { - if !strings.Contains(arg, "/") { - base.Errorf("go get %s: arguments must be package or module paths", arg) + if strings.HasSuffix(q.raw, ".go") && q.rawVersion == "" { + if !strings.Contains(q.raw, "/") { + base.Errorf("go get %s: arguments must be package or module paths", q.raw) continue } - if fi, err := os.Stat(arg); err == nil && !fi.IsDir() { - base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg) + if fi, err := os.Stat(q.raw); err == nil && !fi.IsDir() { + base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", q.raw) continue } } - // If no version suffix is specified, assume @upgrade. - // If -u=patch was specified, assume @patch instead. - if vers == "" { - if getU != "" { - vers = string(getU) + queries = append(queries, q) + } + + return queries +} + +type resolver struct { + localQueries []*query // queries for absolute or relative paths + pathQueries []*query // package path literal queries in original order + wildcardQueries []*query // path wildcard queries in original order + patternAllQueries []*query // queries with the pattern "all" + + // Indexed "none" queries. These are also included in the slices above; + // they are indexed here to speed up noneForPath. + nonesByPath map[string]*query // path-literal "@none" queries indexed by path + wildcardNones []*query // wildcard "@none" queries + + // resolvedVersion maps each module path to the version of that module that + // must be selected in the final build list, along with the first query + // that resolved the module to that version (the “reason”). + resolvedVersion map[string]versionReason + + buildList []module.Version + buildListResolvedVersions int // len(resolvedVersion) when buildList was computed + buildListVersion map[string]string // index of buildList (module path → version) + + initialVersion map[string]string // index of the initial build list at the start of 'go get' + + missing []pathSet // candidates for missing transitive dependencies + + work *par.Queue + + matchInModuleCache par.Cache +} + +type versionReason struct { + version string + reason *query +} + +func newResolver(ctx context.Context, queries []*query) *resolver { + buildList := modload.LoadAllModules(ctx) + initialVersion := make(map[string]string, len(buildList)) + for _, m := range buildList { + initialVersion[m.Path] = m.Version + } + + r := &resolver{ + work: par.NewQueue(runtime.GOMAXPROCS(0)), + resolvedVersion: map[string]versionReason{}, + buildList: buildList, + buildListVersion: initialVersion, + initialVersion: initialVersion, + nonesByPath: map[string]*query{}, + } + + for _, q := range queries { + if q.pattern == "all" { + r.patternAllQueries = append(r.patternAllQueries, q) + } else if q.patternIsLocal { + r.localQueries = append(r.localQueries, q) + } else if q.isWildcard() { + r.wildcardQueries = append(r.wildcardQueries, q) + } else { + r.pathQueries = append(r.pathQueries, q) + } + + if q.version == "none" { + // Index "none" queries to make noneForPath more efficient. + if q.isWildcard() { + r.wildcardNones = append(r.wildcardNones, q) } else { - vers = "upgrade" + // All "<path>@none" queries for the same path are identical; we only + // need to index one copy. + r.nonesByPath[q.pattern] = q } } + } - gets = append(gets, getArg{raw: arg, path: path, vers: vers}) + return r +} - // Determine the modules that path refers to, and create queries - // to lookup modules at target versions before loading packages. - // This is an imprecise process, but it helps reduce unnecessary - // queries and package loading. It's also necessary for handling - // patterns like golang.org/x/tools/..., which can't be expanded - // during package loading until they're in the build list. - switch { - case filepath.IsAbs(path) || search.IsRelativePath(path): - // Absolute paths like C:\foo and relative paths like ../foo... - // are restricted to matching packages in the main module. If the path - // is explicit and contains no wildcards (...), check that it is a - // package in the main module. If the path contains wildcards but - // matches no packages, we'll warn after package loading. - if !strings.Contains(path, "...") { - m := search.NewMatch(path) - if pkgPath := modload.DirImportPath(path); pkgPath != "." { - m = modload.TargetPackages(ctx, pkgPath) - } - if len(m.Pkgs) == 0 { - for _, err := range m.Errs { - base.Errorf("go get %s: %v", arg, err) - } +// initialSelected returns the version of the module with the given path that +// was selected at the start of this 'go get' invocation. +func (r *resolver) initialSelected(mPath string) (version string) { + v, ok := r.initialVersion[mPath] + if !ok { + return "none" + } + return v +} - abs, err := filepath.Abs(path) - if err != nil { - abs = path - } - base.Errorf("go get %s: path %s is not a package in module rooted at %s", arg, abs, modload.ModRoot()) - continue - } - } +// selected returns the version of the module with the given path that is +// selected in the resolver's current build list. +func (r *resolver) selected(mPath string) (version string) { + v, ok := r.buildListVersion[mPath] + if !ok { + return "none" + } + return v +} - if path != arg { - base.Errorf("go get %s: can't request explicit version of path in main module", arg) - continue - } +// noneForPath returns a "none" query matching the given module path, +// or found == false if no such query exists. +func (r *resolver) noneForPath(mPath string) (nq *query, found bool) { + if nq = r.nonesByPath[mPath]; nq != nil { + return nq, true + } + for _, nq := range r.wildcardNones { + if nq.matchesPath(mPath) { + return nq, true + } + } + return nil, false +} - case strings.Contains(path, "..."): - // Wait until we load packages to look up modules. - // We don't know yet whether any modules in the build list provide - // packages matching the pattern. For example, suppose - // golang.org/x/tools and golang.org/x/tools/playground are separate - // modules, and only golang.org/x/tools is in the build list. If the - // user runs 'go get golang.org/x/tools/playground/...', we should - // add a requirement for golang.org/x/tools/playground. We should not - // upgrade golang.org/x/tools. +// queryModule wraps modload.Query, substituting r.checkAllowedOr to decide +// allowed versions. +func (r *resolver) queryModule(ctx context.Context, mPath, query string, selected func(string) string) (module.Version, error) { + current := r.initialSelected(mPath) + rev, err := modload.Query(ctx, mPath, query, current, r.checkAllowedOr(query, selected)) + if err != nil { + return module.Version{}, err + } + return module.Version{Path: mPath, Version: rev.Version}, nil +} - case path == "all": - // If there is no main module, "all" is not meaningful. - if !modload.HasModRoot() { - base.Errorf(`go get %s: cannot match "all": working directory is not part of a module`, arg) +// queryPackage wraps modload.QueryPackage, substituting r.checkAllowedOr to +// decide allowed versions. +func (r *resolver) queryPackages(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, err error) { + results, err := modload.QueryPackages(ctx, pattern, query, selected, r.checkAllowedOr(query, selected)) + if len(results) > 0 { + pkgMods = make([]module.Version, 0, len(results)) + for _, qr := range results { + pkgMods = append(pkgMods, qr.Mod) + } + } + return pkgMods, err +} + +// queryPattern wraps modload.QueryPattern, substituting r.checkAllowedOr to +// decide allowed versions. +func (r *resolver) queryPattern(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, mod module.Version, err error) { + results, modOnly, err := modload.QueryPattern(ctx, pattern, query, selected, r.checkAllowedOr(query, selected)) + if len(results) > 0 { + pkgMods = make([]module.Version, 0, len(results)) + for _, qr := range results { + pkgMods = append(pkgMods, qr.Mod) + } + } + if modOnly != nil { + mod = modOnly.Mod + } + return pkgMods, mod, err +} + +// checkAllowedOr is like modload.CheckAllowed, but it always allows the requested +// and current versions (even if they are retracted or otherwise excluded). +func (r *resolver) checkAllowedOr(requested string, selected func(string) string) modload.AllowedFunc { + return func(ctx context.Context, m module.Version) error { + if m.Version == requested { + return modload.CheckExclusions(ctx, m) + } + if (requested == "upgrade" || requested == "patch") && m.Version == selected(m.Path) { + return nil + } + return modload.CheckAllowed(ctx, m) + } +} + +// matchInModule is a caching wrapper around modload.MatchInModule. +func (r *resolver) matchInModule(ctx context.Context, pattern string, m module.Version) (packages []string, err error) { + type key struct { + pattern string + m module.Version + } + type entry struct { + packages []string + err error + } + + e := r.matchInModuleCache.Do(key{pattern, m}, func() interface{} { + match := modload.MatchInModule(ctx, pattern, m, imports.AnyTags()) + if len(match.Errs) > 0 { + return entry{match.Pkgs, match.Errs[0]} + } + return entry{match.Pkgs, nil} + }).(entry) + + return e.packages, e.err +} + +// queryNone adds a candidate set to q for each module matching q.pattern. +// Each candidate set has only one possible module version: the matched +// module at version "none". +// +// We interpret arguments to 'go get' as packages first, and fall back to +// modules second. However, no module exists at version "none", and therefore no +// package exists at that version either: we know that the argument cannot match +// any packages, and thus it must match modules instead. +func (r *resolver) queryNone(ctx context.Context, q *query) { + if search.IsMetaPackage(q.pattern) { + panic(fmt.Sprintf("internal error: queryNone called with pattern %q", q.pattern)) + } + + if !q.isWildcard() { + q.pathOnce(q.pattern, func() pathSet { + if modload.HasModRoot() && q.pattern == modload.Target.Path { + // The user has explicitly requested to downgrade their own module to + // version "none". This is not an entirely unreasonable request: it + // could plausibly mean “downgrade away everything that depends on any + // explicit version of the main module”, or “downgrade away the + // package with the same path as the main module, found in a module + // with a prefix of the main module's path”. + // + // However, neither of those behaviors would be consistent with the + // plain meaning of the query. To try to reduce confusion, reject the + // query explicitly. + return errSet(&modload.QueryMatchesMainModuleError{Pattern: q.pattern, Query: q.version}) } - // Don't query modules until we load packages. We'll automatically - // look up any missing modules. - case search.IsMetaPackage(path): - base.Errorf("go get %s: explicit requirement on standard-library module %s not allowed", path, path) + return pathSet{mod: module.Version{Path: q.pattern, Version: "none"}} + }) + } + + for _, curM := range r.buildList { + if !q.matchesPath(curM.Path) { continue + } + q.pathOnce(curM.Path, func() pathSet { + if modload.HasModRoot() && curM == modload.Target { + return errSet(&modload.QueryMatchesMainModuleError{Pattern: q.pattern, Query: q.version}) + } + return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}} + }) + } +} - default: - // The argument is a package or module path. - if modload.HasModRoot() { - if m := modload.TargetPackages(ctx, path); len(m.Pkgs) != 0 { - // The path is in the main module. Nothing to query. - if vers != "upgrade" && vers != "patch" { - base.Errorf("go get %s: can't request explicit version of path in main module", arg) - } - continue +func (r *resolver) performLocalQueries(ctx context.Context) { + for _, q := range r.localQueries { + q.pathOnce(q.pattern, func() pathSet { + absDetail := "" + if !filepath.IsAbs(q.pattern) { + if absPath, err := filepath.Abs(q.pattern); err == nil { + absDetail = fmt.Sprintf(" (%s)", absPath) } } - first := path - if i := strings.IndexByte(first, '/'); i >= 0 { - first = path + // Absolute paths like C:\foo and relative paths like ../foo... are + // restricted to matching packages in the main module. + pkgPattern := modload.DirImportPath(q.pattern) + if pkgPattern == "." { + return errSet(fmt.Errorf("%s%s is not within module rooted at %s", q.pattern, absDetail, modload.ModRoot())) } - if !strings.Contains(first, ".") { - // The path doesn't have a dot in the first component and cannot be - // queried as a module. It may be a package in the standard library, - // which is fine, so don't report an error unless we encounter - // a problem loading packages below. - continue + + match := modload.MatchInModule(ctx, pkgPattern, modload.Target, imports.AnyTags()) + if len(match.Errs) > 0 { + return pathSet{err: match.Errs[0]} } - // If we're querying "upgrade" or "patch", we need to know the current - // version of the module. For "upgrade", we want to avoid accidentally - // downgrading from a newer prerelease. For "patch", we need to query - // the correct minor version. - // Here, we check if "path" is the name of a module in the build list - // (other than the main module) and set prevM if so. If "path" isn't - // a module in the build list, the current version doesn't matter - // since it's either an unknown module or a package within a module - // that we'll discover later. - q := &query{querySpec: querySpec{path: path, vers: vers}, arg: arg} - if v, ok := versionByPath[path]; ok && path != modload.Target.Path { - q.prevM = module.Version{Path: path, Version: v} - q.forceModulePath = true + if len(match.Pkgs) == 0 { + if q.raw == "" || q.raw == "." { + return errSet(fmt.Errorf("no package in current directory")) + } + if !q.isWildcard() { + return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.ModRoot())) + } + search.WarnUnmatched([]*search.Match{match}) + return pathSet{} } - queries = append(queries, q) - } - } - base.ExitIfErrors() - // Query modules referenced by command line arguments at requested versions. - // We need to do this before loading packages since patterns that refer to - // packages in unknown modules can't be expanded. This also avoids looking - // up new modules while loading packages, only to downgrade later. - queryCache := make(map[querySpec]*query) - byPath := runQueries(ctx, queryCache, queries, nil) + return pathSet{pkgMods: []module.Version{modload.Target}} + }) + } +} - // Add missing modules to the build list. - // We call SetBuildList here and elsewhere, since newUpgrader, - // ImportPathsQuiet, and other functions read the global build list. - for _, q := range queries { - if _, ok := versionByPath[q.m.Path]; !ok && q.m.Version != "none" { - buildList = append(buildList, q.m) - } +// performWildcardQueries populates the candidates for each query whose pattern +// is a wildcard. +// +// The candidates for a given module path matching (or containing a package +// matching) a wildcard query depend only on the initial build list, but the set +// of modules may be expanded by other queries, so wildcard queries need to be +// re-evaluated whenever a potentially-matching module path is added to the +// build list. +func (r *resolver) performWildcardQueries(ctx context.Context) { + for _, q := range r.wildcardQueries { + q := q + r.work.Add(func() { + if q.version == "none" { + r.queryNone(ctx, q) + } else { + r.queryWildcard(ctx, q) + } + }) } - versionByPath = nil // out of date now; rebuilt later when needed - modload.SetBuildList(buildList) + <-r.work.Idle() +} - // Upgrade modules specifically named on the command line. This is our only - // chance to upgrade modules without root packages (modOnly below). - // This also skips loading packages at an old version, only to upgrade - // and reload at a new version. - upgrade := make(map[string]*query) - for path, q := range byPath { - if q.path == q.m.Path && q.m.Version != "none" { - upgrade[path] = q +// queryWildcard adds a candidate set to q for each module for which: +// - some version of the module is already in the build list, and +// - that module exists at some version matching q.version, and +// - either the module path itself matches q.pattern, or some package within +// the module at q.version matches q.pattern. +func (r *resolver) queryWildcard(ctx context.Context, q *query) { + // For wildcard patterns, modload.QueryPattern only identifies modules + // matching the prefix of the path before the wildcard. However, the build + // list may already contain other modules with matching packages, and we + // should consider those modules to satisfy the query too. + // We want to match any packages in existing dependencies, but we only want to + // resolve new dependencies if nothing else turns up. + for _, curM := range r.buildList { + if !q.canMatchInModule(curM.Path) { + continue } + q.pathOnce(curM.Path, func() pathSet { + if _, hit := r.noneForPath(curM.Path); hit { + // This module is being removed, so it will no longer be in the build list + // (and thus will no longer match the pattern). + return pathSet{} + } + + if curM.Path == modload.Target.Path && !versionOkForMainModule(q.version) { + if q.matchesPath(curM.Path) { + return errSet(&modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + }) + } + + packages, err := r.matchInModule(ctx, q.pattern, curM) + if err != nil { + return errSet(err) + } + if len(packages) > 0 { + return errSet(&modload.QueryMatchesPackagesInMainModuleError{ + Pattern: q.pattern, + Query: q.version, + Packages: packages, + }) + } + + return r.tryWildcard(ctx, q, curM) + } + + m, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected) + if err != nil { + if !isNoSuchModuleVersion(err) { + // We can't tell whether a matching version exists. + return errSet(err) + } + // There is no version of curM.Path matching the query. + + // We haven't checked whether curM contains any matching packages at its + // currently-selected version, or whether curM.Path itself matches q. If + // either of those conditions holds, *and* no other query changes the + // selected version of curM, then we will fail in checkWildcardVersions. + // (This could be an error, but it's too soon to tell.) + // + // However, even then the transitive requirements of some other query + // may downgrade this module out of the build list entirely, in which + // case the pattern will no longer include it and it won't be an error. + // + // Either way, punt on the query rather than erroring out just yet. + return pathSet{} + } + + return r.tryWildcard(ctx, q, m) + }) } - buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(upgrade, nil)) + + // Even if no modules matched, we shouldn't query for a new module to provide + // the pattern yet: some other query may yet induce a new requirement that + // will match the wildcard. Instead, we'll check in findMissingWildcards. +} + +// tryWildcard returns a pathSet for module m matching query q. +// If m does not actually match q, tryWildcard returns an empty pathSet. +func (r *resolver) tryWildcard(ctx context.Context, q *query, m module.Version) pathSet { + mMatches := q.matchesPath(m.Path) + packages, err := r.matchInModule(ctx, q.pattern, m) if err != nil { - base.Fatalf("go get: %v", err) + return errSet(err) } - modload.SetBuildList(buildList) - base.ExitIfErrors() - prevBuildList := buildList + if len(packages) > 0 { + return pathSet{pkgMods: []module.Version{m}} + } + if mMatches { + return pathSet{mod: m} + } + return pathSet{} +} - // Build a set of module paths that we don't plan to load packages from. - // This includes explicitly requested modules that don't have a root package - // and modules with a target version of "none". - var wg sync.WaitGroup - var modOnlyMu sync.Mutex - modOnly := make(map[string]*query) - for _, q := range queries { - if q.m.Version == "none" { - modOnlyMu.Lock() - modOnly[q.m.Path] = q - modOnlyMu.Unlock() - continue +// findMissingWildcards adds a candidate set for each query in r.wildcardQueries +// that has not yet resolved to any version containing packages. +func (r *resolver) findMissingWildcards(ctx context.Context) { + for _, q := range r.wildcardQueries { + if q.version == "none" || q.matchesPackages { + continue // q is not “missing” } - if q.path == q.m.Path { - wg.Add(1) - go func(q *query) { - if hasPkg, err := modload.ModuleHasRootPackage(ctx, q.m); err != nil { - base.Errorf("go get: %v", err) - } else if !hasPkg { - modOnlyMu.Lock() - modOnly[q.m.Path] = q - modOnlyMu.Unlock() + r.work.Add(func() { + q.pathOnce(q.pattern, func() pathSet { + pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected) + if err != nil { + if isNoSuchPackageVersion(err) && len(q.resolved) > 0 { + // q already resolved one or more modules but matches no packages. + // That's ok: this pattern is just a module pattern, and we don't + // need to add any more modules to satisfy it. + return pathSet{} + } + return errSet(err) } - wg.Done() - }(q) - } - } - wg.Wait() - base.ExitIfErrors() - // Build a list of arguments that may refer to packages. - var pkgPatterns []string - var pkgGets []getArg - for _, arg := range gets { - if modOnly[arg.path] == nil && arg.vers != "none" { - pkgPatterns = append(pkgPatterns, arg.path) - pkgGets = append(pkgGets, arg) - } + return pathSet{pkgMods: pkgMods, mod: mod} + }) + }) } + <-r.work.Idle() +} - // Load packages and upgrade the modules that provide them. We do this until - // we reach a fixed point, since modules providing packages may change as we - // change versions. This must terminate because the module graph is finite, - // and the load and upgrade operations may only add and upgrade modules - // in the build list. - var matches []*search.Match - for { - var seenPkgs map[string]bool - seenQuery := make(map[querySpec]bool) - var queries []*query - addQuery := func(q *query) { - if !seenQuery[q.querySpec] { - seenQuery[q.querySpec] = true - queries = append(queries, q) +// checkWildcardVersions reports an error if any module in the build list has a +// path (or contains a package) matching a query with a wildcard pattern, but +// has a selected version that does *not* match the query. +func (r *resolver) checkWildcardVersions(ctx context.Context) { + defer base.ExitIfErrors() + + for _, q := range r.wildcardQueries { + for _, curM := range r.buildList { + if !q.canMatchInModule(curM.Path) { + continue + } + if !q.matchesPath(curM.Path) { + packages, err := r.matchInModule(ctx, q.pattern, curM) + if len(packages) == 0 { + if err != nil { + reportError(q, err) + } + continue // curM is not relevant to q. + } } - } - if len(pkgPatterns) > 0 { - // Don't load packages if pkgPatterns is empty. Both - // modload.ImportPathsQuiet and ModulePackages convert an empty list - // of patterns to []string{"."}, which is not what we want. - matches = modload.ImportPathsQuiet(ctx, pkgPatterns, imports.AnyTags()) - seenPkgs = make(map[string]bool) - for i, match := range matches { - arg := pkgGets[i] + rev, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected) + if err != nil { + reportError(q, err) + continue + } + if rev.Version == curM.Version { + continue // curM already matches q. + } - if len(match.Pkgs) == 0 { - // If the pattern did not match any packages, look up a new module. - // If the pattern doesn't match anything on the last iteration, - // we'll print a warning after the outer loop. - if !match.IsLocal() && !match.IsLiteral() && arg.path != "all" { - addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw}) - } else { - for _, err := range match.Errs { - base.Errorf("go get: %v", err) - } - } + if !q.matchesPath(curM.Path) { + m := module.Version{Path: curM.Path, Version: rev.Version} + packages, err := r.matchInModule(ctx, q.pattern, m) + if err != nil { + reportError(q, err) continue } - - allStd := true - for _, pkg := range match.Pkgs { - if !seenPkgs[pkg] { - seenPkgs[pkg] = true - if _, _, err := modload.Lookup("", false, pkg); err != nil { - allStd = false - base.Errorf("go get %s: %v", arg.raw, err) - continue - } + if len(packages) == 0 { + // curM at its original version contains a path matching q.pattern, + // but at rev.Version it does not, so (somewhat paradoxically) if + // we changed the version of curM it would no longer match the query. + var version interface{} = m + if rev.Version != q.version { + version = fmt.Sprintf("%s@%s (%s)", m.Path, q.version, m.Version) } - m := modload.PackageModule(pkg) - if m.Path == "" { - // pkg is in the standard library. - continue - } - allStd = false - if m.Path == modload.Target.Path { - // pkg is in the main module. - continue - } - addQuery(&query{querySpec: querySpec{path: m.Path, vers: arg.vers, forceModulePath: true, prevM: m}, arg: arg.raw}) - } - if allStd && arg.path != arg.raw { - base.Errorf("go get %s: cannot use pattern %q with explicit version", arg.raw, arg.raw) + reportError(q, fmt.Errorf("%v matches packages in %v but not %v: specify a different version for module %s", q, curM, version, m.Path)) + continue } } + + // Since queryModule succeeded and either curM or one of the packages it + // contains matches q.pattern, we should have either selected the version + // of curM matching q, or reported a conflict error (and exited). + // If we're still here and the version doesn't match, + // something has gone very wrong. + reportError(q, fmt.Errorf("internal error: selected %v instead of %v", curM, rev.Version)) } - base.ExitIfErrors() + } +} - // Query target versions for modules providing packages matched by - // command line arguments. - byPath = runQueries(ctx, queryCache, queries, modOnly) +// performPathQueries populates the candidates for each query whose pattern is +// a path literal. +// +// The candidate packages and modules for path literals depend only on the +// initial build list, not the current build list, so we only need to query path +// literals once. +func (r *resolver) performPathQueries(ctx context.Context) { + for _, q := range r.pathQueries { + q := q + r.work.Add(func() { + if q.version == "none" { + r.queryNone(ctx, q) + } else { + r.queryPath(ctx, q) + } + }) + } + <-r.work.Idle() +} - // Handle upgrades. This is needed for arguments that didn't match - // modules or matched different modules from a previous iteration. It - // also upgrades modules providing package dependencies if -u is set. - buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(byPath, seenPkgs)) - if err != nil { - base.Fatalf("go get: %v", err) +// queryPath adds a candidate set to q for the package with path q.pattern. +// The candidate set consists of all modules that could provide q.pattern +// and have a version matching q, plus (if it exists) the module whose path +// is itself q.pattern (at a matching version). +func (r *resolver) queryPath(ctx context.Context, q *query) { + q.pathOnce(q.pattern, func() pathSet { + if search.IsMetaPackage(q.pattern) || q.isWildcard() { + panic(fmt.Sprintf("internal error: queryPath called with pattern %q", q.pattern)) } - modload.SetBuildList(buildList) - base.ExitIfErrors() + if q.version == "none" { + panic(`internal error: queryPath called with version "none"`) + } + + if search.IsStandardImportPath(q.pattern) { + stdOnly := module.Version{} + packages, _ := r.matchInModule(ctx, q.pattern, stdOnly) + if len(packages) > 0 { + if q.rawVersion != "" { + return errSet(fmt.Errorf("can't request explicit version %q of standard library package %s", q.version, q.pattern)) + } - // Stop if no changes have been made to the build list. - buildList = modload.BuildList() - eq := len(buildList) == len(prevBuildList) - for i := 0; eq && i < len(buildList); i++ { - eq = buildList[i] == prevBuildList[i] + q.matchesPackages = true + return pathSet{} // No module needed for standard library. + } } - if eq { - break + + pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected) + if err != nil { + return errSet(err) } - prevBuildList = buildList - } - if !*getD { - // Only print warnings after the last iteration, - // and only if we aren't going to build. - search.WarnUnmatched(matches) + return pathSet{pkgMods: pkgMods, mod: mod} + }) +} + +// performPatternAllQueries populates the candidates for each query whose +// pattern is "all". +// +// The candidate modules for a given package in "all" depend only on the initial +// build list, but we cannot follow the dependencies of a given package until we +// know which candidate is selected — and that selection may depend on the +// results of other queries. We need to re-evaluate the "all" queries whenever +// the module for one or more packages in "all" are resolved. +func (r *resolver) performPatternAllQueries(ctx context.Context) { + if len(r.patternAllQueries) == 0 { + return } - // Handle downgrades. - var down []module.Version - for _, m := range modload.BuildList() { - q := byPath[m.Path] - if q != nil && semver.Compare(m.Version, q.m.Version) > 0 { - down = append(down, module.Version{Path: m.Path, Version: q.m.Version}) + findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) { + versionOk = true + for _, q := range r.patternAllQueries { + q.pathOnce(path, func() pathSet { + pkgMods, err := r.queryPackages(ctx, path, q.version, r.initialSelected) + if len(pkgMods) != 1 || pkgMods[0] != m { + // There are candidates other than m for the given path, so we can't + // be certain that m will actually be the module selected to provide + // the package. Don't load its dependencies just yet, because they + // might no longer be dependencies after we resolve the correct + // version. + versionOk = false + } + return pathSet{pkgMods: pkgMods, err: err} + }) } + return versionOk } - if len(down) > 0 { - buildList, err := mvs.Downgrade(modload.Target, modload.Reqs(), down...) - if err != nil { - base.Fatalf("go: %v", err) - } - modload.SetBuildList(buildList) - modload.ReloadBuildList() // note: does not update go.mod - base.ExitIfErrors() + + r.loadPackages(ctx, []string{"all"}, findPackage) + + // Since we built up the candidate lists concurrently, they may be in a + // nondeterministic order. We want 'go get' to be fully deterministic, + // including in which errors it chooses to report, so sort the candidates + // into a deterministic-but-arbitrary order. + for _, q := range r.patternAllQueries { + sort.Slice(q.candidates, func(i, j int) bool { + return q.candidates[i].path < q.candidates[j].path + }) } +} - // Scan for any upgrades lost by the downgrades. - var lostUpgrades []*query - if len(down) > 0 { - versionByPath = make(map[string]string) - for _, m := range modload.BuildList() { - versionByPath[m.Path] = m.Version - } - for _, q := range byPath { - if v, ok := versionByPath[q.m.Path]; q.m.Version != "none" && (!ok || semver.Compare(v, q.m.Version) != 0) { - lostUpgrades = append(lostUpgrades, q) - } +// findAndUpgradeImports returns a pathSet for each package that is not yet +// in the build list but is transitively imported by the packages matching the +// given queries (which must already have been resolved). +// +// If the getU flag ("-u") is set, findAndUpgradeImports also returns a +// pathSet for each module that is not constrained by any other +// command-line argument and has an available matching upgrade. +func (r *resolver) findAndUpgradeImports(ctx context.Context, queries []*query) (upgrades []pathSet) { + patterns := make([]string, 0, len(queries)) + for _, q := range queries { + if q.matchesPackages { + patterns = append(patterns, q.pattern) } - sort.Slice(lostUpgrades, func(i, j int) bool { - return lostUpgrades[i].m.Path < lostUpgrades[j].m.Path - }) } - if len(lostUpgrades) > 0 { - desc := func(m module.Version) string { - s := m.Path + "@" + m.Version - t := byPath[m.Path] - if t != nil && t.arg != s { - s += " from " + t.arg + if len(patterns) == 0 { + return nil + } + + // mu guards concurrent writes to upgrades, which will be sorted + // (to restore determinism) after loading. + var mu sync.Mutex + + findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) { + version := "latest" + if m.Path != "" { + if getU.version == "" { + // The user did not request that we upgrade transitive dependencies. + return true } - return s - } - downByPath := make(map[string]module.Version) - for _, d := range down { - downByPath[d.Path] = d + if _, ok := r.resolvedVersion[m.Path]; ok { + // We cannot upgrade m implicitly because its version is determined by + // an explicit pattern argument. + return true + } + version = getU.version } - var buf strings.Builder - fmt.Fprintf(&buf, "go get: inconsistent versions:") - reqs := modload.Reqs() - for _, q := range lostUpgrades { - // We lost q because its build list requires a newer version of something in down. - // Figure out exactly what. - // Repeatedly constructing the build list is inefficient - // if there are MANY command-line arguments, - // but at least all the necessary requirement lists are cached at this point. - list, err := buildListForLostUpgrade(q.m, reqs) - if err != nil { - base.Fatalf("go: %v", err) - } + // Unlike other queries, the "-u" flag upgrades relative to the build list + // after applying changes so far, not the initial build list. + // This is for two reasons: + // + // - The "-u" flag intentionally applies to transitive dependencies, + // which may not be known or even resolved in advance of applying + // other version changes. + // + // - The "-u" flag, unlike other arguments, does not cause version + // conflicts with other queries. (The other query always wins.) - fmt.Fprintf(&buf, "\n\t%s", desc(q.m)) - sep := " requires" - for _, m := range list { - if down, ok := downByPath[m.Path]; ok && semver.Compare(down.Version, m.Version) < 0 { - fmt.Fprintf(&buf, "%s %s@%s (not %s)", sep, m.Path, m.Version, desc(down)) - sep = "," - } + pkgMods, err := r.queryPackages(ctx, path, version, r.selected) + for _, u := range pkgMods { + if u == m { + // The selected package version is already upgraded appropriately; there + // is no need to change it. + return true } - if sep != "," { - // We have no idea why this happened. - // At least report the problem. - if v := versionByPath[q.m.Path]; v == "" { - fmt.Fprintf(&buf, " removed unexpectedly") - } else { - fmt.Fprintf(&buf, " ended up at %s unexpectedly", v) - } - fmt.Fprintf(&buf, " (please report at golang.org/issue/new)") + } + + if err != nil { + if isNoSuchPackageVersion(err) || (m.Path == "" && module.CheckPath(path) != nil) { + // We can't find the package because it doesn't — or can't — even exist + // in any module at the latest version. (Note that invalid module paths + // could in general exist due to replacements, so we at least need to + // run the query to check those.) + // + // There is no version change we can make to fix the package, so leave + // it unresolved. Either some other query (perhaps a wildcard matching a + // newly-added dependency for some other missing package) will fill in + // the gaps, or we will report an error (with a better import stack) in + // the final LoadPackages call. + return true } } - base.Fatalf("%v", buf.String()) - } - // Everything succeeded. Update go.mod. - modload.AllowWriteGoMod() - modload.WriteGoMod() - modload.DisallowWriteGoMod() + mu.Lock() + upgrades = append(upgrades, pathSet{path: path, pkgMods: pkgMods, err: err}) + mu.Unlock() + return false + } - // Report warnings if any retracted versions are in the build list. - // This must be done after writing go.mod to avoid spurious '// indirect' - // comments. These functions read and write global state. - // TODO(golang.org/issue/40775): ListModules resets modload.loader, which - // contains information about direct dependencies that WriteGoMod uses. - // Refactor to avoid these kinds of global side effects. - reportRetractions(ctx) + r.loadPackages(ctx, patterns, findPackage) - // If -d was specified, we're done after the module work. - // We've already downloaded modules by loading packages above. - // Otherwise, we need to build and install the packages matched by - // command line arguments. This may be a different set of packages, - // since we only build packages for the target platform. - // Note that 'go get -u' without arguments is equivalent to - // 'go get -u .', so we'll typically build the package in the current - // directory. - if *getD || len(pkgPatterns) == 0 { - return - } - work.BuildInit() - pkgs := load.PackagesForBuild(ctx, pkgPatterns) - work.InstallPackages(ctx, pkgPatterns, pkgs) + // Since we built up the candidate lists concurrently, they may be in a + // nondeterministic order. We want 'go get' to be fully deterministic, + // including in which errors it chooses to report, so sort the candidates + // into a deterministic-but-arbitrary order. + sort.Slice(upgrades, func(i, j int) bool { + return upgrades[i].path < upgrades[j].path + }) + return upgrades } -// runQueries looks up modules at target versions in parallel. Results will be -// cached. If the same module is referenced by multiple queries at different -// versions (including earlier queries in the modOnly map), an error will be -// reported. A map from module paths to queries is returned, which includes -// queries and modOnly. -func runQueries(ctx context.Context, cache map[querySpec]*query, queries []*query, modOnly map[string]*query) map[string]*query { +// loadPackages loads the packages matching the given patterns, invoking the +// findPackage function for each package that may require a change to the +// build list. +// +// loadPackages invokes the findPackage function for each package loaded from a +// module outside the main module. If the module or version that supplies that +// package needs to be changed due to a query, findPackage may return false +// and the imports of that package will not be loaded. +// +// loadPackages also invokes the findPackage function for each imported package +// that is neither present in the standard library nor in any module in the +// build list. +func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPackage func(ctx context.Context, path string, m module.Version) (versionOk bool)) { + opts := modload.PackageOpts{ + Tags: imports.AnyTags(), + LoadTests: *getT, + SilenceErrors: true, // May be fixed by subsequent upgrades or downgrades. + } - runQuery := func(q *query) { - if q.vers == "none" { - // Wait for downgrade step. - q.m = module.Version{Path: q.path, Version: "none"} - return + opts.AllowPackage = func(ctx context.Context, path string, m module.Version) error { + if m.Path == "" || m == modload.Target { + // Packages in the standard library and main module are already at their + // latest (and only) available versions. + return nil } - m, err := getQuery(ctx, q.path, q.vers, q.prevM, q.forceModulePath) - if err != nil { - base.Errorf("go get %s: %v", q.arg, err) + if ok := findPackage(ctx, path, m); !ok { + return errVersionChange } - q.m = m + return nil } - type token struct{} - sem := make(chan token, runtime.GOMAXPROCS(0)) - for _, q := range queries { - if cached := cache[q.querySpec]; cached != nil { - *q = *cached - } else { - sem <- token{} - go func(q *query) { - runQuery(q) - <-sem - }(q) + _, pkgs := modload.LoadPackages(ctx, opts, patterns...) + for _, path := range pkgs { + const ( + parentPath = "" + parentIsStd = false + ) + _, _, err := modload.Lookup(parentPath, parentIsStd, path) + if err == nil { + continue + } + if errors.Is(err, errVersionChange) { + // We already added candidates during loading. + continue } - } - // Fill semaphore channel to wait for goroutines to finish. - for n := cap(sem); n > 0; n-- { - sem <- token{} - } + var ( + importMissing *modload.ImportMissingError + ambiguous *modload.AmbiguousImportError + ) + if !errors.As(err, &importMissing) && !errors.As(err, &ambiguous) { + // The package, which is a dependency of something we care about, has some + // problem that we can't resolve with a version change. + // Leave the error for the final LoadPackages call. + continue + } - // Add to cache after concurrent section to avoid races... - for _, q := range queries { - cache[q.querySpec] = q + path := path + r.work.Add(func() { + findPackage(ctx, path, module.Version{}) + }) } + <-r.work.Idle() +} - base.ExitIfErrors() +// errVersionChange is a sentinel error indicating that a module's version needs +// to be updated before its dependencies can be loaded. +var errVersionChange = errors.New("version change needed") + +// resolveCandidates resolves candidates sets that are attached to the given +// queries and/or needed to provide the given missing-package dependencies. +// +// resolveCandidates starts by resolving one module version from each +// unambiguous pathSet attached to the given queries. +// +// If no unambiguous query results in a change to the build list, +// resolveCandidates modifies the build list by adding one module version from +// each pathSet in missing, but does not mark those versions as resolved +// (so they can still be modified by other queries). +// +// If that still does not result in any changes to the build list, +// resolveCandidates revisits the ambiguous query candidates and resolves them +// arbitrarily in order to guarantee forward progress. +// +// If all pathSets are resolved without any changes to the build list, +// resolveCandidates returns with changed=false. +func (r *resolver) resolveCandidates(ctx context.Context, queries []*query, upgrades []pathSet) (changed bool) { + defer base.ExitIfErrors() + + // Note: this is O(N²) with the number of pathSets in the worst case. + // + // We could perhaps get it down to O(N) if we were to index the pathSets + // by module path, so that we only revisit a given pathSet when the + // version of some module in its containingPackage list has been determined. + // + // However, N tends to be small, and most candidate sets will include only one + // candidate module (so they will be resolved in the first iteration), so for + // now we'll stick to the simple O(N²) approach. - byPath := make(map[string]*query) - check := func(q *query) { - if prev, ok := byPath[q.m.Path]; prev != nil && prev.m != q.m { - base.Errorf("go get: conflicting versions for module %s: %s and %s", q.m.Path, prev.m.Version, q.m.Version) - byPath[q.m.Path] = nil // sentinel to stop errors - return - } else if !ok { - byPath[q.m.Path] = q + resolved := 0 + for { + prevResolved := resolved + + for _, q := range queries { + unresolved := q.candidates[:0] + + for _, cs := range q.candidates { + if cs.err != nil { + reportError(q, cs.err) + resolved++ + continue + } + + filtered, isPackage, m, unique := r.disambiguate(cs) + if !unique { + unresolved = append(unresolved, filtered) + continue + } + + if m.Path == "" { + // The query is not viable. Choose an arbitrary candidate from + // before filtering and “resolve” it to report a conflict. + isPackage, m = r.chooseArbitrarily(cs) + } + if isPackage { + q.matchesPackages = true + } + r.resolve(q, m) + resolved++ + } + + q.candidates = unresolved + } + + base.ExitIfErrors() + if resolved == prevResolved { + break // No unambiguous candidate remains. } } - for _, q := range queries { - check(q) + + if changed := r.updateBuildList(ctx, nil); changed { + // The build list has changed, so disregard any missing packages: they might + // now be determined by requirements in the build list, which we would + // prefer to use instead of arbitrary "latest" versions. + return true } - for _, q := range modOnly { - check(q) + + // Arbitrarily add a "latest" version that provides each missing package, but + // do not mark the version as resolved: we still want to allow the explicit + // queries to modify the resulting versions. + var tentative []module.Version + for _, cs := range upgrades { + if cs.err != nil { + base.Errorf("go get: %v", cs.err) + continue + } + + filtered, _, m, unique := r.disambiguate(cs) + if !unique { + _, m = r.chooseArbitrarily(filtered) + } + if m.Path == "" { + // There is no viable candidate for the missing package. + // Leave it unresolved. + continue + } + tentative = append(tentative, m) } base.ExitIfErrors() + if changed := r.updateBuildList(ctx, tentative); changed { + return true + } - return byPath + // The build list will be the same on the next iteration as it was on this + // iteration, so any ambiguous queries will remain so. In order to make + // progress, resolve them arbitrarily but deterministically. + // + // If that results in conflicting versions, the user can re-run 'go get' + // with additional explicit versions for the conflicting packages or + // modules. + for _, q := range queries { + for _, cs := range q.candidates { + isPackage, m := r.chooseArbitrarily(cs) + if isPackage { + q.matchesPackages = true + } + r.resolve(q, m) + } + } + return r.updateBuildList(ctx, nil) } -// getQuery evaluates the given (package or module) path and version -// to determine the underlying module version being requested. -// If forceModulePath is set, getQuery must interpret path -// as a module path. -func getQuery(ctx context.Context, path, vers string, prevM module.Version, forceModulePath bool) (module.Version, error) { - if (prevM.Version != "") != forceModulePath { - // We resolve package patterns by calling QueryPattern, which does not - // accept a previous version and therefore cannot take it into account for - // the "latest" or "patch" queries. - // If we are resolving a package path or pattern, the caller has already - // resolved any existing packages to their containing module(s), and - // will set both prevM.Version and forceModulePath for those modules. - // The only remaining package patterns are those that are not already - // provided by the build list, which are indicated by - // an empty prevM.Version. - base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set") +// disambiguate eliminates candidates from cs that conflict with other module +// versions that have already been resolved. If there is only one (unique) +// remaining candidate, disambiguate returns that candidate, along with +// an indication of whether that result interprets cs.path as a package +// +// Note: we're only doing very simple disambiguation here. The goal is to +// reproduce the user's intent, not to find a solution that a human couldn't. +// In the vast majority of cases, we expect only one module per pathSet, +// but we want to give some minimal additional tools so that users can add an +// extra argument or two on the command line to resolve simple ambiguities. +func (r *resolver) disambiguate(cs pathSet) (filtered pathSet, isPackage bool, m module.Version, unique bool) { + if len(cs.pkgMods) == 0 && cs.mod.Path == "" { + panic("internal error: resolveIfUnambiguous called with empty pathSet") } - // If vers is a query like "latest", we should ignore retracted and excluded - // versions. If vers refers to a specific version or commit like "v1.0.0" - // or "master", we should only ignore excluded versions. - allowed := modload.CheckAllowed - if modload.IsRevisionQuery(vers) { - allowed = modload.CheckExclusions - } + for _, m := range cs.pkgMods { + if _, ok := r.noneForPath(m.Path); ok { + // A query with version "none" forces the candidate module to version + // "none", so we cannot use any other version for that module. + continue + } - // If the query must be a module path, try only that module path. - if forceModulePath { - if path == modload.Target.Path { - if vers != "latest" { - return module.Version{}, fmt.Errorf("can't get a specific version of the main module") + if m.Path == modload.Target.Path { + if m.Version == modload.Target.Version { + return pathSet{}, true, m, true } + // The main module can only be set to its own version. + continue } - info, err := modload.Query(ctx, path, vers, prevM.Version, allowed) - if err == nil { - if info.Version != vers && info.Version != prevM.Version { - logOncef("go: %s %s => %s", path, vers, info.Version) - } - return module.Version{Path: path, Version: info.Version}, nil + vr, ok := r.resolvedVersion[m.Path] + if !ok { + // m is a viable answer to the query, but other answers may also + // still be viable. + filtered.pkgMods = append(filtered.pkgMods, m) + continue } - // If the query was "upgrade" or "patch" and the current version has been - // replaced, check to see whether the error was for that same version: - // if so, the version was probably replaced because it is invalid, - // and we should keep that replacement without complaining. - if vers == "upgrade" || vers == "patch" { - var vErr *module.InvalidVersionError - if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" { - return prevM, nil - } + if vr.version != m.Version { + // Some query forces the candidate module to a version other than this + // one. + // + // The command could be something like + // + // go get example.com/foo/bar@none example.com/foo/bar/baz@latest + // + // in which case we *cannot* resolve the package from + // example.com/foo/bar (because it is constrained to version + // "none") and must fall through to module example.com/foo@latest. + continue } - return module.Version{}, err + // Some query forces the candidate module *to* the candidate version. + // As a result, this candidate is the only viable choice to provide + // its package(s): any other choice would result in an ambiguous import + // for this path. + // + // For example, consider the command + // + // go get example.com/foo@latest example.com/foo/bar/baz@latest + // + // If modules example.com/foo and example.com/foo/bar both provide + // package example.com/foo/bar/baz, then we *must* resolve the package + // from example.com/foo: if we instead resolved it from + // example.com/foo/bar, we would have two copies of the package. + return pathSet{}, true, m, true } - // If the query may be either a package or a module, try it as a package path. - // If it turns out to only exist as a module, we can detect the resulting - // PackageNotInModuleError and avoid a second round-trip through (potentially) - // all of the configured proxies. - results, err := modload.QueryPattern(ctx, path, vers, allowed) - if err != nil { - // If the path doesn't contain a wildcard, check whether it was actually a - // module path instead. If so, return that. - if !strings.Contains(path, "...") { - var modErr *modload.PackageNotInModuleError - if errors.As(err, &modErr) && modErr.Mod.Path == path { - if modErr.Mod.Version != vers { - logOncef("go: %s %s => %s", path, vers, modErr.Mod.Version) - } - return modErr.Mod, nil - } + if cs.mod.Path != "" { + vr, ok := r.resolvedVersion[cs.mod.Path] + if !ok || vr.version == cs.mod.Version { + filtered.mod = cs.mod } + } - return module.Version{}, err + if len(filtered.pkgMods) == 1 && + (filtered.mod.Path == "" || filtered.mod == filtered.pkgMods[0]) { + // Exactly one viable module contains the package with the given path + // (by far the common case), so we can resolve it unambiguously. + return pathSet{}, true, filtered.pkgMods[0], true } - m := results[0].Mod - if m.Path != path { - logOncef("go: found %s in %s %s", path, m.Path, m.Version) - } else if m.Version != vers { - logOncef("go: %s %s => %s", path, vers, m.Version) + if len(filtered.pkgMods) == 0 { + // All modules that could provide the path as a package conflict with other + // resolved arguments. If it can refer to a module instead, return that; + // otherwise, this pathSet cannot be resolved (and we will return the + // zero module.Version). + return pathSet{}, false, filtered.mod, true } - return m, nil + + // The query remains ambiguous: there are at least two different modules + // to which cs.path could refer. + return filtered, false, module.Version{}, false } -// An upgrader adapts an underlying mvs.Reqs to apply an -// upgrade policy to a list of targets and their dependencies. -type upgrader struct { - mvs.Reqs +// chooseArbitrarily returns an arbitrary (but deterministic) module version +// from among those in the given set. +// +// chooseArbitrarily prefers module paths that were already in the build list at +// the start of 'go get', prefers modules that provide packages over those that +// do not, and chooses the first module meeting those criteria (so biases toward +// longer paths). +func (r *resolver) chooseArbitrarily(cs pathSet) (isPackage bool, m module.Version) { + // Prefer to upgrade some module that was already in the build list. + for _, m := range cs.pkgMods { + if r.initialSelected(m.Path) != "none" { + return true, m + } + } - // cmdline maps a module path to a query made for that module at a - // specific target version. Each query corresponds to a module - // matched by a command line argument. - cmdline map[string]*query + // Otherwise, arbitrarily choose the first module that provides the package. + if len(cs.pkgMods) > 0 { + return true, cs.pkgMods[0] + } - // upgrade is a set of modules providing dependencies of packages - // matched by command line arguments. If -u or -u=patch is set, - // these modules are upgraded accordingly. - upgrade map[string]bool + return false, cs.mod } -// newUpgrader creates an upgrader. cmdline contains queries made at -// specific versions for modules matched by command line arguments. pkgs -// is the set of packages matched by command line arguments. If -u or -u=patch -// is set, modules providing dependencies of pkgs are upgraded accordingly. -func newUpgrader(cmdline map[string]*query, pkgs map[string]bool) *upgrader { - u := &upgrader{ - Reqs: modload.Reqs(), - cmdline: cmdline, +// checkPackagesAndRetractions reloads packages for the given patterns and +// reports missing and ambiguous package errors. It also reports loads and +// reports retractions for resolved modules and modules needed to build +// named packages. +// +// We skip missing-package errors earlier in the process, since we want to +// resolve pathSets ourselves, but at that point, we don't have enough context +// to log the package-import chains leading to each error. +func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns []string) { + defer base.ExitIfErrors() + + // Build a list of modules to load retractions for. Start with versions + // selected based on command line queries. + // + // This is a subset of the build list. If the main module has a lot of + // dependencies, loading retractions for the entire build list would be slow. + relevantMods := make(map[module.Version]struct{}) + for path, reason := range r.resolvedVersion { + relevantMods[module.Version{Path: path, Version: reason.version}] = struct{}{} } - if getU != "" { - u.upgrade = make(map[string]bool) - // Traverse package import graph. - // Initialize work queue with root packages. - seen := make(map[string]bool) - var work []string - add := func(path string) { - if !seen[path] { - seen[path] = true - work = append(work, path) - } + // Reload packages, reporting errors for missing and ambiguous imports. + if len(pkgPatterns) > 0 { + // LoadPackages will print errors (since it has more context) but will not + // exit, since we need to load retractions later. + pkgOpts := modload.PackageOpts{ + LoadTests: *getT, + ResolveMissingImports: false, + AllowErrors: true, } - for pkg := range pkgs { - add(pkg) + matches, pkgs := modload.LoadPackages(ctx, pkgOpts, pkgPatterns...) + for _, m := range matches { + if len(m.Errs) > 0 { + base.SetExitStatus(1) + break + } } - for len(work) > 0 { - pkg := work[0] - work = work[1:] - m := modload.PackageModule(pkg) - u.upgrade[m.Path] = true - - // testImports is empty unless test imports were actually loaded, - // i.e., -t was set or "all" was one of the arguments. - imports, testImports := modload.PackageImports(pkg) - for _, imp := range imports { - add(imp) + for _, pkg := range pkgs { + if _, _, err := modload.Lookup("", false, pkg); err != nil { + base.SetExitStatus(1) + if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) { + for _, m := range ambiguousErr.Modules { + relevantMods[m] = struct{}{} + } + } } - for _, imp := range testImports { - add(imp) + if m := modload.PackageModule(pkg); m.Path != "" { + relevantMods[m] = struct{}{} } } } - return u -} -// Required returns the requirement list for m. -// For the main module, we override requirements with the modules named -// one the command line, and we include new requirements. Otherwise, -// we defer to u.Reqs. -func (u *upgrader) Required(m module.Version) ([]module.Version, error) { - rs, err := u.Reqs.Required(m) - if err != nil { - return nil, err + // Load and report retractions. + type retraction struct { + m module.Version + err error } - if m != modload.Target { - return rs, nil + retractions := make([]retraction, 0, len(relevantMods)) + for m := range relevantMods { + retractions = append(retractions, retraction{m: m}) } - - overridden := make(map[string]bool) - for i, m := range rs { - if q := u.cmdline[m.Path]; q != nil && q.m.Version != "none" { - rs[i] = q.m - overridden[q.m.Path] = true - } + sort.Slice(retractions, func(i, j int) bool { + return retractions[i].m.Path < retractions[j].m.Path + }) + for i := 0; i < len(retractions); i++ { + i := i + r.work.Add(func() { + err := modload.CheckRetractions(ctx, retractions[i].m) + if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) { + retractions[i].err = err + } + }) } - for _, q := range u.cmdline { - if !overridden[q.m.Path] && q.m.Path != modload.Target.Path && q.m.Version != "none" { - rs = append(rs, q.m) + <-r.work.Idle() + var retractPath string + for _, r := range retractions { + if r.err != nil { + fmt.Fprintf(os.Stderr, "go: warning: %v\n", r.err) + if retractPath == "" { + retractPath = r.m.Path + } else { + retractPath = "<module>" + } } } - return rs, nil + if retractPath != "" { + fmt.Fprintf(os.Stderr, "go: run 'go get %s@latest' to switch to the latest unretracted version\n", retractPath) + } } -// Upgrade returns the desired upgrade for m. +// reportChanges logs version changes to os.Stderr. // -// If m was requested at a specific version on the command line, then -// Upgrade returns that version. +// reportChanges only logs changes to modules named on the command line and to +// explicitly required modules in go.mod. Most changes to indirect requirements +// are not relevant to the user and are not logged. // -// If -u is set and m provides a dependency of a package matched by -// command line arguments, then Upgrade may provider a newer tagged version. -// If m is a tagged version, then Upgrade will return the latest tagged -// version (with the same minor version number if -u=patch). -// If m is a pseudo-version, then Upgrade returns the latest tagged version -// only if that version has a time-stamp newer than m. This special case -// prevents accidental downgrades when already using a pseudo-version -// newer than the latest tagged version. -// -// If none of the above cases apply, then Upgrade returns m. -func (u *upgrader) Upgrade(m module.Version) (module.Version, error) { - // Allow pkg@vers on the command line to override the upgrade choice v. - // If q's version is < m.Version, then we're going to downgrade anyway, - // and it's cleaner to avoid moving back and forth and picking up - // extraneous other newer dependencies. - // If q's version is > m.Version, then we're going to upgrade past - // m.Version anyway, and again it's cleaner to avoid moving back and forth - // picking up extraneous other newer dependencies. - if q := u.cmdline[m.Path]; q != nil { - return q.m, nil +// reportChanges should be called after WriteGoMod. +func (r *resolver) reportChanges(oldReqs, newReqs []module.Version) { + type change struct { + path, old, new string } + changes := make(map[string]change) - if !u.upgrade[m.Path] { - // Not involved in upgrade. Leave alone. - return m, nil + // Collect changes in modules matched by command line arguments. + for path, reason := range r.resolvedVersion { + old := r.initialVersion[path] + new := reason.version + if old != new && (old != "" || new != "none") { + changes[path] = change{path, old, new} + } } - // Run query required by upgrade semantics. - // Note that Query "latest" is not the same as using repo.Latest, - // which may return a pseudoversion for the latest commit. - // Query "latest" returns the newest tagged version or the newest - // prerelease version if there are no non-prereleases, or repo.Latest - // if there aren't any tagged versions. - // If we're querying "upgrade" or "patch", Query will compare the current - // version against the chosen version and will return the current version - // if it is newer. - info, err := modload.Query(context.TODO(), m.Path, string(getU), m.Version, modload.CheckAllowed) - if err != nil { - // Report error but return m, to let version selection continue. - // (Reporting the error will fail the command at the next base.ExitIfErrors.) - - // Special case: if the error is for m.Version itself and m.Version has a - // replacement, then keep it and don't report the error: the fact that the - // version is invalid is likely the reason it was replaced to begin with. - var vErr *module.InvalidVersionError - if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" { - return m, nil + // Collect changes to explicit requirements in go.mod. + for _, req := range oldReqs { + path := req.Path + old := req.Version + new := r.buildListVersion[path] + if old != new { + changes[path] = change{path, old, new} } - - // Special case: if the error is "no matching versions" then don't - // even report the error. Because Query does not consider pseudo-versions, - // it may happen that we have a pseudo-version but during -u=patch - // the query v0.0 matches no versions (not even the one we're using). - var noMatch *modload.NoMatchingVersionError - if !errors.As(err, &noMatch) { - base.Errorf("go get: upgrading %s@%s: %v", m.Path, m.Version, err) + } + for _, req := range newReqs { + path := req.Path + old := r.initialVersion[path] + new := req.Version + if old != new { + changes[path] = change{path, old, new} } - return m, nil } - if info.Version != m.Version { - logOncef("go: %s %s => %s", m.Path, getU, info.Version) + sortedChanges := make([]change, 0, len(changes)) + for _, c := range changes { + sortedChanges = append(sortedChanges, c) + } + sort.Slice(sortedChanges, func(i, j int) bool { + return sortedChanges[i].path < sortedChanges[j].path + }) + for _, c := range sortedChanges { + if c.old == "" { + fmt.Fprintf(os.Stderr, "go get: added %s %s\n", c.path, c.new) + } else if c.new == "none" || c.new == "" { + fmt.Fprintf(os.Stderr, "go get: removed %s %s\n", c.path, c.old) + } else if semver.Compare(c.new, c.old) > 0 { + fmt.Fprintf(os.Stderr, "go get: upgraded %s %s => %s\n", c.path, c.old, c.new) + } else { + fmt.Fprintf(os.Stderr, "go get: downgraded %s %s => %s\n", c.path, c.old, c.new) + } } - return module.Version{Path: m.Path, Version: info.Version}, nil -} -// buildListForLostUpgrade returns the build list for the module graph -// rooted at lost. Unlike mvs.BuildList, the target module (lost) is not -// treated specially. The returned build list may contain a newer version -// of lost. -// -// buildListForLostUpgrade is used after a downgrade has removed a module -// requested at a specific version. This helps us understand the requirements -// implied by each downgrade. -func buildListForLostUpgrade(lost module.Version, reqs mvs.Reqs) ([]module.Version, error) { - return mvs.BuildList(lostUpgradeRoot, &lostUpgradeReqs{Reqs: reqs, lost: lost}) + // TODO(golang.org/issue/33284): attribute changes to command line arguments. + // For modules matched by command line arguments, this probably isn't + // necessary, but it would be useful for unmatched direct dependencies of + // the main module. } -var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""} +// resolve records that module m must be at its indicated version (which may be +// "none") due to query q. If some other query forces module m to be at a +// different version, resolve reports a conflict error. +func (r *resolver) resolve(q *query, m module.Version) { + if m.Path == "" { + panic("internal error: resolving a module.Version with an empty path") + } -type lostUpgradeReqs struct { - mvs.Reqs - lost module.Version -} + if m.Path == modload.Target.Path && m.Version != modload.Target.Version { + reportError(q, &modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + }) + return + } -func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) { - if mod == lostUpgradeRoot { - return []module.Version{r.lost}, nil + vr, ok := r.resolvedVersion[m.Path] + if ok && vr.version != m.Version { + reportConflict(q, m, vr) + return } - return r.Reqs.Required(mod) + r.resolvedVersion[m.Path] = versionReason{m.Version, q} + q.resolved = append(q.resolved, m) } -// reportRetractions prints warnings if any modules in the build list are -// retracted. -func reportRetractions(ctx context.Context) { - // Query for retractions of modules in the build list. - // Use modload.ListModules, since that provides information in the same format - // as 'go list -m'. Don't query for "all", since that's not allowed outside a - // module. - buildList := modload.BuildList() - args := make([]string, 0, len(buildList)) - for _, m := range buildList { - if m.Version == "" { - // main module or dummy target module - continue +// updateBuildList updates the module loader's global build list to be +// consistent with r.resolvedVersion, and to include additional modules +// provided that they do not conflict with the resolved versions. +// +// If the additional modules conflict with the resolved versions, they will be +// downgraded to a non-conflicting version (possibly "none"). +func (r *resolver) updateBuildList(ctx context.Context, additions []module.Version) (changed bool) { + if len(additions) == 0 && len(r.resolvedVersion) == r.buildListResolvedVersions { + return false + } + + defer base.ExitIfErrors() + + resolved := make([]module.Version, 0, len(r.resolvedVersion)) + for mPath, rv := range r.resolvedVersion { + if mPath != modload.Target.Path { + resolved = append(resolved, module.Version{Path: mPath, Version: rv.version}) } - args = append(args, m.Path+"@"+m.Version) } - listU := false - listVersions := false - listRetractions := true - mods := modload.ListModules(ctx, args, listU, listVersions, listRetractions) - retractPath := "" - for _, mod := range mods { - if len(mod.Retracted) > 0 { - if retractPath == "" { - retractPath = mod.Path - } else { - retractPath = "<module>" + + if err := modload.EditBuildList(ctx, additions, resolved); err != nil { + var constraint *modload.ConstraintError + if !errors.As(err, &constraint) { + base.Errorf("go get: %v", err) + return false + } + + reason := func(m module.Version) string { + rv, ok := r.resolvedVersion[m.Path] + if !ok { + panic(fmt.Sprintf("internal error: can't find reason for requirement on %v", m)) } - rationale := modload.ShortRetractionRationale(mod.Retracted[0]) - logOncef("go: warning: %s@%s is retracted: %s", mod.Path, mod.Version, rationale) + return rv.reason.ResolvedString(module.Version{Path: m.Path, Version: rv.version}) + } + for _, c := range constraint.Conflicts { + base.Errorf("go get: %v requires %v, not %v", reason(c.Source), c.Dep, reason(c.Constraint)) } + return false } - if modload.HasModRoot() && retractPath != "" { - logOncef("go: run 'go get %s@latest' to switch to the latest unretracted version", retractPath) + + buildList := modload.LoadAllModules(ctx) + r.buildListResolvedVersions = len(r.resolvedVersion) + if reflect.DeepEqual(r.buildList, buildList) { + return false } + r.buildList = buildList + r.buildListVersion = make(map[string]string, len(r.buildList)) + for _, m := range r.buildList { + r.buildListVersion[m.Path] = m.Version + } + return true } -var loggedLines sync.Map - -func logOncef(format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - if _, dup := loggedLines.LoadOrStore(msg, true); !dup { - fmt.Fprintln(os.Stderr, msg) +func reqsFromGoMod(f *modfile.File) []module.Version { + reqs := make([]module.Version, len(f.Require)) + for i, r := range f.Require { + reqs[i] = r.Mod } + return reqs +} + +// isNoSuchModuleVersion reports whether err indicates that the requested module +// does not exist at the requested version, either because the module does not +// exist at all or because it does not include that specific version. +func isNoSuchModuleVersion(err error) bool { + var noMatch *modload.NoMatchingVersionError + return errors.Is(err, os.ErrNotExist) || errors.As(err, &noMatch) +} + +// isNoSuchPackageVersion reports whether err indicates that the requested +// package does not exist at the requested version, either because no module +// that could contain it exists at that version, or because every such module +// that does exist does not actually contain the package. +func isNoSuchPackageVersion(err error) bool { + var noPackage *modload.PackageNotInModuleError + return isNoSuchModuleVersion(err) || errors.As(err, &noPackage) } diff --git a/src/cmd/go/internal/modget/query.go b/src/cmd/go/internal/modget/query.go new file mode 100644 index 0000000000..20eb0b6364 --- /dev/null +++ b/src/cmd/go/internal/modget/query.go @@ -0,0 +1,357 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modget + +import ( + "fmt" + "path/filepath" + "regexp" + "strings" + "sync" + + "cmd/go/internal/base" + "cmd/go/internal/modload" + "cmd/go/internal/search" + "cmd/go/internal/str" + + "golang.org/x/mod/module" +) + +// A query describes a command-line argument and the modules and/or packages +// to which that argument may resolve.. +type query struct { + // raw is the original argument, to be printed in error messages. + raw string + + // rawVersion is the portion of raw corresponding to version, if any + rawVersion string + + // pattern is the part of the argument before "@" (or the whole argument + // if there is no "@"), which may match either packages (preferred) or + // modules (if no matching packages). + // + // The pattern may also be "-u", for the synthetic query representing the -u + // (“upgrade”)flag. + pattern string + + // patternIsLocal indicates whether pattern is restricted to match only paths + // local to the main module, such as absolute filesystem paths or paths + // beginning with './'. + // + // A local pattern must resolve to one or more packages in the main module. + patternIsLocal bool + + // version is the part of the argument after "@", or an implied + // "upgrade" or "patch" if there is no "@". version specifies the + // module version to get. + version string + + // matchWildcard, if non-nil, reports whether pattern, which must be a + // wildcard (with the substring "..."), matches the given package or module + // path. + matchWildcard func(path string) bool + + // canMatchWildcard, if non-nil, reports whether the module with the given + // path could lexically contain a package matching pattern, which must be a + // wildcard. + canMatchWildcardInModule func(mPath string) bool + + // conflict is the first query identified as incompatible with this one. + // conflict forces one or more of the modules matching this query to a + // version that does not match version. + conflict *query + + // candidates is a list of sets of alternatives for a path that matches (or + // contains packages that match) the pattern. The query can be resolved by + // choosing exactly one alternative from each set in the list. + // + // A path-literal query results in only one set: the path itself, which + // may resolve to either a package path or a module path. + // + // A wildcard query results in one set for each matching module path, each + // module for which the matching version contains at least one matching + // package, and (if no other modules match) one candidate set for the pattern + // overall if no existing match is identified in the build list. + // + // A query for pattern "all" results in one set for each package transitively + // imported by the main module. + // + // The special query for the "-u" flag results in one set for each + // otherwise-unconstrained package that has available upgrades. + candidates []pathSet + candidatesMu sync.Mutex + + // pathSeen ensures that only one pathSet is added to the query per + // unique path. + pathSeen sync.Map + + // resolved contains the set of modules whose versions have been determined by + // this query, in the order in which they were determined. + // + // The resolver examines the candidate sets for each query, resolving one + // module per candidate set in a way that attempts to avoid obvious conflicts + // between the versions resolved by different queries. + resolved []module.Version + + // matchesPackages is true if the resolved modules provide at least one + // package mathcing q.pattern. + matchesPackages bool +} + +// A pathSet describes the possible options for resolving a specific path +// to a package and/or module. +type pathSet struct { + // path is a package (if "all" or "-u" or a non-wildcard) or module (if + // wildcard) path that could be resolved by adding any of the modules in this + // set. For a wildcard pattern that so far matches no packages, the path is + // the wildcard pattern itself. + // + // Each path must occur only once in a query's candidate sets, and the path is + // added implicitly to each pathSet returned to pathOnce. + path string + + // pkgMods is a set of zero or more modules, each of which contains the + // package with the indicated path. Due to the requirement that imports be + // unambiguous, only one such module can be in the build list, and all others + // must be excluded. + pkgMods []module.Version + + // mod is either the zero Version, or a module that does not contain any + // packages matching the query but for which the module path itself + // matches the query pattern. + // + // We track this module separately from pkgMods because, all else equal, we + // prefer to match a query to a package rather than just a module. Also, + // unlike the modules in pkgMods, this module does not inherently exclude + // any other module in pkgMods. + mod module.Version + + err error +} + +// errSet returns a pathSet containing the given error. +func errSet(err error) pathSet { return pathSet{err: err} } + +// newQuery returns a new query parsed from the raw argument, +// which must be either path or path@version. +func newQuery(raw string) (*query, error) { + pattern := raw + rawVers := "" + if i := strings.Index(raw, "@"); i >= 0 { + pattern, rawVers = raw[:i], raw[i+1:] + if strings.Contains(rawVers, "@") || rawVers == "" { + return nil, fmt.Errorf("invalid module version syntax %q", raw) + } + } + + // If no version suffix is specified, assume @upgrade. + // If -u=patch was specified, assume @patch instead. + version := rawVers + if version == "" { + if getU.version == "" { + version = "upgrade" + } else { + version = getU.version + } + } + + q := &query{ + raw: raw, + rawVersion: rawVers, + pattern: pattern, + patternIsLocal: filepath.IsAbs(pattern) || search.IsRelativePath(pattern), + version: version, + } + if strings.Contains(q.pattern, "...") { + q.matchWildcard = search.MatchPattern(q.pattern) + q.canMatchWildcardInModule = search.TreeCanMatchPattern(q.pattern) + } + if err := q.validate(); err != nil { + return q, err + } + return q, nil +} + +// validate reports a non-nil error if q is not sensible and well-formed. +func (q *query) validate() error { + if q.patternIsLocal { + if q.rawVersion != "" { + return fmt.Errorf("can't request explicit version %q of path %q in main module", q.rawVersion, q.pattern) + } + return nil + } + + if q.pattern == "all" { + // If there is no main module, "all" is not meaningful. + if !modload.HasModRoot() { + return fmt.Errorf(`cannot match "all": working directory is not part of a module`) + } + if !versionOkForMainModule(q.version) { + // TODO(bcmills): "all@none" seems like a totally reasonable way to + // request that we remove all module requirements, leaving only the main + // module and standard library. Perhaps we should implement that someday. + return &modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + } + } + } + + if search.IsMetaPackage(q.pattern) && q.pattern != "all" { + if q.pattern != q.raw { + return fmt.Errorf("can't request explicit version of standard-library pattern %q", q.pattern) + } + } + + return nil +} + +// String returns the original argument from which q was parsed. +func (q *query) String() string { return q.raw } + +// ResolvedString returns a string describing m as a resolved match for q. +func (q *query) ResolvedString(m module.Version) string { + if m.Path != q.pattern { + if m.Version != q.version { + return fmt.Sprintf("%v (matching %s@%s)", m, q.pattern, q.version) + } + return fmt.Sprintf("%v (matching %v)", m, q) + } + if m.Version != q.version { + return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, m.Version) + } + return q.String() +} + +// isWildcard reports whether q is a pattern that can match multiple paths. +func (q *query) isWildcard() bool { + return q.matchWildcard != nil || (q.patternIsLocal && strings.Contains(q.pattern, "...")) +} + +// matchesPath reports whether the given path matches q.pattern. +func (q *query) matchesPath(path string) bool { + if q.matchWildcard != nil { + return q.matchWildcard(path) + } + return path == q.pattern +} + +// canMatchInModule reports whether the given module path can potentially +// contain q.pattern. +func (q *query) canMatchInModule(mPath string) bool { + if q.canMatchWildcardInModule != nil { + return q.canMatchWildcardInModule(mPath) + } + return str.HasPathPrefix(q.pattern, mPath) +} + +// pathOnce invokes f to generate the pathSet for the given path, +// if one is still needed. +// +// Note that, unlike sync.Once, pathOnce does not guarantee that a concurrent +// call to f for the given path has completed on return. +// +// pathOnce is safe for concurrent use by multiple goroutines, but note that +// multiple concurrent calls will result in the sets being added in +// nondeterministic order. +func (q *query) pathOnce(path string, f func() pathSet) { + if _, dup := q.pathSeen.LoadOrStore(path, nil); dup { + return + } + + cs := f() + + if len(cs.pkgMods) > 0 || cs.mod != (module.Version{}) || cs.err != nil { + cs.path = path + q.candidatesMu.Lock() + q.candidates = append(q.candidates, cs) + q.candidatesMu.Unlock() + } +} + +// reportError logs err concisely using base.Errorf. +func reportError(q *query, err error) { + errStr := err.Error() + + // If err already mentions all of the relevant parts of q, just log err to + // reduce stutter. Otherwise, log both q and err. + // + // TODO(bcmills): Use errors.As to unpack these errors instead of parsing + // strings with regular expressions. + + patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:)\"`]|$)") + if patternRE.MatchString(errStr) { + if q.rawVersion == "" { + base.Errorf("go get: %s", errStr) + return + } + + versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :)\"`]|$)") + if versionRE.MatchString(errStr) { + base.Errorf("go get: %s", errStr) + return + } + } + + if qs := q.String(); qs != "" { + base.Errorf("go get %s: %s", qs, errStr) + } else { + base.Errorf("go get: %s", errStr) + } +} + +func reportConflict(pq *query, m module.Version, conflict versionReason) { + if pq.conflict != nil { + // We've already reported a conflict for the proposed query. + // Don't report it again, even if it has other conflicts. + return + } + pq.conflict = conflict.reason + + proposed := versionReason{ + version: m.Version, + reason: pq, + } + if pq.isWildcard() && !conflict.reason.isWildcard() { + // Prefer to report the specific path first and the wildcard second. + proposed, conflict = conflict, proposed + } + reportError(pq, &conflictError{ + mPath: m.Path, + proposed: proposed, + conflict: conflict, + }) +} + +type conflictError struct { + mPath string + proposed versionReason + conflict versionReason +} + +func (e *conflictError) Error() string { + argStr := func(q *query, v string) string { + if v != q.version { + return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, v) + } + return q.String() + } + + pq := e.proposed.reason + rq := e.conflict.reason + modDetail := "" + if e.mPath != pq.pattern { + modDetail = fmt.Sprintf("for module %s, ", e.mPath) + } + + return fmt.Sprintf("%s%s conflicts with %s", + modDetail, + argStr(pq, e.proposed.version), + argStr(rq, e.conflict.version)) +} + +func versionOkForMainModule(version string) bool { + return version == "upgrade" || version == "patch" +} diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go index e9f9a82fab..8ad5f834de 100644 --- a/src/cmd/go/internal/modload/build.go +++ b/src/cmd/go/internal/modload/build.go @@ -13,7 +13,6 @@ import ( "internal/goroot" "os" "path/filepath" - "runtime/debug" "strings" "cmd/go/internal/base" @@ -50,7 +49,7 @@ func findStandardImportPath(path string) string { // PackageModuleInfo returns information about the module that provides // a given package. If modules are not enabled or if the package is in the // standard library or if the package was not successfully loaded with -// ImportPaths or a similar loading function, nil is returned. +// LoadPackages or ImportFromFiles, nil is returned. func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic { if isStandardImportPath(pkgpath) || !Enabled() { return nil @@ -76,7 +75,7 @@ func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic { return moduleInfo(ctx, m, fromBuildList, listRetracted) } - for _, m := range BuildList() { + for _, m := range buildList { if m.Path == path { fromBuildList := true return moduleInfo(ctx, m, fromBuildList, listRetracted) @@ -124,13 +123,13 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) { return } - err := checkRetractions(ctx, module.Version{Path: m.Path, Version: m.Version}) - var rerr *retractedError + err := CheckRetractions(ctx, module.Version{Path: m.Path, Version: m.Version}) + var rerr *ModuleRetractedError if errors.As(err, &rerr) { - if len(rerr.rationale) == 0 { + if len(rerr.Rationale) == 0 { m.Retracted = []string{"retracted by module author"} } else { - m.Retracted = rerr.rationale + m.Retracted = rerr.Rationale } } else if err != nil && m.Error == nil { m.Error = &modinfo.ModuleError{Err: err.Error()} @@ -250,8 +249,7 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList, listRetrac // PackageBuildInfo returns a string containing module version information // for modules providing packages named by path and deps. path and deps must -// name packages that were resolved successfully with ImportPaths or one of -// the Load functions. +// name packages that were resolved successfully with LoadPackages. func PackageBuildInfo(path string, deps []string) string { if isStandardImportPath(path) || !Enabled() { return "" @@ -313,17 +311,13 @@ func mustFindModule(target, path string) module.Version { return Target } - if printStackInDie { - debug.PrintStack() - } base.Fatalf("build %v: cannot find module for path %v", target, path) panic("unreachable") } // findModule searches for the module that contains the package at path. -// If the package was loaded with ImportPaths or one of the other loading -// functions, its containing module and true are returned. Otherwise, -// module.Version{} and false are returend. +// If the package was loaded, its containing module and true are returned. +// Otherwise, module.Version{} and false are returend. func findModule(path string) (module.Version, bool) { if pkg, ok := loaded.pkgCache.Get(path).(*loadPkg); ok { return pkg.mod, pkg.mod != module.Version{} @@ -355,13 +349,13 @@ func ModInfoProg(info string, isgccgo bool) []byte { import _ "unsafe" //go:linkname __debug_modinfo__ runtime.modinfo var __debug_modinfo__ = %q - `, string(infoStart)+info+string(infoEnd))) +`, string(infoStart)+info+string(infoEnd))) } else { return []byte(fmt.Sprintf(`package main import _ "unsafe" //go:linkname __set_debug_modinfo__ runtime.setmodinfo func __set_debug_modinfo__(string) func init() { __set_debug_modinfo__(%q) } - `, string(infoStart)+info+string(infoEnd))) +`, string(infoStart)+info+string(infoEnd))) } } diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go new file mode 100644 index 0000000000..896adebbb1 --- /dev/null +++ b/src/cmd/go/internal/modload/buildlist.go @@ -0,0 +1,267 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modload + +import ( + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/imports" + "cmd/go/internal/mvs" + "context" + "fmt" + "os" + "strings" + + "golang.org/x/mod/module" +) + +// buildList is the list of modules to use for building packages. +// It is initialized by calling LoadPackages or ImportFromFiles, +// each of which uses loaded.load. +// +// Ideally, exactly ONE of those functions would be called, +// and exactly once. Most of the time, that's true. +// During "go get" it may not be. TODO(rsc): Figure out if +// that restriction can be established, or else document why not. +// +var buildList []module.Version + +// capVersionSlice returns s with its cap reduced to its length. +func capVersionSlice(s []module.Version) []module.Version { + return s[:len(s):len(s)] +} + +// LoadAllModules loads and returns the list of modules matching the "all" +// module pattern, starting with the Target module and in a deterministic +// (stable) order, without loading any packages. +// +// Modules are loaded automatically (and lazily) in LoadPackages: +// LoadAllModules need only be called if LoadPackages is not, +// typically in commands that care about modules but no particular package. +// +// The caller must not modify the returned list, but may append to it. +func LoadAllModules(ctx context.Context) []module.Version { + LoadModFile(ctx) + ReloadBuildList() + WriteGoMod() + return capVersionSlice(buildList) +} + +// Selected returns the selected version of the module with the given path, or +// the empty string if the given module has no selected version +// (either because it is not required or because it is the Target module). +func Selected(path string) (version string) { + if path == Target.Path { + return "" + } + for _, m := range buildList { + if m.Path == path { + return m.Version + } + } + return "" +} + +// EditBuildList edits the global build list by first adding every module in add +// to the existing build list, then adjusting versions (and adding or removing +// requirements as needed) until every module in mustSelect is selected at the +// given version. +// +// (Note that the newly-added modules might not be selected in the resulting +// build list: they could be lower than existing requirements or conflict with +// versions in mustSelect.) +// +// If the versions listed in mustSelect are mutually incompatible (due to one of +// the listed modules requiring a higher version of another), EditBuildList +// returns a *ConstraintError and leaves the build list in its previous state. +func EditBuildList(ctx context.Context, add, mustSelect []module.Version) error { + var upgraded = capVersionSlice(buildList) + if len(add) > 0 { + // First, upgrade the build list with any additions. + // In theory we could just append the additions to the build list and let + // mvs.Downgrade take care of resolving the upgrades too, but the + // diagnostics from Upgrade are currently much better in case of errors. + var err error + upgraded, err = mvs.Upgrade(Target, &mvsReqs{buildList: upgraded}, add...) + if err != nil { + return err + } + } + + downgraded, err := mvs.Downgrade(Target, &mvsReqs{buildList: append(upgraded, mustSelect...)}, mustSelect...) + if err != nil { + return err + } + + final, err := mvs.Upgrade(Target, &mvsReqs{buildList: downgraded}, mustSelect...) + if err != nil { + return err + } + + selected := make(map[string]module.Version, len(final)) + for _, m := range final { + selected[m.Path] = m + } + inconsistent := false + for _, m := range mustSelect { + s, ok := selected[m.Path] + if !ok { + if m.Version != "none" { + panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m)) + } + continue + } + if s.Version != m.Version { + inconsistent = true + break + } + } + + if !inconsistent { + buildList = final + return nil + } + + // We overshot one or more of the modules in mustSelected, which means that + // Downgrade removed something in mustSelect because it conflicted with + // something else in mustSelect. + // + // Walk the requirement graph to find the conflict. + // + // TODO(bcmills): Ideally, mvs.Downgrade (or a replacement for it) would do + // this directly. + + reqs := &mvsReqs{buildList: final} + reason := map[module.Version]module.Version{} + for _, m := range mustSelect { + reason[m] = m + } + queue := mustSelect[:len(mustSelect):len(mustSelect)] + for len(queue) > 0 { + var m module.Version + m, queue = queue[0], queue[1:] + required, err := reqs.Required(m) + if err != nil { + return err + } + for _, r := range required { + if _, ok := reason[r]; !ok { + reason[r] = reason[m] + queue = append(queue, r) + } + } + } + + var conflicts []Conflict + for _, m := range mustSelect { + s, ok := selected[m.Path] + if !ok { + if m.Version != "none" { + panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m)) + } + continue + } + if s.Version != m.Version { + conflicts = append(conflicts, Conflict{ + Source: reason[s], + Dep: s, + Constraint: m, + }) + } + } + + return &ConstraintError{ + Conflicts: conflicts, + } +} + +// A ConstraintError describes inconsistent constraints in EditBuildList +type ConstraintError struct { + // Conflict lists the source of the conflict for each version in mustSelect + // that could not be selected due to the requirements of some other version in + // mustSelect. + Conflicts []Conflict +} + +func (e *ConstraintError) Error() string { + b := new(strings.Builder) + b.WriteString("version constraints conflict:") + for _, c := range e.Conflicts { + fmt.Fprintf(b, "\n\t%v requires %v, but %v is requested", c.Source, c.Dep, c.Constraint) + } + return b.String() +} + +// A Conflict documents that Source requires Dep, which conflicts with Constraint. +// (That is, Dep has the same module path as Constraint but a higher version.) +type Conflict struct { + Source module.Version + Dep module.Version + Constraint module.Version +} + +// ReloadBuildList resets the state of loaded packages, then loads and returns +// the build list set by EditBuildList. +func ReloadBuildList() []module.Version { + loaded = loadFromRoots(loaderParams{ + PackageOpts: PackageOpts{ + Tags: imports.Tags(), + }, + listRoots: func() []string { return nil }, + allClosesOverTests: index.allPatternClosesOverTests(), // but doesn't matter because the root list is empty. + }) + return capVersionSlice(buildList) +} + +// TidyBuildList trims the build list to the minimal requirements needed to +// retain the same versions of all packages from the preceding call to +// LoadPackages. +func TidyBuildList() { + used := map[module.Version]bool{Target: true} + for _, pkg := range loaded.pkgs { + used[pkg.mod] = true + } + + keep := []module.Version{Target} + var direct []string + for _, m := range buildList[1:] { + if used[m] { + keep = append(keep, m) + if loaded.direct[m.Path] { + direct = append(direct, m.Path) + } + } else if cfg.BuildV { + if _, ok := index.require[m]; ok { + fmt.Fprintf(os.Stderr, "unused %s\n", m.Path) + } + } + } + + min, err := mvs.Req(Target, direct, &mvsReqs{buildList: keep}) + if err != nil { + base.Fatalf("go: %v", err) + } + buildList = append([]module.Version{Target}, min...) +} + +// checkMultiplePaths verifies that a given module path is used as itself +// or as a replacement for another module, but not both at the same time. +// +// (See https://golang.org/issue/26607 and https://golang.org/issue/34650.) +func checkMultiplePaths() { + firstPath := make(map[module.Version]string, len(buildList)) + for _, mod := range buildList { + src := mod + if rep := Replacement(mod); rep.Path != "" { + src = rep + } + if prev, ok := firstPath[src]; !ok { + firstPath[src] = mod.Path + } else if prev != mod.Path { + base.Errorf("go: %s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path) + } + } + base.ExitIfErrors() +} diff --git a/src/cmd/go/internal/modload/help.go b/src/cmd/go/internal/modload/help.go index 37f23d967f..d81dfd56fb 100644 --- a/src/cmd/go/internal/modload/help.go +++ b/src/cmd/go/internal/modload/help.go @@ -124,72 +124,63 @@ and the build list. For example: Maintaining module requirements -The go.mod file is meant to be readable and editable by both -programmers and tools. The go command itself automatically updates the go.mod file -to maintain a standard formatting and the accuracy of require statements. +The go.mod file is meant to be readable and editable by both programmers and +tools. Most updates to dependencies can be performed using "go get" and +"go mod tidy". Other module-aware build commands may be invoked using the +-mod=mod flag to automatically add missing requirements and fix inconsistencies. -Any go command that finds an unfamiliar import will look up the module -containing that import and add the latest version of that module -to go.mod automatically. In most cases, therefore, it suffices to -add an import to source code and run 'go build', 'go test', or even 'go list': -as part of analyzing the package, the go command will discover -and resolve the import and update the go.mod file. +The "go get" command updates go.mod to change the module versions used in a +build. An upgrade of one module may imply upgrading others, and similarly a +downgrade of one module may imply downgrading others. The "go get" command +makes these implied changes as well. See "go help module-get". -Any go command can determine that a module requirement is -missing and must be added, even when considering only a single -package from the module. On the other hand, determining that a module requirement -is no longer necessary and can be deleted requires a full view of -all packages in the module, across all possible build configurations -(architectures, operating systems, build tags, and so on). -The 'go mod tidy' command builds that view and then -adds any missing module requirements and removes unnecessary ones. +The "go mod" command provides other functionality for use in maintaining +and understanding modules and go.mod files. See "go help mod", particularly +"go help mod tidy" and "go help mod edit". As part of maintaining the require statements in go.mod, the go command tracks which ones provide packages imported directly by the current module and which ones provide packages only used indirectly by other module dependencies. Requirements needed only for indirect uses are marked with a -"// indirect" comment in the go.mod file. Indirect requirements are +"// indirect" comment in the go.mod file. Indirect requirements may be automatically removed from the go.mod file once they are implied by other direct requirements. Indirect requirements only arise when using modules that fail to state some of their own dependencies or when explicitly upgrading a module's dependencies ahead of its own stated requirements. -Because of this automatic maintenance, the information in go.mod is an -up-to-date, readable description of the build. - -The 'go get' command updates go.mod to change the module versions used in a -build. An upgrade of one module may imply upgrading others, and similarly a -downgrade of one module may imply downgrading others. The 'go get' command -makes these implied changes as well. If go.mod is edited directly, commands -like 'go build' or 'go list' will assume that an upgrade is intended and -automatically make any implied upgrades and update go.mod to reflect them. - -The 'go mod' command provides other functionality for use in maintaining -and understanding modules and go.mod files. See 'go help mod'. +The -mod build flag provides additional control over the updating and use of +go.mod for commands that build packages like "go build" and "go test". -The -mod build flag provides additional control over updating and use of go.mod. +If invoked with -mod=readonly (the default in most situations), the go command +reports an error if a package named on the command line or an imported package +is not provided by any module in the build list computed from the main module's +requirements. The go command also reports an error if a module's checksum is +missing from go.sum (see Module downloading and verification). Either go.mod or +go.sum must be updated in these situations. -If invoked with -mod=readonly, the go command is disallowed from the implicit -automatic updating of go.mod described above. Instead, it fails when any changes -to go.mod are needed. This setting is most useful to check that go.mod does -not need updates, such as in a continuous integration and testing system. -The "go get" command remains permitted to update go.mod even with -mod=readonly, -and the "go mod" commands do not take the -mod flag (or any other build flags). +If invoked with -mod=mod, the go command automatically updates go.mod and +go.sum, fixing inconsistencies and adding missing requirements and checksums +as needed. If the go command finds an unfamiliar import, it looks up the +module containing that import and adds a requirement for the latest version +of that module to go.mod. In most cases, therefore, one may add an import to +source code and run "go build", "go test", or even "go list" with -mod=mod: +as part of analyzing the package, the go command will resolve the import and +update the go.mod file. If invoked with -mod=vendor, the go command loads packages from the main module's vendor directory instead of downloading modules to and loading packages from the module cache. The go command assumes the vendor directory holds correct copies of dependencies, and it does not compute the set of required module versions from go.mod files. However, the go command does check that -vendor/modules.txt (generated by 'go mod vendor') contains metadata consistent +vendor/modules.txt (generated by "go mod vendor") contains metadata consistent with go.mod. -If invoked with -mod=mod, the go command loads modules from the module cache -even if there is a vendor directory present. +If the go command is not invoked with a -mod flag, and the vendor directory +is present, and the "go" version in go.mod is 1.14 or higher, the go command +will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag +defaults to -mod=readonly. -If the go command is not invoked with a -mod flag and the vendor directory -is present and the "go" version in go.mod is 1.14 or higher, the go command -will act as if it were invoked with -mod=vendor. +Note that neither "go get" nor the "go mod" subcommands accept the -mod flag. Pseudo-versions @@ -374,7 +365,7 @@ list if the error is a 404 or 410 HTTP response or if the current proxy is followed by a pipe character, indicating it is safe to fall back on any error. The GOPRIVATE and GONOPROXY environment variables allow bypassing -the proxy for selected modules. See 'go help module-private' for details. +the proxy for selected modules. See 'go help private' for details. No matter the source of the modules, the go command checks downloads against known checksums, to detect unexpected changes in the content of any specific @@ -448,7 +439,7 @@ The leading verb can be factored out of adjacent lines to create a block, like in Go imports: require ( - new/thing v2.3.4 + new/thing/v2 v2.3.4 old/thing v1.2.3 ) diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go index 6459e716b7..ce5671728e 100644 --- a/src/cmd/go/internal/modload/import.go +++ b/src/cmd/go/internal/modload/import.go @@ -10,14 +10,14 @@ import ( "fmt" "go/build" "internal/goroot" + "io/fs" "os" "path/filepath" "sort" "strings" - "time" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" "cmd/go/internal/modfetch" "cmd/go/internal/par" "cmd/go/internal/search" @@ -31,23 +31,60 @@ type ImportMissingError struct { Module module.Version QueryErr error + // inAll indicates whether Path is in the "all" package pattern, + // and thus would be added by 'go mod tidy'. + inAll bool + + // isStd indicates whether we would expect to find the package in the standard + // library. This is normally true for all dotless import paths, but replace + // directives can cause us to treat the replaced paths as also being in + // modules. + isStd bool + + // replaced the highest replaced version of the module where the replacement + // contains the package. replaced is only set if the replacement is unused. + replaced module.Version + // newMissingVersion is set to a newer version of Module if one is present // in the build list. When set, we can't automatically upgrade. newMissingVersion string } -var _ load.ImportPathError = (*ImportMissingError)(nil) - func (e *ImportMissingError) Error() string { if e.Module.Path == "" { - if search.IsStandardImportPath(e.Path) { + if e.isStd { return fmt.Sprintf("package %s is not in GOROOT (%s)", e.Path, filepath.Join(cfg.GOROOT, "src", e.Path)) } if e.QueryErr != nil { return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr) } - return "cannot find module providing package " + e.Path + if cfg.BuildMod == "mod" { + return "cannot find module providing package " + e.Path + } + + if e.replaced.Path != "" { + suggestArg := e.replaced.Path + if !modfetch.IsZeroPseudoVersion(e.replaced.Version) { + suggestArg = e.replaced.String() + } + return fmt.Sprintf("module %s provides package %s and is replaced but not required; try 'go get -d %s' to add it", e.replaced.Path, e.Path, suggestArg) + } + + suggestion := "" + if !HasModRoot() { + suggestion = ": working directory is not part of a module" + } else if e.inAll { + suggestion = "; try 'go mod tidy' to add it" + } else { + suggestion = fmt.Sprintf("; try 'go get -d %s' to add it", e.Path) + } + return fmt.Sprintf("no required module provides package %s%s", e.Path, suggestion) } + + if e.newMissingVersion != "" { + return fmt.Sprintf("package %s provided by %s at latest version %s but not at required version %s", e.Path, e.Module.Path, e.Module.Version, e.newMissingVersion) + } + return fmt.Sprintf("missing module for import: %s@%s provides %s", e.Module.Path, e.Module.Version, e.Path) } @@ -98,20 +135,62 @@ func (e *AmbiguousImportError) Error() string { return buf.String() } -var _ load.ImportPathError = &AmbiguousImportError{} +// ImportMissingSumError is reported in readonly mode when we need to check +// if a module in the build list contains a package, but we don't have a sum +// for its .zip file. +type ImportMissingSumError struct { + importPath string + found, inAll bool +} -// Import finds the module and directory in the build list -// containing the package with the given import path. -// The answer must be unique: Import returns an error -// if multiple modules attempt to provide the same package. -// Import can return a module with an empty m.Path, for packages in the standard library. -// Import can return an empty directory string, for fake packages like "C" and "unsafe". +func (e *ImportMissingSumError) Error() string { + var message string + if e.found { + message = fmt.Sprintf("missing go.sum entry needed to verify package %s is provided by exactly one module", e.importPath) + } else { + message = fmt.Sprintf("missing go.sum entry for module providing package %s", e.importPath) + } + if e.inAll { + return message + "; try 'go mod tidy' to add it" + } + return message +} + +func (e *ImportMissingSumError) ImportPath() string { + return e.importPath +} + +type invalidImportError struct { + importPath string + err error +} + +func (e *invalidImportError) ImportPath() string { + return e.importPath +} + +func (e *invalidImportError) Error() string { + return e.err.Error() +} + +func (e *invalidImportError) Unwrap() error { + return e.err +} + +// importFromBuildList finds the module and directory in the build list +// containing the package with the given import path. The answer must be unique: +// importFromBuildList returns an error if multiple modules attempt to provide +// the same package. // -// If the package cannot be found in the current build list, -// Import returns an ImportMissingError as the error. -// If Import can identify a module that could be added to supply the package, -// the ImportMissingError records that module. -func Import(ctx context.Context, path string) (m module.Version, dir string, err error) { +// importFromBuildList can return a module with an empty m.Path, for packages in +// the standard library. +// +// importFromBuildList can return an empty directory string, for fake packages +// like "C" and "unsafe". +// +// If the package cannot be found in buildList, +// importFromBuildList returns an *ImportMissingError. +func importFromBuildList(ctx context.Context, path string, buildList []module.Version) (m module.Version, dir string, err error) { if strings.Contains(path, "@") { return module.Version{}, "", fmt.Errorf("import path should not have @version") } @@ -122,6 +201,10 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err // There's no directory for import "C" or import "unsafe". return module.Version{}, "", nil } + // Before any further lookup, check that the path is valid. + if err := module.CheckImportPath(path); err != nil { + return module.Version{}, "", &invalidImportError{importPath: path, err: err} + } // Is the package in the standard library? pathIsStd := search.IsStandardImportPath(path) @@ -161,13 +244,23 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err // Check each module on the build list. var dirs []string var mods []module.Version + haveSumErr := false for _, m := range buildList { if !maybeInModule(path, m.Path) { // Avoid possibly downloading irrelevant modules. continue } - root, isLocal, err := fetch(ctx, m) + needSum := true + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { + if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) { + // We are missing a sum needed to fetch a module in the build list. + // We can't verify that the package is unique, and we may not find + // the package at all. Keep checking other modules to decide which + // error to report. + haveSumErr = true + continue + } // Report fetch error. // Note that we don't know for sure this module is necessary, // but it certainly _could_ provide the package, and even if we @@ -183,88 +276,76 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err dirs = append(dirs, dir) } } - if len(mods) == 1 { - return mods[0], dirs[0], nil - } - if len(mods) > 0 { + if len(mods) > 1 { return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods} } - - // Look up module containing the package, for addition to the build list. - // Goal is to determine the module, download it to dir, and return m, dir, ErrMissing. - if cfg.BuildMod == "readonly" { - var queryErr error - if !pathIsStd { - if cfg.BuildModReason == "" { - queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) - } else { - queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) - } - } - return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr} + if haveSumErr { + return module.Version{}, "", &ImportMissingSumError{importPath: path, found: len(mods) > 0} } - if modRoot == "" && !allowMissingModuleImports { - return module.Version{}, "", &ImportMissingError{ - Path: path, - QueryErr: errors.New("working directory is not part of a module"), - } + if len(mods) == 1 { + return mods[0], dirs[0], nil } - // Not on build list. - // To avoid spurious remote fetches, next try the latest replacement for each module. - // (golang.org/issue/26241) - if modFile != nil { - latest := map[string]string{} // path -> version - for _, r := range modFile.Replace { - if maybeInModule(path, r.Old.Path) { - // Don't use semver.Max here; need to preserve +incompatible suffix. - v := latest[r.Old.Path] - if semver.Compare(r.Old.Version, v) > 0 { - v = r.Old.Version - } - latest[r.Old.Path] = v - } - } + return module.Version{}, "", &ImportMissingError{Path: path, isStd: pathIsStd} +} - mods = make([]module.Version, 0, len(latest)) - for p, v := range latest { - // If the replacement didn't specify a version, synthesize a - // pseudo-version with an appropriate major version and a timestamp below - // any real timestamp. That way, if the main module is used from within - // some other module, the user will be able to upgrade the requirement to - // any real version they choose. - if v == "" { - if _, pathMajor, ok := module.SplitPathVersion(p); ok && len(pathMajor) > 0 { - v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000") +// queryImport attempts to locate a module that can be added to the current +// build list to provide the package with the given import path. +// +// Unlike QueryPattern, queryImport prefers to add a replaced version of a +// module *before* checking the proxies for a version to add. +func queryImport(ctx context.Context, path string) (module.Version, error) { + // To avoid spurious remote fetches, try the latest replacement for each + // module (golang.org/issue/26241). + if index != nil { + var mods []module.Version + for mp, mv := range index.highestReplaced { + if !maybeInModule(path, mp) { + continue + } + if mv == "" { + // The only replacement is a wildcard that doesn't specify a version, so + // synthesize a pseudo-version with an appropriate major version and a + // timestamp below any real timestamp. That way, if the main module is + // used from within some other module, the user will be able to upgrade + // the requirement to any real version they choose. + if _, pathMajor, ok := module.SplitPathVersion(mp); ok && len(pathMajor) > 0 { + mv = modfetch.ZeroPseudoVersion(pathMajor[1:]) } else { - v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000") + mv = modfetch.ZeroPseudoVersion("v0") } } - mods = append(mods, module.Version{Path: p, Version: v}) + mods = append(mods, module.Version{Path: mp, Version: mv}) } // Every module path in mods is a prefix of the import path. - // As in QueryPackage, prefer the longest prefix that satisfies the import. + // As in QueryPattern, prefer the longest prefix that satisfies the import. sort.Slice(mods, func(i, j int) bool { return len(mods[i].Path) > len(mods[j].Path) }) for _, m := range mods { - root, isLocal, err := fetch(ctx, m) + needSum := true + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { - // Report fetch error as above. - return module.Version{}, "", err + if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) { + return module.Version{}, &ImportMissingSumError{importPath: path} + } + return module.Version{}, err } if _, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil { - return m, "", err + return m, err } else if ok { - return m, "", &ImportMissingError{Path: path, Module: m} + if cfg.BuildMod == "readonly" { + return module.Version{}, &ImportMissingError{Path: path, replaced: m} + } + return m, nil } } if len(mods) > 0 && module.CheckPath(path) != nil { // The package path is not valid to fetch remotely, - // so it can only exist if in a replaced module, + // so it can only exist in a replaced module, // and we know from the above loop that it is not. - return module.Version{}, "", &PackageNotInModuleError{ + return module.Version{}, &PackageNotInModuleError{ Mod: mods[0], Query: "latest", Pattern: path, @@ -273,36 +354,53 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err } } - if pathIsStd { + if search.IsStandardImportPath(path) { // This package isn't in the standard library, isn't in any module already // in the build list, and isn't in any other module that the user has // shimmed in via a "replace" directive. // Moreover, the import path is reserved for the standard library, so - // QueryPackage cannot possibly find a module containing this package. + // QueryPattern cannot possibly find a module containing this package. // - // Instead of trying QueryPackage, report an ImportMissingError immediately. - return module.Version{}, "", &ImportMissingError{Path: path} + // Instead of trying QueryPattern, report an ImportMissingError immediately. + return module.Version{}, &ImportMissingError{Path: path, isStd: true} + } + + if cfg.BuildMod == "readonly" { + // In readonly mode, we can't write go.mod, so we shouldn't try to look up + // the module. If readonly mode was enabled explicitly, include that in + // the error message. + var queryErr error + if cfg.BuildModExplicit { + queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) + } else if cfg.BuildModReason != "" { + queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) + } + return module.Version{}, &ImportMissingError{Path: path, QueryErr: queryErr} } + // Look up module containing the package, for addition to the build list. + // Goal is to determine the module, download it to dir, + // and return m, dir, ImpportMissingError. fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path) - candidates, err := QueryPackage(ctx, path, "latest", CheckAllowed) + candidates, err := QueryPackages(ctx, path, "latest", Selected, CheckAllowed) if err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // Return "cannot find module providing package […]" instead of whatever - // low-level error QueryPackage produced. - return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: err} + // low-level error QueryPattern produced. + return module.Version{}, &ImportMissingError{Path: path, QueryErr: err} } else { - return module.Version{}, "", err + return module.Version{}, err } } - m = candidates[0].Mod - newMissingVersion := "" - for _, c := range candidates { + + candidate0MissingVersion := "" + for i, c := range candidates { cm := c.Mod + canAdd := true for _, bm := range buildList { if bm.Path == cm.Path && semver.Compare(bm.Version, cm.Version) > 0 { - // QueryPackage proposed that we add module cm to provide the package, + // QueryPattern proposed that we add module cm to provide the package, // but we already depend on a newer version of that module (and we don't // have the package). // @@ -310,13 +408,22 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err // version (e.g., v1.0.0) of a module, but we have a newer version // of the same module in the build list (e.g., v1.0.1-beta), and // the package is not present there. - m = cm - newMissingVersion = bm.Version + canAdd = false + if i == 0 { + candidate0MissingVersion = bm.Version + } break } } + if canAdd { + return cm, nil + } + } + return module.Version{}, &ImportMissingError{ + Path: path, + Module: candidates[0].Mod, + newMissingVersion: candidate0MissingVersion, } - return m, "", &ImportMissingError{Path: path, Module: m, newMissingVersion: newMissingVersion} } // maybeInModule reports whether, syntactically, @@ -370,7 +477,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile if isLocal { for d := dir; d != mdir && len(d) > len(mdir); { haveGoMod := haveGoModCache.Do(d, func() interface{} { - fi, err := os.Stat(filepath.Join(d, "go.mod")) + fi, err := fsys.Stat(filepath.Join(d, "go.mod")) return err == nil && !fi.IsDir() }).(bool) @@ -393,57 +500,65 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile // We don't care about build tags, not even "+build ignore". // We're just looking for a plausible directory. res := haveGoFilesCache.Do(dir, func() interface{} { - ok, err := isDirWithGoFiles(dir) + ok, err := fsys.IsDirWithGoFiles(dir) return goFilesEntry{haveGoFiles: ok, err: err} }).(goFilesEntry) return dir, res.haveGoFiles, res.err } -func isDirWithGoFiles(dir string) (bool, error) { - f, err := os.Open(dir) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - defer f.Close() - - names, firstErr := f.Readdirnames(-1) - if firstErr != nil { - if fi, err := f.Stat(); err == nil && !fi.IsDir() { - return false, nil - } - - // Rewrite the error from ReadDirNames to include the path if not present. - // See https://golang.org/issue/38923. - var pe *os.PathError - if !errors.As(firstErr, &pe) { - firstErr = &os.PathError{Op: "readdir", Path: dir, Err: firstErr} - } +// fetch downloads the given module (or its replacement) +// and returns its location. +// +// needSum indicates whether the module may be downloaded in readonly mode +// without a go.sum entry. It should only be false for modules fetched +// speculatively (for example, for incompatible version filtering). The sum +// will still be verified normally. +// +// The isLocal return value reports whether the replacement, +// if any, is local to the filesystem. +func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, isLocal bool, err error) { + if mod == Target { + return ModRoot(), true, nil } - - for _, name := range names { - if strings.HasSuffix(name, ".go") { - info, err := os.Stat(filepath.Join(dir, name)) - if err == nil && info.Mode().IsRegular() { - // If any .go source file exists, the package exists regardless of - // errors for other source files. Leave further error reporting for - // later. - return true, nil + if r := Replacement(mod); r.Path != "" { + if r.Version == "" { + dir = r.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) } - if firstErr == nil { + // Ensure that the replacement directory actually exists: + // dirInModule does not report errors for missing modules, + // so if we don't report the error now, later failures will be + // very mysterious. + if _, err := fsys.Stat(dir); err != nil { if os.IsNotExist(err) { - // If the file was concurrently deleted, or was a broken symlink, - // convert the error to an opaque error instead of one matching - // os.IsNotExist. - err = errors.New(err.Error()) + // Semantically the module version itself “exists” — we just don't + // have its source code. Remove the equivalence to os.ErrNotExist, + // and make the message more concise while we're at it. + err = fmt.Errorf("replacement directory %s does not exist", r.Path) + } else { + err = fmt.Errorf("replacement directory %s: %w", r.Path, err) } - firstErr = err + return dir, true, module.VersionError(mod, err) } + return dir, true, nil } + mod = r + } + + if cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) { + return "", false, module.VersionError(mod, &sumMissingError{}) } - return false, firstErr + dir, err = modfetch.Download(ctx, mod) + return dir, false, err +} + +type sumMissingError struct { + suggestion string +} + +func (e *sumMissingError) Error() string { + return "missing go.sum entry" + e.suggestion } diff --git a/src/cmd/go/internal/modload/import_test.go b/src/cmd/go/internal/modload/import_test.go index 47ce89a084..22d5b82e21 100644 --- a/src/cmd/go/internal/modload/import_test.go +++ b/src/cmd/go/internal/modload/import_test.go @@ -10,15 +10,20 @@ import ( "regexp" "strings" "testing" + + "golang.org/x/mod/module" ) var importTests = []struct { path string + m module.Version err string }{ { path: "golang.org/x/net/context", - err: "missing module for import: golang.org/x/net@.* provides golang.org/x/net/context", + m: module.Version{ + Path: "golang.org/x/net", + }, }, { path: "golang.org/x/net", @@ -26,15 +31,23 @@ var importTests = []struct { }, { path: "golang.org/x/text", - err: "missing module for import: golang.org/x/text@.* provides golang.org/x/text", + m: module.Version{ + Path: "golang.org/x/text", + }, }, { path: "github.com/rsc/quote/buggy", - err: "missing module for import: github.com/rsc/quote@v1.5.2 provides github.com/rsc/quote/buggy", + m: module.Version{ + Path: "github.com/rsc/quote", + Version: "v1.5.2", + }, }, { path: "github.com/rsc/quote", - err: "missing module for import: github.com/rsc/quote@v1.5.2 provides github.com/rsc/quote", + m: module.Version{ + Path: "github.com/rsc/quote", + Version: "v1.5.2", + }, }, { path: "golang.org/x/foo/bar", @@ -42,7 +55,7 @@ var importTests = []struct { }, } -func TestImport(t *testing.T) { +func TestQueryImport(t *testing.T) { testenv.MustHaveExternalNetwork(t) testenv.MustHaveExecPath(t, "git") defer func(old bool) { @@ -55,12 +68,23 @@ func TestImport(t *testing.T) { for _, tt := range importTests { t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { // Note that there is no build list, so Import should always fail. - m, dir, err := Import(ctx, tt.path) - if err == nil { - t.Fatalf("Import(%q) = %v, %v, nil; expected error", tt.path, m, dir) + m, err := queryImport(ctx, tt.path) + + if tt.err == "" { + if err != nil { + t.Fatalf("queryImport(_, %q): %v", tt.path, err) + } + } else { + if err == nil { + t.Fatalf("queryImport(_, %q) = %v, nil; expected error", tt.path, m) + } + if !regexp.MustCompile(tt.err).MatchString(err.Error()) { + t.Fatalf("queryImport(_, %q): error %q, want error matching %#q", tt.path, err, tt.err) + } } - if !regexp.MustCompile(tt.err).MatchString(err.Error()) { - t.Fatalf("Import(%q): error %q, want error matching %#q", tt.path, err, tt.err) + + if m.Path != tt.m.Path || (tt.m.Version != "" && m.Version != tt.m.Version) { + t.Errorf("queryImport(_, %q) = %v, _; want %v", tt.path, m, tt.m) } }) } diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 6f93b88eab..3f70d04145 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -12,17 +12,16 @@ import ( "fmt" "go/build" "internal/lazyregexp" - "io/ioutil" "os" "path" "path/filepath" - "runtime/debug" "strconv" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile" "cmd/go/internal/modconv" "cmd/go/internal/modfetch" @@ -35,8 +34,7 @@ import ( ) var ( - mustUseModules = false - initialized bool + initialized bool modRoot string Target module.Version @@ -52,20 +50,42 @@ var ( gopath string - CmdModInit bool // running 'go mod init' - CmdModModule string // module argument for 'go mod init' + // RootMode determines whether a module root is needed. + RootMode Root + + // ForceUseModules may be set to force modules to be enabled when + // GO111MODULE=auto or to report an error when GO111MODULE=off. + ForceUseModules bool allowMissingModuleImports bool ) +type Root int + +const ( + // AutoRoot is the default for most commands. modload.Init will look for + // a go.mod file in the current directory or any parent. If none is found, + // modules may be disabled (GO111MODULE=on) or commands may run in a + // limited module mode. + AutoRoot Root = iota + + // NoRoot is used for commands that run in module mode and ignore any go.mod + // file the current directory or in parent directories. + NoRoot + + // NeedRoot is used for commands that must run in module mode and don't + // make sense without a main module. + NeedRoot +) + // ModFile returns the parsed go.mod file. // -// Note that after calling ImportPaths or LoadBuildList, +// Note that after calling LoadPackages or LoadAllModules, // the require statements in the modfile.File are no longer // the source of truth and will be ignored: edits made directly // will be lost at the next call to WriteGoMod. // To make permanent changes to the require statements -// in go.mod, edit it before calling ImportPaths or LoadBuildList. +// in go.mod, edit it before loading. func ModFile() *modfile.File { Init() if modFile == nil { @@ -92,19 +112,27 @@ func Init() { // Keep in sync with WillBeEnabled. We perform extra validation here, and // there are lots of diagnostics and side effects, so we can't use // WillBeEnabled directly. + var mustUseModules bool env := cfg.Getenv("GO111MODULE") switch env { default: base.Fatalf("go: unknown environment setting GO111MODULE=%s", env) - case "auto", "": - mustUseModules = false - case "on": + case "auto": + mustUseModules = ForceUseModules + case "on", "": mustUseModules = true case "off": + if ForceUseModules { + base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") + } mustUseModules = false return } + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } + // Disable any prompting for passwords by Git. // Only has an effect for 2.3.0 or later, but avoiding // the prompt in earlier versions is just too hard. @@ -132,15 +160,23 @@ func Init() { os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no") } - if CmdModInit { - // Running 'go mod init': go.mod will be created in current directory. - modRoot = base.Cwd + if modRoot != "" { + // modRoot set before Init was called ("go mod init" does this). + // No need to search for go.mod. + } else if RootMode == NoRoot { + if cfg.ModFile != "" && !base.InGOFLAGS("-modfile") { + base.Fatalf("go: -modfile cannot be used with commands that ignore the current module") + } + modRoot = "" } else { modRoot = findModuleRoot(base.Cwd) if modRoot == "" { if cfg.ModFile != "" { base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.") } + if RootMode == NeedRoot { + base.Fatalf("go: cannot find main module; see 'go help modules'") + } if !mustUseModules { // GO111MODULE is 'auto', and we can't find a module root. // Stay in GOPATH mode. @@ -154,32 +190,26 @@ func Init() { // when it happens. See golang.org/issue/26708. modRoot = "" fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir()) + if !mustUseModules { + return + } } } if cfg.ModFile != "" && !strings.HasSuffix(cfg.ModFile, ".mod") { base.Fatalf("go: -modfile=%s: file does not have .mod extension", cfg.ModFile) } - // We're in module mode. Install the hooks to make it work. - + // We're in module mode. Set any global variables that need to be set. list := filepath.SplitList(cfg.BuildContext.GOPATH) if len(list) == 0 || list[0] == "" { base.Fatalf("missing $GOPATH") } gopath = list[0] - if _, err := os.Stat(filepath.Join(gopath, "go.mod")); err == nil { + if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil { base.Fatalf("$GOPATH/go.mod exists but should not") } cfg.ModulesEnabled = true - load.ModBinDir = BinDir - load.ModLookup = Lookup - load.ModPackageModuleInfo = PackageModuleInfo - load.ModImportPaths = ImportPaths - load.ModPackageBuildInfo = PackageBuildInfo - load.ModInfoProg = ModInfoProg - load.ModImportFromFiles = ImportFromFiles - load.ModDirImportPath = DirImportPath if modRoot == "" { // We're in module mode, but not inside a module. @@ -205,10 +235,6 @@ func Init() { } } -func init() { - load.ModInit = Init -} - // WillBeEnabled checks whether modules should be enabled but does not // initialize modules by installing hooks. If Init has already been called, // WillBeEnabled returns the same result as Enabled. @@ -219,10 +245,12 @@ func init() { // be called until the command is installed and flags are parsed. Instead of // calling Init and Enabled, the main package can call this function. func WillBeEnabled() bool { - if modRoot != "" || mustUseModules { + if modRoot != "" || cfg.ModulesEnabled { + // Already enabled. return true } if initialized { + // Initialized, not enabled. return false } @@ -230,18 +258,14 @@ func WillBeEnabled() bool { // exits, so it can't call this function directly. env := cfg.Getenv("GO111MODULE") switch env { - case "on": + case "on", "": return true - case "auto", "": + case "auto": break default: return false } - if CmdModInit { - // Running 'go mod init': go.mod will be created in current directory. - return true - } if modRoot := findModuleRoot(base.Cwd); modRoot == "" { // GO111MODULE is 'auto', and we can't find a module root. // Stay in GOPATH mode. @@ -263,7 +287,7 @@ func WillBeEnabled() bool { // (usually through MustModRoot). func Enabled() bool { Init() - return modRoot != "" || mustUseModules + return modRoot != "" || cfg.ModulesEnabled } // ModRoot returns the root of the main module. @@ -297,16 +321,7 @@ func ModFilePath() string { return filepath.Join(modRoot, "go.mod") } -// printStackInDie causes die to print a stack trace. -// -// It is enabled by the testgo tag, and helps to diagnose paths that -// unexpectedly require a main module. -var printStackInDie = false - func die() { - if printStackInDie { - debug.PrintStack() - } if cfg.Getenv("GO111MODULE") == "off" { base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") } @@ -324,16 +339,16 @@ func die() { base.Fatalf("go: cannot find main module; see 'go help modules'") } -// InitMod sets Target and, if there is a main module, parses the initial build -// list from its go.mod file. If InitMod is called by 'go mod init', InitMod -// will populate go.mod in memory, possibly importing dependencies from a -// legacy configuration file. For other commands, InitMod may make other -// adjustments in memory, like adding a go directive. WriteGoMod should be -// called later to write changes out to disk. +// LoadModFile sets Target and, if there is a main module, parses the initial +// build list from its go.mod file. +// +// LoadModFile may make changes in memory, like adding a go directive and +// ensuring requirements are consistent. WriteGoMod should be called later to +// write changes out to disk or report errors in readonly mode. // -// As a side-effect, InitMod sets a default for cfg.BuildMod if it does not +// As a side-effect, LoadModFile sets a default for cfg.BuildMod if it does not // already have an explicit value. -func InitMod(ctx context.Context) { +func LoadModFile(ctx context.Context) { if len(buildList) > 0 { return } @@ -346,13 +361,6 @@ func InitMod(ctx context.Context) { return } - if CmdModInit { - // Running go mod init: do legacy module conversion - legacyModInit() - modFileToBuildList() - return - } - gomod := ModFilePath() data, err := lockedfile.Read(gomod) if err != nil { @@ -373,12 +381,6 @@ func InitMod(ctx context.Context) { base.Fatalf("go: no module declaration in go.mod.\n\tRun 'go mod edit -module=example.com/mod' to specify the module path.") } - if len(f.Syntax.Stmt) == 1 && f.Module != nil { - // Entire file is just a module statement. - // Populate require if possible. - legacyModInit() - } - if err := checkModulePathLax(f.Module.Mod.Path); err != nil { base.Fatalf("go: %v", err) } @@ -391,6 +393,73 @@ func InitMod(ctx context.Context) { } } +// CreateModFile initializes a new module by creating a go.mod file. +// +// If modPath is empty, CreateModFile will attempt to infer the path from the +// directory location within GOPATH. +// +// If a vendoring configuration file is present, CreateModFile will attempt to +// translate it to go.mod directives. The resulting build list may not be +// exactly the same as in the legacy configuration (for example, we can't get +// packages at multiple versions from the same module). +func CreateModFile(ctx context.Context, modPath string) { + modRoot = base.Cwd + Init() + modFilePath := ModFilePath() + if _, err := fsys.Stat(modFilePath); err == nil { + base.Fatalf("go: %s already exists", modFilePath) + } + + if modPath == "" { + var err error + modPath, err = findModulePath(modRoot) + if err != nil { + base.Fatalf("go: %v", err) + } + } else if err := checkModulePathLax(modPath); err != nil { + base.Fatalf("go: %v", err) + } + + fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath) + modFile = new(modfile.File) + modFile.AddModuleStmt(modPath) + addGoStmt() // Add the go directive before converted module requirements. + + convertedFrom, err := convertLegacyConfig(modPath) + if convertedFrom != "" { + fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(convertedFrom)) + } + if err != nil { + base.Fatalf("go: %v", err) + } + + modFileToBuildList() + WriteGoMod() + + // Suggest running 'go mod tidy' unless the project is empty. Even if we + // imported all the correct requirements above, we're probably missing + // some sums, so the next build command in -mod=readonly will likely fail. + // + // We look for non-hidden .go files or subdirectories to determine whether + // this is an existing project. Walking the tree for packages would be more + // accurate, but could take much longer. + empty := true + files, _ := os.ReadDir(modRoot) + for _, f := range files { + name := f.Name() + if strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") { + continue + } + if strings.HasSuffix(name, ".go") || f.IsDir() { + empty = false + break + } + } + if !empty { + fmt.Fprintf(os.Stderr, "go: run 'go mod tidy' to add module requirements and sums\n") + } +} + // checkModulePathLax checks that the path meets some minimum requirements // to avoid confusing users or the module cache. The requirements are weaker // than those of module.CheckPath to allow room for weakening module path @@ -518,21 +587,24 @@ func modFileToBuildList() { // setDefaultBuildMod sets a default value for cfg.BuildMod // if it is currently empty. func setDefaultBuildMod() { - if cfg.BuildMod != "" { + if cfg.BuildModExplicit { // Don't override an explicit '-mod=' argument. return } - cfg.BuildMod = "mod" + if cfg.CmdName == "get" || strings.HasPrefix(cfg.CmdName, "mod ") { - // Don't set -mod implicitly for commands whose purpose is to - // manipulate the build list. + // 'get' and 'go mod' commands may update go.mod automatically. + // TODO(jayconrod): should this narrower? Should 'go mod download' or + // 'go mod graph' update go.mod by default? + cfg.BuildMod = "mod" return } if modRoot == "" { + cfg.BuildMod = "readonly" return } - if fi, err := os.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() { modGo := "unspecified" if index.goVersionV != "" { if semver.Compare(index.goVersionV, "v1.14") >= 0 { @@ -546,52 +618,31 @@ func setDefaultBuildMod() { } } - // Since a vendor directory exists, we have a non-trivial reason for - // choosing -mod=mod, although it probably won't be used for anything. - // Record the reason anyway for consistency. - // It may be overridden if we switch to mod=readonly below. - cfg.BuildModReason = fmt.Sprintf("Go version in go.mod is %s.", modGo) + // Since a vendor directory exists, we should record why we didn't use it. + // This message won't normally be shown, but it may appear with import errors. + cfg.BuildModReason = fmt.Sprintf("Go version in go.mod is %s, so vendor directory was not used.", modGo) } - p := ModFilePath() - if fi, err := os.Stat(p); err == nil && !hasWritePerm(p, fi) { - cfg.BuildMod = "readonly" - cfg.BuildModReason = "go.mod file is read-only." - } + cfg.BuildMod = "readonly" } -func legacyModInit() { - if modFile == nil { - path, err := findModulePath(modRoot) - if err != nil { - base.Fatalf("go: %v", err) - } - fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", path) - modFile = new(modfile.File) - modFile.AddModuleStmt(path) - addGoStmt() // Add the go directive before converted module requirements. - } - +// convertLegacyConfig imports module requirements from a legacy vendoring +// configuration file, if one is present. +func convertLegacyConfig(modPath string) (from string, err error) { for _, name := range altConfigs { cfg := filepath.Join(modRoot, name) - data, err := ioutil.ReadFile(cfg) + data, err := os.ReadFile(cfg) if err == nil { convert := modconv.Converters[name] if convert == nil { - return + return "", nil } - fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(cfg)) cfg = filepath.ToSlash(cfg) - if err := modconv.ConvertLegacyConfig(modFile, cfg, data); err != nil { - base.Fatalf("go: %v", err) - } - if len(modFile.Syntax.Stmt) == 1 { - // Add comment to avoid re-converting every time it runs. - modFile.AddComment("// go: no requirements found in " + name) - } - return + err := modconv.ConvertLegacyConfig(modFile, cfg, data) + return name, err } } + return "", nil } // addGoStmt adds a go directive to the go.mod file if it does not already include one. @@ -633,7 +684,7 @@ func findModuleRoot(dir string) (root string) { // Look for enclosing go.mod. for { - if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() { return dir } d := filepath.Dir(dir) @@ -657,7 +708,7 @@ func findAltConfig(dir string) (root, name string) { } for { for _, name := range altConfigs { - if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() { return dir, name } } @@ -671,14 +722,6 @@ func findAltConfig(dir string) (root, name string) { } func findModulePath(dir string) (string, error) { - if CmdModModule != "" { - // Running go mod init x/y/z; return x/y/z. - if err := module.CheckImportPath(CmdModModule); err != nil { - return "", err - } - return CmdModModule, nil - } - // TODO(bcmills): once we have located a plausible module path, we should // query version control (if available) to verify that it matches the major // version of the most recent tag. @@ -687,9 +730,9 @@ func findModulePath(dir string) (string, error) { // Cast about for import comments, // first in top-level directory, then in subdirectories. - list, _ := ioutil.ReadDir(dir) + list, _ := os.ReadDir(dir) for _, info := range list { - if info.Mode().IsRegular() && strings.HasSuffix(info.Name(), ".go") { + if info.Type().IsRegular() && strings.HasSuffix(info.Name(), ".go") { if com := findImportComment(filepath.Join(dir, info.Name())); com != "" { return com, nil } @@ -697,9 +740,9 @@ func findModulePath(dir string) (string, error) { } for _, info1 := range list { if info1.IsDir() { - files, _ := ioutil.ReadDir(filepath.Join(dir, info1.Name())) + files, _ := os.ReadDir(filepath.Join(dir, info1.Name())) for _, info2 := range files { - if info2.Mode().IsRegular() && strings.HasSuffix(info2.Name(), ".go") { + if info2.Type().IsRegular() && strings.HasSuffix(info2.Name(), ".go") { if com := findImportComment(filepath.Join(dir, info1.Name(), info2.Name())); com != "" { return path.Dir(com), nil } @@ -709,7 +752,7 @@ func findModulePath(dir string) (string, error) { } // Look for Godeps.json declaring import path. - data, _ := ioutil.ReadFile(filepath.Join(dir, "Godeps/Godeps.json")) + data, _ := os.ReadFile(filepath.Join(dir, "Godeps/Godeps.json")) var cfg1 struct{ ImportPath string } json.Unmarshal(data, &cfg1) if cfg1.ImportPath != "" { @@ -717,7 +760,7 @@ func findModulePath(dir string) (string, error) { } // Look for vendor.json declaring import path. - data, _ = ioutil.ReadFile(filepath.Join(dir, "vendor/vendor.json")) + data, _ = os.ReadFile(filepath.Join(dir, "vendor/vendor.json")) var cfg2 struct{ RootPath string } json.Unmarshal(data, &cfg2) if cfg2.RootPath != "" { @@ -769,7 +812,7 @@ var ( ) func findImportComment(file string) string { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return "" } @@ -809,7 +852,7 @@ func MinReqs() mvs.Reqs { retain = append(retain, m.Path) } } - min, err := mvs.Req(Target, retain, Reqs()) + min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList}) if err != nil { base.Fatalf("go: %v", err) } @@ -855,21 +898,23 @@ func WriteGoMod() { if dirty && cfg.BuildMod == "readonly" { // If we're about to fail due to -mod=readonly, // prefer to report a dirty go.mod over a dirty go.sum - if cfg.BuildModReason != "" { + if cfg.BuildModExplicit { + base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly") + } else if cfg.BuildModReason != "" { base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason) } else { - base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly") + base.Fatalf("go: updates to go.mod needed; try 'go mod tidy' first") } } - // Always update go.sum, even if we didn't change go.mod: we may have - // downloaded modules that we didn't have before. - modfetch.WriteGoSum(keepSums()) - if !dirty && cfg.CmdName != "mod tidy" { // The go.mod file has the same semantic content that it had before // (but not necessarily the same exact bytes). - // Ignore any intervening edits. + // Don't write go.mod, but write go.sum in case we added or trimmed sums. + // 'go mod init' shouldn't write go.sum, since it will be incomplete. + if cfg.CmdName != "mod init" { + modfetch.WriteGoSum(keepSums(true)) + } return } @@ -880,6 +925,12 @@ func WriteGoMod() { defer func() { // At this point we have determined to make the go.mod file on disk equal to new. index = indexModFile(new, modFile, false) + + // Update go.sum after releasing the side lock and refreshing the index. + // 'go mod init' shouldn't write go.sum, since it will be incomplete. + if cfg.CmdName != "mod init" { + modfetch.WriteGoSum(keepSums(true)) + } }() // Make a best-effort attempt to acquire the side lock, only to exclude @@ -917,56 +968,99 @@ func WriteGoMod() { // keepSums returns a set of module sums to preserve in go.sum. The set // includes entries for all modules used to load packages (according to -// the last load function like ImportPaths, LoadALL, etc.). It also contains -// entries for go.mod files needed for MVS (the version of these entries -// ends with "/go.mod"). -func keepSums() map[module.Version]bool { - // Walk the module graph and keep sums needed by MVS. +// the last load function such as LoadPackages or ImportFromFiles). +// It also contains entries for go.mod files needed for MVS (the version +// of these entries ends with "/go.mod"). +// +// If addDirect is true, the set also includes sums for modules directly +// required by go.mod, as represented by the index, with replacements applied. +func keepSums(addDirect bool) map[module.Version]bool { + // Re-derive the build list using the current list of direct requirements. + // Keep the sum for the go.mod of each visited module version (or its + // replacement). modkey := func(m module.Version) module.Version { return module.Version{Path: m.Path, Version: m.Version + "/go.mod"} } keep := make(map[module.Version]bool) - replaced := make(map[module.Version]bool) - reqs := Reqs() - var walk func(module.Version) - walk = func(m module.Version) { - // If we build using a replacement module, keep the sum for the replacement, - // since that's the code we'll actually use during a build. - // - // TODO(golang.org/issue/29182): Perhaps we should keep both sums, and the - // sums for both sets of transitive requirements. - r := Replacement(m) - if r.Path == "" { - keep[modkey(m)] = true - } else { - replaced[m] = true - keep[modkey(r)] = true - } - list, _ := reqs.Required(m) - for _, r := range list { - if !keep[modkey(r)] && !replaced[r] { - walk(r) + var mu sync.Mutex + reqs := &keepSumReqs{ + Reqs: &mvsReqs{buildList: buildList}, + visit: func(m module.Version) { + // If we build using a replacement module, keep the sum for the replacement, + // since that's the code we'll actually use during a build. + mu.Lock() + r := Replacement(m) + if r.Path == "" { + keep[modkey(m)] = true + } else { + keep[modkey(r)] = true } - } + mu.Unlock() + }, + } + buildList, err := mvs.BuildList(Target, reqs) + if err != nil { + panic(fmt.Sprintf("unexpected error reloading build list: %v", err)) } - walk(Target) - // Add entries for modules that provided packages loaded with ImportPaths, - // LoadALL, or similar functions. + // Add entries for modules in the build list with paths that are prefixes of + // paths of loaded packages. We need to retain sums for modules needed to + // report ambiguous import errors. We use our re-derived build list, + // since the global build list may have been tidied. if loaded != nil { + actualMods := make(map[string]module.Version) + for _, m := range buildList[1:] { + if r := Replacement(m); r.Path != "" { + actualMods[m.Path] = r + } else { + actualMods[m.Path] = m + } + } for _, pkg := range loaded.pkgs { - m := pkg.mod + if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil { + continue + } + for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) { + if m, ok := actualMods[prefix]; ok { + keep[m] = true + } + } + } + } + + // Add entries for modules directly required by go.mod. + if addDirect { + for m := range index.require { + var kept module.Version if r := Replacement(m); r.Path != "" { - keep[r] = true + kept = r } else { - keep[m] = true + kept = m } + keep[kept] = true + keep[module.Version{Path: kept.Path, Version: kept.Version + "/go.mod"}] = true } } return keep } +// keepSumReqs embeds another Reqs implementation. The Required method +// calls visit for each version in the module graph. +type keepSumReqs struct { + mvs.Reqs + visit func(module.Version) +} + +func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) { + r.visit(m) + return r.Reqs.Required(m) +} + func TrimGoSum() { - modfetch.TrimGoSum(keepSums()) + // Don't retain sums for direct requirements in go.mod. When TrimGoSum is + // called, go.mod has not been updated, and it may contain requirements on + // modules deleted from the build list. + addDirect := false + modfetch.TrimGoSum(keepSums(addDirect)) } diff --git a/src/cmd/go/internal/modload/list.go b/src/cmd/go/internal/modload/list.go index 8c7b9a3950..3491f941cd 100644 --- a/src/cmd/go/internal/modload/list.go +++ b/src/cmd/go/internal/modload/list.go @@ -58,7 +58,7 @@ func ListModules(ctx context.Context, args []string, listU, listVersions, listRe } func listModules(ctx context.Context, args []string, listVersions, listRetracted bool) []*modinfo.ModulePublic { - LoadBuildList(ctx) + LoadAllModules(ctx) if len(args) == 0 { return []*modinfo.ModulePublic{moduleInfo(ctx, buildList[0], true, listRetracted)} } diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go index 2a37f1d874..a0f93d028a 100644 --- a/src/cmd/go/internal/modload/load.go +++ b/src/cmd/go/internal/modload/load.go @@ -4,66 +4,196 @@ package modload +// This file contains the module-mode package loader, as well as some accessory +// functions pertaining to the package import graph. +// +// There are two exported entry points into package loading — LoadPackages and +// ImportFromFiles — both implemented in terms of loadFromRoots, which itself +// manipulates an instance of the loader struct. +// +// Although most of the loading state is maintained in the loader struct, +// one key piece - the build list - is a global, so that it can be modified +// separate from the loading operation, such as during "go get" +// upgrades/downgrades or in "go mod" operations. +// TODO(#40775): It might be nice to make the loader take and return +// a buildList rather than hard-coding use of the global. +// +// Loading is an iterative process. On each iteration, we try to load the +// requested packages and their transitive imports, then try to resolve modules +// for any imported packages that are still missing. +// +// The first step of each iteration identifies a set of “root” packages. +// Normally the root packages are exactly those matching the named pattern +// arguments. However, for the "all" meta-pattern, the final set of packages is +// computed from the package import graph, and therefore cannot be an initial +// input to loading that graph. Instead, the root packages for the "all" pattern +// are those contained in the main module, and allPatternIsRoot parameter to the +// loader instructs it to dynamically expand those roots to the full "all" +// pattern as loading progresses. +// +// The pkgInAll flag on each loadPkg instance tracks whether that +// package is known to match the "all" meta-pattern. +// A package matches the "all" pattern if: +// - it is in the main module, or +// - it is imported by any test in the main module, or +// - it is imported by another package in "all", or +// - the main module specifies a go version ≤ 1.15, and the package is imported +// by a *test of* another package in "all". +// +// When we implement lazy loading, we will record the modules providing packages +// in "all" even when we are only loading individual packages, so we set the +// pkgInAll flag regardless of the whether the "all" pattern is a root. +// (This is necessary to maintain the “import invariant” described in +// https://golang.org/design/36460-lazy-module-loading.) +// +// Because "go mod vendor" prunes out the tests of vendored packages, the +// behavior of the "all" pattern with -mod=vendor in Go 1.11–1.15 is the same +// as the "all" pattern (regardless of the -mod flag) in 1.16+. +// The allClosesOverTests parameter to the loader indicates whether the "all" +// pattern should close over tests (as in Go 1.11–1.15) or stop at only those +// packages transitively imported by the packages and tests in the main module +// ("all" in Go 1.16+ and "go mod vendor" in Go 1.11+). +// +// Note that it is possible for a loaded package NOT to be in "all" even when we +// are loading the "all" pattern. For example, packages that are transitive +// dependencies of other roots named on the command line must be loaded, but are +// not in "all". (The mod_notall test illustrates this behavior.) +// Similarly, if the LoadTests flag is set but the "all" pattern does not close +// over test dependencies, then when we load the test of a package that is in +// "all" but outside the main module, the dependencies of that test will not +// necessarily themselves be in "all". (That configuration does not arise in Go +// 1.11–1.15, but it will be possible in Go 1.16+.) +// +// Loading proceeds from the roots, using a parallel work-queue with a limit on +// the amount of active work (to avoid saturating disks, CPU cores, and/or +// network connections). Each package is added to the queue the first time it is +// imported by another package. When we have finished identifying the imports of +// a package, we add the test for that package if it is needed. A test may be +// needed if: +// - the package matches a root pattern and tests of the roots were requested, or +// - the package is in the main module and the "all" pattern is requested +// (because the "all" pattern includes the dependencies of tests in the main +// module), or +// - the package is in "all" and the definition of "all" we are using includes +// dependencies of tests (as is the case in Go ≤1.15). +// +// After all available packages have been loaded, we examine the results to +// identify any requested or imported packages that are still missing, and if +// so, which modules we could add to the module graph in order to make the +// missing packages available. We add those to the module graph and iterate, +// until either all packages resolve successfully or we cannot identify any +// module that would resolve any remaining missing package. +// +// If the main module is “tidy” (that is, if "go mod tidy" is a no-op for it) +// and all requested packages are in "all", then loading completes in a single +// iteration. +// TODO(bcmills): We should also be able to load in a single iteration if the +// requested packages all come from modules that are themselves tidy, regardless +// of whether those packages are in "all". Today, that requires two iterations +// if those packages are not found in existing dependencies of the main module. + import ( "bytes" "context" "errors" "fmt" "go/build" + "io/fs" "os" "path" pathpkg "path" "path/filepath" + "reflect" + "runtime" "sort" "strings" + "sync" + "sync/atomic" "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/imports" "cmd/go/internal/modfetch" "cmd/go/internal/mvs" "cmd/go/internal/par" "cmd/go/internal/search" "cmd/go/internal/str" - "cmd/go/internal/trace" "golang.org/x/mod/module" ) -// buildList is the list of modules to use for building packages. -// It is initialized by calling ImportPaths, ImportFromFiles, -// LoadALL, or LoadBuildList, each of which uses loaded.load. -// -// Ideally, exactly ONE of those functions would be called, -// and exactly once. Most of the time, that's true. -// During "go get" it may not be. TODO(rsc): Figure out if -// that restriction can be established, or else document why not. -// -var buildList []module.Version - // loaded is the most recently-used package loader. // It holds details about individual packages. -// -// Note that loaded.buildList is only valid during a load operation; -// afterward, it is copied back into the global buildList, -// which should be used instead. var loaded *loader -// ImportPaths returns the set of packages matching the args (patterns), -// on the target platform. Modules may be added to the build list -// to satisfy new imports. -func ImportPaths(ctx context.Context, patterns []string) []*search.Match { - matches := ImportPathsQuiet(ctx, patterns, imports.Tags()) - search.WarnUnmatched(matches) - return matches +// PackageOpts control the behavior of the LoadPackages function. +type PackageOpts struct { + // Tags are the build tags in effect (as interpreted by the + // cmd/go/internal/imports package). + // If nil, treated as equivalent to imports.Tags(). + Tags map[string]bool + + // ResolveMissingImports indicates that we should attempt to add module + // dependencies as needed to resolve imports of packages that are not found. + // + // For commands that support the -mod flag, resolving imports may still fail + // if the flag is set to "readonly" (the default) or "vendor". + ResolveMissingImports bool + + // AllowPackage, if non-nil, is called after identifying the module providing + // each package. If AllowPackage returns a non-nil error, that error is set + // for the package, and the imports and test of that package will not be + // loaded. + // + // AllowPackage may be invoked concurrently by multiple goroutines, + // and may be invoked multiple times for a given package path. + AllowPackage func(ctx context.Context, path string, mod module.Version) error + + // LoadTests loads the test dependencies of each package matching a requested + // pattern. If ResolveMissingImports is also true, test dependencies will be + // resolved if missing. + LoadTests bool + + // UseVendorAll causes the "all" package pattern to be interpreted as if + // running "go mod vendor" (or building with "-mod=vendor"). + // + // This is a no-op for modules that declare 'go 1.16' or higher, for which this + // is the default (and only) interpretation of the "all" pattern in module mode. + UseVendorAll bool + + // AllowErrors indicates that LoadPackages should not terminate the process if + // an error occurs. + AllowErrors bool + + // SilenceErrors indicates that LoadPackages should not print errors + // that occur while loading packages. SilenceErrors implies AllowErrors. + SilenceErrors bool + + // SilenceUnmatchedWarnings suppresses the warnings normally emitted for + // patterns that did not match any packages. + SilenceUnmatchedWarnings bool } -// ImportPathsQuiet is like ImportPaths but does not warn about patterns with -// no matches. It also lets the caller specify a set of build tags to match -// packages. The build tags should typically be imports.Tags() or -// imports.AnyTags(); a nil map has no special meaning. -func ImportPathsQuiet(ctx context.Context, patterns []string, tags map[string]bool) []*search.Match { - updateMatches := func(matches []*search.Match, iterating bool) { +// LoadPackages identifies the set of packages matching the given patterns and +// loads the packages in the import graph rooted at that set. +func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (matches []*search.Match, loadedPackages []string) { + LoadModFile(ctx) + if opts.Tags == nil { + opts.Tags = imports.Tags() + } + + patterns = search.CleanPatterns(patterns) + matches = make([]*search.Match, 0, len(patterns)) + allPatternIsRoot := false + for _, pattern := range patterns { + matches = append(matches, search.NewMatch(pattern)) + if pattern == "all" { + allPatternIsRoot = true + } + } + + updateMatches := func(ld *loader) { for _, m := range matches { switch { case m.IsLocal(): @@ -90,7 +220,7 @@ func ImportPathsQuiet(ctx context.Context, patterns []string, tags map[string]bo // indicates that. ModRoot() - if !iterating { + if ld != nil { m.AddError(err) } continue @@ -103,19 +233,18 @@ func ImportPathsQuiet(ctx context.Context, patterns []string, tags map[string]bo case strings.Contains(m.Pattern(), "..."): m.Errs = m.Errs[:0] - matchPackages(ctx, m, loaded.tags, includeStd, buildList) + matchPackages(ctx, m, opts.Tags, includeStd, buildList) case m.Pattern() == "all": - loaded.testAll = true - if iterating { - // Enumerate the packages in the main module. - // We'll load the dependencies as we find them. + if ld == nil { + // The initial roots are the packages in the main module. + // loadFromRoots will expand that to "all". m.Errs = m.Errs[:0] - matchPackages(ctx, m, loaded.tags, omitStd, []module.Version{Target}) + matchPackages(ctx, m, opts.Tags, omitStd, []module.Version{Target}) } else { // Starting with the packages in the main module, // enumerate the full list of "all". - m.Pkgs = loaded.computePatternAll(m.Pkgs) + m.Pkgs = ld.computePatternAll() } case m.Pattern() == "std" || m.Pattern() == "cmd": @@ -129,49 +258,71 @@ func ImportPathsQuiet(ctx context.Context, patterns []string, tags map[string]bo } } - InitMod(ctx) + loaded = loadFromRoots(loaderParams{ + PackageOpts: opts, - var matches []*search.Match - for _, pattern := range search.CleanPatterns(patterns) { - matches = append(matches, search.NewMatch(pattern)) - } + allClosesOverTests: index.allPatternClosesOverTests() && !opts.UseVendorAll, + allPatternIsRoot: allPatternIsRoot, - loaded = newLoader(tags) - loaded.load(func() []string { - var roots []string - updateMatches(matches, true) - for _, m := range matches { - roots = append(roots, m.Pkgs...) - } - return roots + listRoots: func() (roots []string) { + updateMatches(nil) + for _, m := range matches { + roots = append(roots, m.Pkgs...) + } + return roots + }, }) // One last pass to finalize wildcards. - updateMatches(matches, false) - checkMultiplePaths() - WriteGoMod() + updateMatches(loaded) - return matches -} + // Report errors, if any. + checkMultiplePaths() + for _, pkg := range loaded.pkgs { + if pkg.err != nil { + if pkg.flags.has(pkgInAll) { + if imErr := (*ImportMissingError)(nil); errors.As(pkg.err, &imErr) { + imErr.inAll = true + } else if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) { + sumErr.inAll = true + } + } -// checkMultiplePaths verifies that a given module path is used as itself -// or as a replacement for another module, but not both at the same time. -// -// (See https://golang.org/issue/26607 and https://golang.org/issue/34650.) -func checkMultiplePaths() { - firstPath := make(map[module.Version]string, len(buildList)) - for _, mod := range buildList { - src := mod - if rep := Replacement(mod); rep.Path != "" { - src = rep + if !opts.SilenceErrors { + if opts.AllowErrors { + fmt.Fprintf(os.Stderr, "%s: %v\n", pkg.stackText(), pkg.err) + } else { + base.Errorf("%s: %v", pkg.stackText(), pkg.err) + } + } } - if prev, ok := firstPath[src]; !ok { - firstPath[src] = mod.Path - } else if prev != mod.Path { - base.Errorf("go: %s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path) + if !pkg.isTest() { + loadedPackages = append(loadedPackages, pkg.path) + } + } + if !opts.SilenceErrors { + // Also list errors in matching patterns (such as directory permission + // errors for wildcard patterns). + for _, match := range matches { + for _, err := range match.Errs { + if opts.AllowErrors { + fmt.Fprintf(os.Stderr, "%v\n", err) + } else { + base.Errorf("%v", err) + } + } } } base.ExitIfErrors() + + if !opts.SilenceUnmatchedWarnings { + search.WarnUnmatched(matches) + } + + // Success! Update go.mod (if needed) and return the results. + WriteGoMod() + sort.Strings(loadedPackages) + return matches, loadedPackages } // matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories @@ -220,11 +371,11 @@ func resolveLocalPackage(dir string) (string, error) { // If the named directory does not exist or contains no Go files, // the package does not exist. // Other errors may affect package loading, but not resolution. - if _, err := os.Stat(absDir); err != nil { + if _, err := fsys.Stat(absDir); err != nil { if os.IsNotExist(err) { // Canonicalize OS-specific errors to errDirectoryNotFound so that error // messages will be easier for users to search for. - return "", &os.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound} + return "", &fs.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound} } return "", err } @@ -310,7 +461,7 @@ var ( // pathInModuleCache returns the import path of the directory dir, // if dir is in the module cache copy of a module in our build list. func pathInModuleCache(dir string) string { - for _, m := range buildList[1:] { + tryMod := func(m module.Version) (string, bool) { var root string var err error if repl := Replacement(m); repl.Path != "" && repl.Version == "" { @@ -324,13 +475,26 @@ func pathInModuleCache(dir string) string { root, err = modfetch.DownloadDir(m) } if err != nil { - continue + return "", false } - if sub := search.InDir(dir, root); sub != "" { - sub = filepath.ToSlash(sub) - if !strings.Contains(sub, "/vendor/") && !strings.HasPrefix(sub, "vendor/") && !strings.Contains(sub, "@") { - return path.Join(m.Path, filepath.ToSlash(sub)) - } + + sub := search.InDir(dir, root) + if sub == "" { + return "", false + } + sub = filepath.ToSlash(sub) + if strings.Contains(sub, "/vendor/") || strings.HasPrefix(sub, "vendor/") || strings.Contains(sub, "@") { + return "", false + } + + return path.Join(m.Path, filepath.ToSlash(sub)), true + } + + for _, m := range buildList[1:] { + if importPath, ok := tryMod(m); ok { + // checkMultiplePaths ensures that a module can be used for at most one + // requirement, so this must be it. + return importPath } } return "" @@ -339,7 +503,7 @@ func pathInModuleCache(dir string) string { // ImportFromFiles adds modules to the build list as needed // to satisfy the imports in the named Go source files. func ImportFromFiles(ctx context.Context, gofiles []string) { - InitMod(ctx) + LoadModFile(ctx) tags := imports.Tags() imports, testImports, err := imports.ScanFiles(gofiles, tags) @@ -347,12 +511,17 @@ func ImportFromFiles(ctx context.Context, gofiles []string) { base.Fatalf("go: %v", err) } - loaded = newLoader(tags) - loaded.load(func() []string { - var roots []string - roots = append(roots, imports...) - roots = append(roots, testImports...) - return roots + loaded = loadFromRoots(loaderParams{ + PackageOpts: PackageOpts{ + Tags: tags, + ResolveMissingImports: true, + }, + allClosesOverTests: index.allPatternClosesOverTests(), + listRoots: func() (roots []string) { + roots = append(roots, imports...) + roots = append(roots, testImports...) + return roots + }, }) WriteGoMod() } @@ -360,9 +529,10 @@ func ImportFromFiles(ctx context.Context, gofiles []string) { // DirImportPath returns the effective import path for dir, // provided it is within the main module, or else returns ".". func DirImportPath(dir string) string { - if modRoot == "" { + if !HasModRoot() { return "." } + LoadModFile(context.TODO()) if !filepath.IsAbs(dir) { dir = filepath.Join(base.Cwd, dir) @@ -383,79 +553,13 @@ func DirImportPath(dir string) string { return "." } -// LoadBuildList loads and returns the build list from go.mod. -// The loading of the build list happens automatically in ImportPaths: -// LoadBuildList need only be called if ImportPaths is not -// (typically in commands that care about the module but -// no particular package). -func LoadBuildList(ctx context.Context) []module.Version { - ctx, span := trace.StartSpan(ctx, "LoadBuildList") - defer span.Done() - InitMod(ctx) - ReloadBuildList() - WriteGoMod() - return buildList -} - -func ReloadBuildList() []module.Version { - loaded = newLoader(imports.Tags()) - loaded.load(func() []string { return nil }) - return buildList -} - -// LoadALL returns the set of all packages in the current module -// and their dependencies in any other modules, without filtering -// due to build tags, except "+build ignore". -// It adds modules to the build list as needed to satisfy new imports. -// This set is useful for deciding whether a particular import is needed -// anywhere in a module. -func LoadALL(ctx context.Context) []string { - return loadAll(ctx, true) -} - -// LoadVendor is like LoadALL but only follows test dependencies -// for tests in the main module. Tests in dependency modules are -// ignored completely. -// This set is useful for identifying the which packages to include in a vendor directory. -func LoadVendor(ctx context.Context) []string { - return loadAll(ctx, false) -} - -func loadAll(ctx context.Context, testAll bool) []string { - InitMod(ctx) - - loaded = newLoader(imports.AnyTags()) - loaded.isALL = true - loaded.testAll = testAll - if !testAll { - loaded.testRoots = true - } - all := TargetPackages(ctx, "...") - loaded.load(func() []string { return all.Pkgs }) - checkMultiplePaths() - WriteGoMod() - - var paths []string - for _, pkg := range loaded.pkgs { - if pkg.err != nil { - base.Errorf("%s: %v", pkg.stackText(), pkg.err) - continue - } - paths = append(paths, pkg.path) - } - for _, err := range all.Errs { - base.Errorf("%v", err) - } - base.ExitIfErrors() - return paths -} - // TargetPackages returns the list of packages in the target (top-level) module // matching pattern, which may be relative to the working directory, under all // build tag settings. func TargetPackages(ctx context.Context, pattern string) *search.Match { // TargetPackages is relative to the main module, so ensure that the main // module is a thing that can contain packages. + LoadModFile(ctx) ModRoot() m := search.NewMatch(pattern) @@ -463,52 +567,6 @@ func TargetPackages(ctx context.Context, pattern string) *search.Match { return m } -// BuildList returns the module build list, -// typically constructed by a previous call to -// LoadBuildList or ImportPaths. -// The caller must not modify the returned list. -func BuildList() []module.Version { - return buildList -} - -// SetBuildList sets the module build list. -// The caller is responsible for ensuring that the list is valid. -// SetBuildList does not retain a reference to the original list. -func SetBuildList(list []module.Version) { - buildList = append([]module.Version{}, list...) -} - -// TidyBuildList trims the build list to the minimal requirements needed to -// retain the same versions of all packages from the preceding Load* or -// ImportPaths* call. -func TidyBuildList() { - used := map[module.Version]bool{Target: true} - for _, pkg := range loaded.pkgs { - used[pkg.mod] = true - } - - keep := []module.Version{Target} - var direct []string - for _, m := range buildList[1:] { - if used[m] { - keep = append(keep, m) - if loaded.direct[m.Path] { - direct = append(direct, m.Path) - } - } else if cfg.BuildV { - if _, ok := index.require[m]; ok { - fmt.Fprintf(os.Stderr, "unused %s\n", m.Path) - } - } - } - - min, err := mvs.Req(Target, direct, &mvsReqs{buildList: keep}) - if err != nil { - base.Fatalf("go: %v", err) - } - buildList = append([]module.Version{Target}, min...) -} - // ImportMap returns the actual package import path // for an import path found in source code. // If the given import path does not appear in the source code @@ -563,12 +621,6 @@ func PackageImports(path string) (imports, testImports []string) { return imports, testImports } -// ModuleUsedDirectly reports whether the main module directly imports -// some package in the module with the given path. -func ModuleUsedDirectly(path string) bool { - return loaded.direct[path] -} - // Lookup returns the source directory, import path, and any loading error for // the package at path as imported from the package in parentDir. // Lookup requires that one of the Load functions in this package has already @@ -604,128 +656,193 @@ func Lookup(parentPath string, parentIsStd bool, path string) (dir, realPath str // the required packages for a particular build, // checking that the packages are available in the module set, // and updating the module set if needed. -// Loading is an iterative process: try to load all the needed packages, -// but if imports are missing, try to resolve those imports, and repeat. -// -// Although most of the loading state is maintained in the loader struct, -// one key piece - the build list - is a global, so that it can be modified -// separate from the loading operation, such as during "go get" -// upgrades/downgrades or in "go mod" operations. -// TODO(rsc): It might be nice to make the loader take and return -// a buildList rather than hard-coding use of the global. type loader struct { - tags map[string]bool // tags for scanDir - testRoots bool // include tests for roots - isALL bool // created with LoadALL - testAll bool // include tests for all packages - forceStdVendor bool // if true, load standard-library dependencies from the vendor subtree + loaderParams + + work *par.Queue // reset on each iteration roots []*loadPkg - pkgs []*loadPkg - work *par.Work // current work queue - pkgCache *par.Cache // map from string to *loadPkg + pkgCache *par.Cache // package path (string) → *loadPkg + pkgs []*loadPkg // transitive closure of loaded packages and tests; populated in buildStacks // computed at end of iterations direct map[string]bool // imported directly by main module } -// LoadTests controls whether the loaders load tests of the root packages. -var LoadTests bool +// loaderParams configure the packages loaded by, and the properties reported +// by, a loader instance. +type loaderParams struct { + PackageOpts -func newLoader(tags map[string]bool) *loader { - ld := new(loader) - ld.tags = tags - ld.testRoots = LoadTests - - // Inside the "std" and "cmd" modules, we prefer to use the vendor directory - // unless the command explicitly changes the module graph. - if !targetInGorootSrc || (cfg.CmdName != "get" && !strings.HasPrefix(cfg.CmdName, "mod ")) { - ld.forceStdVendor = true - } + allClosesOverTests bool // Does the "all" pattern include the transitive closure of tests of packages in "all"? + allPatternIsRoot bool // Is the "all" pattern an additional root? - return ld + listRoots func() []string } func (ld *loader) reset() { + select { + case <-ld.work.Idle(): + default: + panic("loader.reset when not idle") + } + ld.roots = nil - ld.pkgs = nil - ld.work = new(par.Work) ld.pkgCache = new(par.Cache) + ld.pkgs = nil } // A loadPkg records information about a single loaded package. type loadPkg struct { - path string // import path + // Populated at construction time: + path string // import path + testOf *loadPkg + + // Populated at construction time and updated by (*loader).applyPkgFlags: + flags atomicLoadPkgFlags + + // Populated by (*loader).load: mod module.Version // module providing package dir string // directory containing source code - imports []*loadPkg // packages imported by this one err error // error loading package - stack *loadPkg // package importing this one in minimal import stack for this pkg - test *loadPkg // package with test imports, if we need test - testOf *loadPkg - testImports []string // test-only imports, saved for use by pkg.test. + imports []*loadPkg // packages imported by this one + testImports []string // test-only imports, saved for use by pkg.test. + inStd bool + + // Populated by (*loader).pkgTest: + testOnce sync.Once + test *loadPkg + + // Populated by postprocessing in (*loader).buildStacks: + stack *loadPkg // package importing this one in minimal import stack for this pkg +} + +// loadPkgFlags is a set of flags tracking metadata about a package. +type loadPkgFlags int8 + +const ( + // pkgInAll indicates that the package is in the "all" package pattern, + // regardless of whether we are loading the "all" package pattern. + // + // When the pkgInAll flag and pkgImportsLoaded flags are both set, the caller + // who set the last of those flags must propagate the pkgInAll marking to all + // of the imports of the marked package. + // + // A test is marked with pkgInAll if that test would promote the packages it + // imports to be in "all" (such as when the test is itself within the main + // module, or when ld.allClosesOverTests is true). + pkgInAll loadPkgFlags = 1 << iota + + // pkgIsRoot indicates that the package matches one of the root package + // patterns requested by the caller. + // + // If LoadTests is set, then when pkgIsRoot and pkgImportsLoaded are both set, + // the caller who set the last of those flags must populate a test for the + // package (in the pkg.test field). + // + // If the "all" pattern is included as a root, then non-test packages in "all" + // are also roots (and must be marked pkgIsRoot). + pkgIsRoot + + // pkgImportsLoaded indicates that the imports and testImports fields of a + // loadPkg have been populated. + pkgImportsLoaded +) + +// has reports whether all of the flags in cond are set in f. +func (f loadPkgFlags) has(cond loadPkgFlags) bool { + return f&cond == cond +} + +// An atomicLoadPkgFlags stores a loadPkgFlags for which individual flags can be +// added atomically. +type atomicLoadPkgFlags struct { + bits int32 +} + +// update sets the given flags in af (in addition to any flags already set). +// +// update returns the previous flag state so that the caller may determine which +// flags were newly-set. +func (af *atomicLoadPkgFlags) update(flags loadPkgFlags) (old loadPkgFlags) { + for { + old := atomic.LoadInt32(&af.bits) + new := old | int32(flags) + if new == old || atomic.CompareAndSwapInt32(&af.bits, old, new) { + return loadPkgFlags(old) + } + } +} + +// has reports whether all of the flags in cond are set in af. +func (af *atomicLoadPkgFlags) has(cond loadPkgFlags) bool { + return loadPkgFlags(atomic.LoadInt32(&af.bits))&cond == cond +} + +// isTest reports whether pkg is a test of another package. +func (pkg *loadPkg) isTest() bool { + return pkg.testOf != nil } var errMissing = errors.New("cannot find package") -// load attempts to load the build graph needed to process a set of root packages. -// The set of root packages is defined by the addRoots function, -// which must call add(path) with the import path of each root package. -func (ld *loader) load(roots func() []string) { +// loadFromRoots attempts to load the build graph needed to process a set of +// root packages and their dependencies. +// +// The set of root packages is returned by the params.listRoots function, and +// expanded to the full set of packages by tracing imports (and possibly tests) +// as needed. +func loadFromRoots(params loaderParams) *loader { + ld := &loader{ + loaderParams: params, + work: par.NewQueue(runtime.GOMAXPROCS(0)), + } + var err error - reqs := Reqs() + reqs := &mvsReqs{buildList: buildList} buildList, err = mvs.BuildList(Target, reqs) if err != nil { base.Fatalf("go: %v", err) } - added := make(map[string]bool) + addedModuleFor := make(map[string]bool) for { ld.reset() - if roots != nil { - // Note: the returned roots can change on each iteration, - // since the expansion of package patterns depends on the - // build list we're using. - for _, path := range roots() { - ld.work.Add(ld.pkg(path, true)) + + // Load the root packages and their imports. + // Note: the returned roots can change on each iteration, + // since the expansion of package patterns depends on the + // build list we're using. + inRoots := map[*loadPkg]bool{} + for _, path := range ld.listRoots() { + root := ld.pkg(path, pkgIsRoot) + if !inRoots[root] { + ld.roots = append(ld.roots, root) + inRoots[root] = true } } - ld.work.Do(10, ld.doPkg) + + // ld.pkg adds imported packages to the work queue and calls applyPkgFlags, + // which adds tests (and test dependencies) as needed. + // + // When all of the work in the queue has completed, we'll know that the + // transitive closure of dependencies has been loaded. + <-ld.work.Idle() + ld.buildStacks() - numAdded := 0 - haveMod := make(map[module.Version]bool) - for _, m := range buildList { - haveMod[m] = true - } - modAddedBy := make(map[module.Version]*loadPkg) - for _, pkg := range ld.pkgs { - if err, ok := pkg.err.(*ImportMissingError); ok && err.Module.Path != "" { - if err.newMissingVersion != "" { - base.Fatalf("go: %s: package provided by %s at latest version %s but not at required version %s", pkg.stackText(), err.Module.Path, err.Module.Version, err.newMissingVersion) - } - fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version) - if added[pkg.path] { - base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) - } - added[pkg.path] = true - numAdded++ - if !haveMod[err.Module] { - haveMod[err.Module] = true - modAddedBy[err.Module] = pkg - buildList = append(buildList, err.Module) - } - continue - } - // Leave other errors for Import or load.Packages to report. + + if !ld.ResolveMissingImports || (!HasModRoot() && !allowMissingModuleImports) { + // We've loaded as much as we can without resolving missing imports. + break } - base.ExitIfErrors() - if numAdded == 0 { + modAddedBy := ld.resolveMissingImports(addedModuleFor) + if len(modAddedBy) == 0 { break } // Recompute buildList with all our additions. - reqs = Reqs() + reqs = &mvsReqs{buildList: buildList} buildList, err = mvs.BuildList(Target, reqs) if err != nil { // If an error was found in a newly added module, report the package @@ -753,92 +870,280 @@ func (ld *loader) load(roots func() []string) { } } - // Mix in direct markings (really, lack of indirect markings) - // from go.mod, unless we scanned the whole module - // and can therefore be sure we know better than go.mod. - if !ld.isALL && modFile != nil { + // If we didn't scan all of the imports from the main module, or didn't use + // imports.AnyTags, then we didn't necessarily load every package that + // contributes “direct” imports — so we can't safely mark existing + // dependencies as indirect-only. + // Conservatively mark those dependencies as direct. + if modFile != nil && (!ld.allPatternIsRoot || !reflect.DeepEqual(ld.Tags, imports.AnyTags())) { for _, r := range modFile.Require { if !r.Indirect { ld.direct[r.Mod.Path] = true } } } + + return ld } -// pkg returns the *loadPkg for path, creating and queuing it if needed. -// If the package should be tested, its test is created but not queued -// (the test is queued after processing pkg). -// If isRoot is true, the pkg is being queued as one of the roots of the work graph. -func (ld *loader) pkg(path string, isRoot bool) *loadPkg { - return ld.pkgCache.Do(path, func() interface{} { - pkg := &loadPkg{ - path: path, +// resolveMissingImports adds module dependencies to the global build list +// in order to resolve missing packages from pkgs. +// +// The newly-resolved packages are added to the addedModuleFor map, and +// resolveMissingImports returns a map from each newly-added module version to +// the first package for which that module was added. +func (ld *loader) resolveMissingImports(addedModuleFor map[string]bool) (modAddedBy map[module.Version]*loadPkg) { + var needPkgs []*loadPkg + for _, pkg := range ld.pkgs { + if pkg.err == nil { + continue } - if ld.testRoots && isRoot || ld.testAll { - test := &loadPkg{ - path: path, - testOf: pkg, - } - pkg.test = test + if pkg.isTest() { + // If we are missing a test, we are also missing its non-test version, and + // we should only add the missing import once. + continue + } + if !errors.As(pkg.err, new(*ImportMissingError)) { + // Leave other errors for Import or load.Packages to report. + continue } - if isRoot { - ld.roots = append(ld.roots, pkg) + + needPkgs = append(needPkgs, pkg) + + pkg := pkg + ld.work.Add(func() { + pkg.mod, pkg.err = queryImport(context.TODO(), pkg.path) + }) + } + <-ld.work.Idle() + + modAddedBy = map[module.Version]*loadPkg{} + for _, pkg := range needPkgs { + if pkg.err != nil { + continue + } + + fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, pkg.mod.Path, pkg.mod.Version) + if addedModuleFor[pkg.path] { + // TODO(bcmills): This should only be an error if pkg.mod is the same + // version we already tried to add previously. + base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) + } + if modAddedBy[pkg.mod] == nil { + modAddedBy[pkg.mod] = pkg + buildList = append(buildList, pkg.mod) + } + } + + return modAddedBy +} + +// pkg locates the *loadPkg for path, creating and queuing it for loading if +// needed, and updates its state to reflect the given flags. +// +// The imports of the returned *loadPkg will be loaded asynchronously in the +// ld.work queue, and its test (if requested) will also be populated once +// imports have been resolved. When ld.work goes idle, all transitive imports of +// the requested package (and its test, if requested) will have been loaded. +func (ld *loader) pkg(path string, flags loadPkgFlags) *loadPkg { + if flags.has(pkgImportsLoaded) { + panic("internal error: (*loader).pkg called with pkgImportsLoaded flag set") + } + + pkg := ld.pkgCache.Do(path, func() interface{} { + pkg := &loadPkg{ + path: path, } - ld.work.Add(pkg) + ld.applyPkgFlags(pkg, flags) + + ld.work.Add(func() { ld.load(pkg) }) return pkg }).(*loadPkg) + + ld.applyPkgFlags(pkg, flags) + return pkg } -// doPkg processes a package on the work queue. -func (ld *loader) doPkg(item interface{}) { - // TODO: what about replacements? - pkg := item.(*loadPkg) - var imports []string - if pkg.testOf != nil { - pkg.dir = pkg.testOf.dir - pkg.mod = pkg.testOf.mod - imports = pkg.testOf.testImports - } else { - if strings.Contains(pkg.path, "@") { - // Leave for error during load. - return +// applyPkgFlags updates pkg.flags to set the given flags and propagate the +// (transitive) effects of those flags, possibly loading or enqueueing further +// packages as a result. +func (ld *loader) applyPkgFlags(pkg *loadPkg, flags loadPkgFlags) { + if flags == 0 { + return + } + + if flags.has(pkgInAll) && ld.allPatternIsRoot && !pkg.isTest() { + // This package matches a root pattern by virtue of being in "all". + flags |= pkgIsRoot + } + + old := pkg.flags.update(flags) + new := old | flags + if new == old || !new.has(pkgImportsLoaded) { + // We either didn't change the state of pkg, or we don't know anything about + // its dependencies yet. Either way, we can't usefully load its test or + // update its dependencies. + return + } + + if !pkg.isTest() { + // Check whether we should add (or update the flags for) a test for pkg. + // ld.pkgTest is idempotent and extra invocations are inexpensive, + // so it's ok if we call it more than is strictly necessary. + wantTest := false + switch { + case ld.allPatternIsRoot && pkg.mod == Target: + // We are loading the "all" pattern, which includes packages imported by + // tests in the main module. This package is in the main module, so we + // need to identify the imports of its test even if LoadTests is not set. + // + // (We will filter out the extra tests explicitly in computePatternAll.) + wantTest = true + + case ld.allPatternIsRoot && ld.allClosesOverTests && new.has(pkgInAll): + // This variant of the "all" pattern includes imports of tests of every + // package that is itself in "all", and pkg is in "all", so its test is + // also in "all" (as above). + wantTest = true + + case ld.LoadTests && new.has(pkgIsRoot): + // LoadTest explicitly requests tests of “the root packages”. + wantTest = true } - if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) { - // Leave for error during load. - // (Module mode does not allow local imports.) - return + + if wantTest { + var testFlags loadPkgFlags + if pkg.mod == Target || (ld.allClosesOverTests && new.has(pkgInAll)) { + // Tests of packages in the main module are in "all", in the sense that + // they cause the packages they import to also be in "all". So are tests + // of packages in "all" if "all" closes over test dependencies. + testFlags |= pkgInAll + } + ld.pkgTest(pkg, testFlags) } + } - // TODO(matloob): Handle TODO context. This needs to be threaded through Do. - pkg.mod, pkg.dir, pkg.err = Import(context.TODO(), pkg.path) - if pkg.dir == "" { - return + if new.has(pkgInAll) && !old.has(pkgInAll|pkgImportsLoaded) { + // We have just marked pkg with pkgInAll, or we have just loaded its + // imports, or both. Now is the time to propagate pkgInAll to the imports. + for _, dep := range pkg.imports { + ld.applyPkgFlags(dep, pkgInAll) } - var testImports []string - var err error - imports, testImports, err = scanDir(pkg.dir, ld.tags) - if err != nil { - pkg.err = err - return + } +} + +// load loads an individual package. +func (ld *loader) load(pkg *loadPkg) { + if strings.Contains(pkg.path, "@") { + // Leave for error during load. + return + } + if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) { + // Leave for error during load. + // (Module mode does not allow local imports.) + return + } + + if search.IsMetaPackage(pkg.path) { + pkg.err = &invalidImportError{ + importPath: pkg.path, + err: fmt.Errorf("%q is not an importable package; see 'go help packages'", pkg.path), } - if pkg.test != nil { - pkg.testImports = testImports + return + } + + pkg.mod, pkg.dir, pkg.err = importFromBuildList(context.TODO(), pkg.path, buildList) + if pkg.dir == "" { + return + } + if pkg.mod == Target { + // Go ahead and mark pkg as in "all". This provides the invariant that a + // package that is *only* imported by other packages in "all" is always + // marked as such before loading its imports. + // + // We don't actually rely on that invariant at the moment, but it may + // improve efficiency somewhat and makes the behavior a bit easier to reason + // about (by reducing churn on the flag bits of dependencies), and costs + // essentially nothing (these atomic flag ops are essentially free compared + // to scanning source code for imports). + ld.applyPkgFlags(pkg, pkgInAll) + } + if ld.AllowPackage != nil { + if err := ld.AllowPackage(context.TODO(), pkg.path, pkg.mod); err != nil { + pkg.err = err } } - inStd := (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "") + imports, testImports, err := scanDir(pkg.dir, ld.Tags) + if err != nil { + pkg.err = err + return + } + + pkg.inStd = (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "") + + pkg.imports = make([]*loadPkg, 0, len(imports)) + var importFlags loadPkgFlags + if pkg.flags.has(pkgInAll) { + importFlags = pkgInAll + } for _, path := range imports { - if inStd { + if pkg.inStd { + // Imports from packages in "std" and "cmd" should resolve using + // GOROOT/src/vendor even when "std" is not the main module. path = ld.stdVendor(pkg.path, path) } - pkg.imports = append(pkg.imports, ld.pkg(path, false)) + pkg.imports = append(pkg.imports, ld.pkg(path, importFlags)) } + pkg.testImports = testImports - // Now that pkg.dir, pkg.mod, pkg.testImports are set, we can queue pkg.test. - // TODO: All that's left is creating new imports. Why not just do it now? - if pkg.test != nil { - ld.work.Add(pkg.test) + ld.applyPkgFlags(pkg, pkgImportsLoaded) +} + +// pkgTest locates the test of pkg, creating it if needed, and updates its state +// to reflect the given flags. +// +// pkgTest requires that the imports of pkg have already been loaded (flagged +// with pkgImportsLoaded). +func (ld *loader) pkgTest(pkg *loadPkg, testFlags loadPkgFlags) *loadPkg { + if pkg.isTest() { + panic("pkgTest called on a test package") + } + + createdTest := false + pkg.testOnce.Do(func() { + pkg.test = &loadPkg{ + path: pkg.path, + testOf: pkg, + mod: pkg.mod, + dir: pkg.dir, + err: pkg.err, + inStd: pkg.inStd, + } + ld.applyPkgFlags(pkg.test, testFlags) + createdTest = true + }) + + test := pkg.test + if createdTest { + test.imports = make([]*loadPkg, 0, len(pkg.testImports)) + var importFlags loadPkgFlags + if test.flags.has(pkgInAll) { + importFlags = pkgInAll + } + for _, path := range pkg.testImports { + if pkg.inStd { + path = ld.stdVendor(test.path, path) + } + test.imports = append(test.imports, ld.pkg(path, importFlags)) + } + pkg.testImports = nil + ld.applyPkgFlags(test, pkgImportsLoaded) + } else { + ld.applyPkgFlags(test, testFlags) } + + return test } // stdVendor returns the canonical import path for the package with the given @@ -849,13 +1154,25 @@ func (ld *loader) stdVendor(parentPath, path string) string { } if str.HasPathPrefix(parentPath, "cmd") { - if ld.forceStdVendor || Target.Path != "cmd" { + if Target.Path != "cmd" { vendorPath := pathpkg.Join("cmd", "vendor", path) if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil { return vendorPath } } - } else if ld.forceStdVendor || Target.Path != "std" { + } else if Target.Path != "std" || str.HasPathPrefix(parentPath, "vendor") { + // If we are outside of the 'std' module, resolve imports from within 'std' + // to the vendor directory. + // + // Do the same for importers beginning with the prefix 'vendor/' even if we + // are *inside* of the 'std' module: the 'vendor/' packages that resolve + // globally from GOROOT/src/vendor (and are listed as part of 'go list std') + // are distinct from the real module dependencies, and cannot import + // internal packages from the real module. + // + // (Note that although the 'vendor/' packages match the 'std' *package* + // pattern, they are not part of the std *module*, and do not affect + // 'go mod tidy' and similar module commands when working within std.) vendorPath := pathpkg.Join("vendor", path) if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil { return vendorPath @@ -868,30 +1185,13 @@ func (ld *loader) stdVendor(parentPath, path string) string { // computePatternAll returns the list of packages matching pattern "all", // starting with a list of the import paths for the packages in the main module. -func (ld *loader) computePatternAll(paths []string) []string { - seen := make(map[*loadPkg]bool) - var all []string - var walk func(*loadPkg) - walk = func(pkg *loadPkg) { - if seen[pkg] { - return - } - seen[pkg] = true - if pkg.testOf == nil { +func (ld *loader) computePatternAll() (all []string) { + for _, pkg := range ld.pkgs { + if pkg.flags.has(pkgInAll) && !pkg.isTest() { all = append(all, pkg.path) } - for _, p := range pkg.imports { - walk(p) - } - if p := pkg.test; p != nil { - walk(p) - } - } - for _, path := range paths { - walk(ld.pkg(path, false)) } sort.Strings(all) - return all } @@ -1013,7 +1313,7 @@ func (pkg *loadPkg) why() string { // Why returns the "go mod why" output stanza for the given package, // without the leading # comment. -// The package graph must have been loaded already, usually by LoadALL. +// The package graph must have been loaded already, usually by LoadPackages. // If there is no reason for the package to be in the current build, // Why returns an empty string. func Why(path string) string { diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go index a45c4a63be..eb05e9f9c9 100644 --- a/src/cmd/go/internal/modload/modfile.go +++ b/src/cmd/go/internal/modload/modfile.go @@ -25,18 +25,25 @@ import ( "golang.org/x/mod/semver" ) +// narrowAllVersionV is the Go version (plus leading "v") at which the +// module-module "all" pattern no longer closes over the dependencies of +// tests outside of the main module. +const narrowAllVersionV = "v1.16" +const go116EnableNarrowAll = true + var modFile *modfile.File // A modFileIndex is an index of data corresponding to a modFile // at a specific point in time. type modFileIndex struct { - data []byte - dataNeedsFix bool // true if fixVersion applied a change while parsing data - module module.Version - goVersionV string // GoVersion with "v" prefix - require map[module.Version]requireMeta - replace map[module.Version]module.Version - exclude map[module.Version]bool + data []byte + dataNeedsFix bool // true if fixVersion applied a change while parsing data + module module.Version + goVersionV string // GoVersion with "v" prefix + require map[module.Version]requireMeta + replace map[module.Version]module.Version + highestReplaced map[string]string // highest replaced version of each module path; empty string for wildcard-only replacements + exclude map[module.Version]bool } // index is the index of the go.mod file as of when it was last read or written. @@ -53,7 +60,7 @@ func CheckAllowed(ctx context.Context, m module.Version) error { if err := CheckExclusions(ctx, m); err != nil { return err } - if err := checkRetractions(ctx, m); err != nil { + if err := CheckRetractions(ctx, m); err != nil { return err } return nil @@ -79,9 +86,9 @@ type excludedError struct{} func (e *excludedError) Error() string { return "excluded by go.mod" } func (e *excludedError) Is(err error) bool { return err == ErrDisallowed } -// checkRetractions returns an error if module m has been retracted by +// CheckRetractions returns an error if module m has been retracted by // its author. -func checkRetractions(ctx context.Context, m module.Version) error { +func CheckRetractions(ctx context.Context, m module.Version) error { if m.Version == "" { // Main module, standard library, or file replacement module. // Cannot be retracted. @@ -108,29 +115,44 @@ func checkRetractions(ctx context.Context, m module.Version) error { // Find the latest version of the module. // Ignore exclusions from the main module's go.mod. - // We may need to account for the current version: for example, - // v2.0.0+incompatible is not "latest" if v1.0.0 is current. - rev, err := Query(ctx, path, "latest", findCurrentVersion(path), nil) + const ignoreSelected = "" + var allowAll AllowedFunc + rev, err := Query(ctx, path, "latest", ignoreSelected, allowAll) if err != nil { - return &entry{err: err} + return &entry{nil, err} } // Load go.mod for that version. // If the version is replaced, we'll load retractions from the replacement. + // // If there's an error loading the go.mod, we'll return it here. // These errors should generally be ignored by callers of checkRetractions, // since they happen frequently when we're offline. These errors are not // equivalent to ErrDisallowed, so they may be distinguished from // retraction errors. - summary, err := goModSummary(module.Version{Path: path, Version: rev.Version}) + // + // We load the raw file here: the go.mod file may have a different module + // path that we expect if the module or its repository was renamed. + // We still want to apply retractions to other aliases of the module. + rm := module.Version{Path: path, Version: rev.Version} + if repl := Replacement(rm); repl.Path != "" { + rm = repl + } + summary, err := rawGoModSummary(rm) if err != nil { - return &entry{err: err} + return &entry{nil, err} } - return &entry{retract: summary.retract} + return &entry{summary.retract, nil} }).(*entry) - if e.err != nil { - return fmt.Errorf("loading module retractions: %v", e.err) + if err := e.err; err != nil { + // Attribute the error to the version being checked, not the version from + // which the retractions were to be loaded. + var mErr *module.ModuleError + if errors.As(err, &mErr) { + err = mErr.Err + } + return &retractionLoadingError{m: m, err: err} } var rationale []string @@ -144,31 +166,44 @@ func checkRetractions(ctx context.Context, m module.Version) error { } } if isRetracted { - return &retractedError{rationale: rationale} + return module.VersionError(m, &ModuleRetractedError{Rationale: rationale}) } return nil } var retractCache par.Cache -type retractedError struct { - rationale []string +type ModuleRetractedError struct { + Rationale []string } -func (e *retractedError) Error() string { +func (e *ModuleRetractedError) Error() string { msg := "retracted by module author" - if len(e.rationale) > 0 { + if len(e.Rationale) > 0 { // This is meant to be a short error printed on a terminal, so just // print the first rationale. - msg += ": " + ShortRetractionRationale(e.rationale[0]) + msg += ": " + ShortRetractionRationale(e.Rationale[0]) } return msg } -func (e *retractedError) Is(err error) bool { +func (e *ModuleRetractedError) Is(err error) bool { return err == ErrDisallowed } +type retractionLoadingError struct { + m module.Version + err error +} + +func (e *retractionLoadingError) Error() string { + return fmt.Sprintf("loading module retractions for %v: %v", e.m, e.err) +} + +func (e *retractionLoadingError) Unwrap() error { + return e.err +} + // ShortRetractionRationale returns a retraction rationale string that is safe // to print in a terminal. It returns hard-coded strings if the rationale // is empty, too long, or contains non-printable characters. @@ -241,6 +276,14 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd i.replace[r.Old] = r.New } + i.highestReplaced = make(map[string]string) + for _, r := range modFile.Replace { + v, ok := i.highestReplaced[r.Old.Path] + if !ok || semver.Compare(r.Old.Version, v) > 0 { + i.highestReplaced[r.Old.Path] = r.Old.Version + } + } + i.exclude = make(map[module.Version]bool, len(modFile.Exclude)) for _, x := range modFile.Exclude { i.exclude[x.Mod] = true @@ -249,6 +292,23 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd return i } +// allPatternClosesOverTests reports whether the "all" pattern includes +// dependencies of tests outside the main module (as in Go 1.11–1.15). +// (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages +// transitively *imported by* the packages and tests in the main module.) +func (i *modFileIndex) allPatternClosesOverTests() bool { + if !go116EnableNarrowAll { + return true + } + if i != nil && semver.Compare(i.goVersionV, narrowAllVersionV) < 0 { + // The module explicitly predates the change in "all" for lazy loading, so + // continue to use the older interpretation. (If i == nil, we not in any + // module at all and should use the latest semantics.) + return true + } + return false +} + // modFileIsDirty reports whether the go.mod file differs meaningfully // from what was indexed. // If modFile has been changed (even cosmetically) since it was first read, @@ -347,8 +407,11 @@ type retraction struct { // taking into account any replacements for m, exclusions of its dependencies, // and/or vendoring. // -// goModSummary cannot be used on the Target module, as its requirements -// may change. +// m must be a version in the module graph, reachable from the Target module. +// In readonly mode, the go.sum file must contain an entry for m's go.mod file +// (or its replacement). goModSummary must not be called for the Target module +// itself, as its requirements may change. Use rawGoModSummary for other +// module versions. // // The caller must not modify the returned summary. func goModSummary(m module.Version) (*modFileSummary, error) { @@ -356,87 +419,97 @@ func goModSummary(m module.Version) (*modFileSummary, error) { panic("internal error: goModSummary called on the Target module") } - type cached struct { - summary *modFileSummary - err error - } - c := goModSummaryCache.Do(m, func() interface{} { - if cfg.BuildMod == "vendor" { - summary := &modFileSummary{ - module: module.Version{Path: m.Path}, - } - if vendorVersion[m.Path] != m.Version { - // This module is not vendored, so packages cannot be loaded from it and - // it cannot be relevant to the build. - return cached{summary, nil} - } + if cfg.BuildMod == "vendor" { + summary := &modFileSummary{ + module: module.Version{Path: m.Path}, + } + if vendorVersion[m.Path] != m.Version { + // This module is not vendored, so packages cannot be loaded from it and + // it cannot be relevant to the build. + return summary, nil + } - // For every module other than the target, - // return the full list of modules from modules.txt. - readVendorList() + // For every module other than the target, + // return the full list of modules from modules.txt. + readVendorList() - // TODO(#36876): Load the "go" version from vendor/modules.txt and store it - // in rawGoVersion with the appropriate key. + // TODO(#36876): Load the "go" version from vendor/modules.txt and store it + // in rawGoVersion with the appropriate key. - // We don't know what versions the vendored module actually relies on, - // so assume that it requires everything. - summary.require = vendorList - return cached{summary, nil} - } + // We don't know what versions the vendored module actually relies on, + // so assume that it requires everything. + summary.require = vendorList + return summary, nil + } - actual := Replacement(m) - if actual.Path == "" { - actual = m - } - summary, err := rawGoModSummary(actual) - if err != nil { - return cached{nil, err} + actual := Replacement(m) + if actual.Path == "" { + actual = m + } + if cfg.BuildMod == "readonly" && actual.Version != "" { + key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"} + if !modfetch.HaveSum(key) { + suggestion := fmt.Sprintf("; try 'go mod download %s' to add it", m.Path) + return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion}) } + } + summary, err := rawGoModSummary(actual) + if err != nil { + return nil, err + } - if actual.Version == "" { - // The actual module is a filesystem-local replacement, for which we have - // unfortunately not enforced any sort of invariants about module lines or - // matching module paths. Anything goes. - // - // TODO(bcmills): Remove this special-case, update tests, and add a - // release note. - } else { - if summary.module.Path == "" { - return cached{nil, module.VersionError(actual, errors.New("parsing go.mod: missing module line"))} - } + if actual.Version == "" { + // The actual module is a filesystem-local replacement, for which we have + // unfortunately not enforced any sort of invariants about module lines or + // matching module paths. Anything goes. + // + // TODO(bcmills): Remove this special-case, update tests, and add a + // release note. + } else { + if summary.module.Path == "" { + return nil, module.VersionError(actual, errors.New("parsing go.mod: missing module line")) + } - // In theory we should only allow mpath to be unequal to m.Path here if the - // version that we fetched lacks an explicit go.mod file: if the go.mod file - // is explicit, then it should match exactly (to ensure that imports of other - // packages within the module are interpreted correctly). Unfortunately, we - // can't determine that information from the module proxy protocol: we'll have - // to leave that validation for when we load actual packages from within the - // module. - if mpath := summary.module.Path; mpath != m.Path && mpath != actual.Path { - return cached{nil, module.VersionError(actual, fmt.Errorf(`parsing go.mod: + // In theory we should only allow mpath to be unequal to m.Path here if the + // version that we fetched lacks an explicit go.mod file: if the go.mod file + // is explicit, then it should match exactly (to ensure that imports of other + // packages within the module are interpreted correctly). Unfortunately, we + // can't determine that information from the module proxy protocol: we'll have + // to leave that validation for when we load actual packages from within the + // module. + if mpath := summary.module.Path; mpath != m.Path && mpath != actual.Path { + return nil, module.VersionError(actual, fmt.Errorf(`parsing go.mod: module declares its path as: %s - but was required as: %s`, mpath, m.Path))} - } + but was required as: %s`, mpath, m.Path)) } + } - if index != nil && len(index.exclude) > 0 { - // Drop any requirements on excluded versions. - nonExcluded := summary.require[:0] + if index != nil && len(index.exclude) > 0 { + // Drop any requirements on excluded versions. + // Don't modify the cached summary though, since we might need the raw + // summary separately. + haveExcludedReqs := false + for _, r := range summary.require { + if index.exclude[r] { + haveExcludedReqs = true + break + } + } + if haveExcludedReqs { + s := new(modFileSummary) + *s = *summary + s.require = make([]module.Version, 0, len(summary.require)) for _, r := range summary.require { if !index.exclude[r] { - nonExcluded = append(nonExcluded, r) + s.require = append(s.require, r) } } - summary.require = nonExcluded + summary = s } - return cached{summary, nil} - }).(cached) - - return c.summary, c.err + } + return summary, nil } -var goModSummaryCache par.Cache // module.Version → goModSummary result - // rawGoModSummary returns a new summary of the go.mod file for module m, // ignoring all replacements that may apply to m and excludes that may apply to // its dependencies. @@ -447,62 +520,72 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) { panic("internal error: rawGoModSummary called on the Target module") } - summary := new(modFileSummary) - var f *modfile.File - if m.Version == "" { - // m is a replacement module with only a file path. - dir := m.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - gomod := filepath.Join(dir, "go.mod") + type cached struct { + summary *modFileSummary + err error + } + c := rawGoModSummaryCache.Do(m, func() interface{} { + summary := new(modFileSummary) + var f *modfile.File + if m.Version == "" { + // m is a replacement module with only a file path. + dir := m.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) + } + gomod := filepath.Join(dir, "go.mod") - data, err := lockedfile.Read(gomod) - if err != nil { - return nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err)) - } - f, err = modfile.ParseLax(gomod, data, nil) - if err != nil { - return nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)) - } - } else { - if !semver.IsValid(m.Version) { - // Disallow the broader queries supported by fetch.Lookup. - base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) + data, err := lockedfile.Read(gomod) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))} + } + f, err = modfile.ParseLax(gomod, data, nil) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))} + } + } else { + if !semver.IsValid(m.Version) { + // Disallow the broader queries supported by fetch.Lookup. + base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) + } + + data, err := modfetch.GoMod(m.Path, m.Version) + if err != nil { + return cached{nil, err} + } + f, err = modfile.ParseLax("go.mod", data, nil) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))} + } } - data, err := modfetch.GoMod(m.Path, m.Version) - if err != nil { - return nil, err + if f.Module != nil { + summary.module = f.Module.Mod } - f, err = modfile.ParseLax("go.mod", data, nil) - if err != nil { - return nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err)) + if f.Go != nil && f.Go.Version != "" { + rawGoVersion.LoadOrStore(m, f.Go.Version) + summary.goVersionV = "v" + f.Go.Version } - } - - if f.Module != nil { - summary.module = f.Module.Mod - } - if f.Go != nil && f.Go.Version != "" { - rawGoVersion.LoadOrStore(m, f.Go.Version) - summary.goVersionV = "v" + f.Go.Version - } - if len(f.Require) > 0 { - summary.require = make([]module.Version, 0, len(f.Require)) - for _, req := range f.Require { - summary.require = append(summary.require, req.Mod) + if len(f.Require) > 0 { + summary.require = make([]module.Version, 0, len(f.Require)) + for _, req := range f.Require { + summary.require = append(summary.require, req.Mod) + } } - } - if len(f.Retract) > 0 { - summary.retract = make([]retraction, 0, len(f.Retract)) - for _, ret := range f.Retract { - summary.retract = append(summary.retract, retraction{ - VersionInterval: ret.VersionInterval, - Rationale: ret.Rationale, - }) + if len(f.Retract) > 0 { + summary.retract = make([]retraction, 0, len(f.Retract)) + for _, ret := range f.Retract { + summary.retract = append(summary.retract, retraction{ + VersionInterval: ret.VersionInterval, + Rationale: ret.Rationale, + }) + } } - } - return summary, nil + return cached{summary, nil} + }).(cached) + + return c.summary, c.err } + +var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result diff --git a/src/cmd/go/internal/modload/mvs.go b/src/cmd/go/internal/modload/mvs.go index 24856260d4..167d6819b0 100644 --- a/src/cmd/go/internal/modload/mvs.go +++ b/src/cmd/go/internal/modload/mvs.go @@ -7,13 +7,10 @@ package modload import ( "context" "errors" - "fmt" "os" - "path/filepath" "sort" "cmd/go/internal/modfetch" - "cmd/go/internal/mvs" "golang.org/x/mod/module" "golang.org/x/mod/semver" @@ -25,16 +22,6 @@ type mvsReqs struct { buildList []module.Version } -// Reqs returns the current module requirement graph. -// Future calls to SetBuildList do not affect the operation -// of the returned Reqs. -func Reqs() mvs.Reqs { - r := &mvsReqs{ - buildList: buildList, - } - return r -} - func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { if mod == Target { // Use the build list as it existed when r was constructed, not the current @@ -60,7 +47,7 @@ func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { // be chosen over other versions of the same module in the module dependency // graph. func (*mvsReqs) Max(v1, v2 string) string { - if v1 != "" && semver.Compare(v1, v2) == -1 { + if v1 != "" && (v2 == "" || semver.Compare(v1, v2) == -1) { return v2 } return v1 @@ -77,7 +64,7 @@ func versions(ctx context.Context, path string, allowed AllowedFunc) ([]string, // so there's no need for us to add extra caching here. var versions []string err := modfetch.TryProxies(func(proxy string) error { - repo, err := modfetch.Lookup(proxy, path) + repo, err := lookupRepo(proxy, path) if err != nil { return err } @@ -101,10 +88,21 @@ func versions(ctx context.Context, path string, allowed AllowedFunc) ([]string, // Previous returns the tagged version of m.Path immediately prior to // m.Version, or version "none" if no prior version is tagged. +// +// Since the version of Target is not found in the version list, +// it has no previous version. func (*mvsReqs) Previous(m module.Version) (module.Version, error) { // TODO(golang.org/issue/38714): thread tracing context through MVS. + + if m == Target { + return module.Version{Path: m.Path, Version: "none"}, nil + } + list, err := versions(context.TODO(), m.Path, CheckAllowed) if err != nil { + if errors.Is(err, os.ErrNotExist) { + return module.Version{Path: m.Path, Version: "none"}, nil + } return module.Version{}, err } i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 }) @@ -129,42 +127,3 @@ func (*mvsReqs) next(m module.Version) (module.Version, error) { } return module.Version{Path: m.Path, Version: "none"}, nil } - -// fetch downloads the given module (or its replacement) -// and returns its location. -// -// The isLocal return value reports whether the replacement, -// if any, is local to the filesystem. -func fetch(ctx context.Context, mod module.Version) (dir string, isLocal bool, err error) { - if mod == Target { - return ModRoot(), true, nil - } - if r := Replacement(mod); r.Path != "" { - if r.Version == "" { - dir = r.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - // Ensure that the replacement directory actually exists: - // dirInModule does not report errors for missing modules, - // so if we don't report the error now, later failures will be - // very mysterious. - if _, err := os.Stat(dir); err != nil { - if os.IsNotExist(err) { - // Semantically the module version itself “exists” — we just don't - // have its source code. Remove the equivalence to os.ErrNotExist, - // and make the message more concise while we're at it. - err = fmt.Errorf("replacement directory %s does not exist", r.Path) - } else { - err = fmt.Errorf("replacement directory %s: %w", r.Path, err) - } - return dir, true, module.VersionError(mod, err) - } - return dir, true, nil - } - mod = r - } - - dir, err = modfetch.Download(ctx, mod) - return dir, false, err -} diff --git a/src/cmd/go/internal/modload/mvs_test.go b/src/cmd/go/internal/modload/mvs_test.go new file mode 100644 index 0000000000..50e93c381f --- /dev/null +++ b/src/cmd/go/internal/modload/mvs_test.go @@ -0,0 +1,31 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modload + +import ( + "testing" +) + +func TestReqsMax(t *testing.T) { + type testCase struct { + a, b, want string + } + reqs := new(mvsReqs) + for _, tc := range []testCase{ + {a: "v0.1.0", b: "v0.2.0", want: "v0.2.0"}, + {a: "v0.2.0", b: "v0.1.0", want: "v0.2.0"}, + {a: "", b: "v0.1.0", want: ""}, // "" is Target.Version + {a: "v0.1.0", b: "", want: ""}, + {a: "none", b: "v0.1.0", want: "v0.1.0"}, + {a: "v0.1.0", b: "none", want: "v0.1.0"}, + {a: "none", b: "", want: ""}, + {a: "", b: "none", want: ""}, + } { + max := reqs.Max(tc.a, tc.b) + if max != tc.want { + t.Errorf("(%T).Max(%q, %q) = %q; want %q", reqs, tc.a, tc.b, max, tc.want) + } + } +} diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go index f67a738677..e35e0fc16e 100644 --- a/src/cmd/go/internal/modload/query.go +++ b/src/cmd/go/internal/modload/query.go @@ -8,17 +8,19 @@ import ( "context" "errors" "fmt" + "io/fs" "os" pathpkg "path" "path/filepath" + "sort" "strings" "sync" + "time" "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/modfetch" "cmd/go/internal/search" - "cmd/go/internal/str" "cmd/go/internal/trace" "golang.org/x/mod/module" @@ -45,8 +47,9 @@ import ( // with non-prereleases preferred over prereleases. // - a repository commit identifier or tag, denoting that commit. // -// current denotes the current version of the module; it may be "" if the -// current version is unknown or should not be considered. If query is +// current denotes the currently-selected version of the module; it may be +// "none" if no version is currently selected, or "" if the currently-selected +// version is unknown or should not be considered. If query is // "upgrade" or "patch", current will be returned if it is a newer // semantic version or a chronologically later pseudo-version than the // version that would otherwise be chosen. This prevents accidental downgrades @@ -96,7 +99,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed ctx, span := trace.StartSpan(ctx, "modload.queryProxy "+path+" "+query) defer span.Done() - if current != "" && !semver.IsValid(current) { + if current != "" && current != "none" && !semver.IsValid(current) { return nil, fmt.Errorf("invalid previous version %q", current) } if cfg.BuildMod == "vendor" { @@ -106,125 +109,42 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed allowed = func(context.Context, module.Version) error { return nil } } - // Parse query to detect parse errors (and possibly handle query) - // before any network I/O. - badVersion := func(v string) (*modfetch.RevInfo, error) { - return nil, fmt.Errorf("invalid semantic version %q in range %q", v, query) - } - matchesMajor := func(v string) bool { - _, pathMajor, ok := module.SplitPathVersion(path) - if !ok { - return false + if path == Target.Path && (query == "upgrade" || query == "patch") { + if err := allowed(ctx, Target); err != nil { + return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err) } - return module.CheckPathMajor(v, pathMajor) == nil + return &modfetch.RevInfo{Version: Target.Version}, nil } - var ( - match = func(m module.Version) bool { return true } - - prefix string - preferOlder bool - mayUseLatest bool - preferIncompatible bool = strings.HasSuffix(current, "+incompatible") - ) - switch { - case query == "latest": - mayUseLatest = true - case query == "upgrade": - mayUseLatest = true - - case query == "patch": - if current == "" { - mayUseLatest = true - } else { - prefix = semver.MajorMinor(current) - match = func(m module.Version) bool { - return matchSemverPrefix(prefix, m.Version) - } - } - - case strings.HasPrefix(query, "<="): - v := query[len("<="):] - if !semver.IsValid(v) { - return badVersion(v) - } - if isSemverPrefix(v) { - // Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). - return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) - } - match = func(m module.Version) bool { - return semver.Compare(m.Version, v) <= 0 - } - if !matchesMajor(v) { - preferIncompatible = true - } - - case strings.HasPrefix(query, "<"): - v := query[len("<"):] - if !semver.IsValid(v) { - return badVersion(v) - } - match = func(m module.Version) bool { - return semver.Compare(m.Version, v) < 0 - } - if !matchesMajor(v) { - preferIncompatible = true - } - - case strings.HasPrefix(query, ">="): - v := query[len(">="):] - if !semver.IsValid(v) { - return badVersion(v) - } - match = func(m module.Version) bool { - return semver.Compare(m.Version, v) >= 0 - } - preferOlder = true - if !matchesMajor(v) { - preferIncompatible = true - } + if path == "std" || path == "cmd" { + return nil, fmt.Errorf("can't query specific version (%q) of standard-library module %q", query, path) + } - case strings.HasPrefix(query, ">"): - v := query[len(">"):] - if !semver.IsValid(v) { - return badVersion(v) - } - if isSemverPrefix(v) { - // Refuse to say whether >v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). - return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) - } - match = func(m module.Version) bool { - return semver.Compare(m.Version, v) > 0 - } - preferOlder = true - if !matchesMajor(v) { - preferIncompatible = true - } + repo, err := lookupRepo(proxy, path) + if err != nil { + return nil, err + } - case semver.IsValid(query) && isSemverPrefix(query): - match = func(m module.Version) bool { - return matchSemverPrefix(query, m.Version) - } - prefix = query + "." - if !matchesMajor(query) { - preferIncompatible = true - } + // Parse query to detect parse errors (and possibly handle query) + // before any network I/O. + qm, err := newQueryMatcher(path, query, current, allowed) + if (err == nil && qm.canStat) || err == errRevQuery { + // Direct lookup of a commit identifier or complete (non-prefix) semantic + // version. - default: - // Direct lookup of semantic version or commit identifier. - // // If the identifier is not a canonical semver tag — including if it's a // semver tag with a +metadata suffix — then modfetch.Stat will populate // info.Version with a suitable pseudo-version. - info, err := modfetch.Stat(proxy, path, query) + info, err := repo.Stat(query) if err != nil { queryErr := err // The full query doesn't correspond to a tag. If it is a semantic version // with a +metadata suffix, see if there is a tag without that suffix: // semantic versioning defines them to be equivalent. - if vers := module.CanonicalVersion(query); vers != "" && vers != query { - info, err = modfetch.Stat(proxy, path, vers) - if !errors.Is(err, os.ErrNotExist) { + canonicalQuery := module.CanonicalVersion(query) + if canonicalQuery != "" && query != canonicalQuery { + info, err = repo.Stat(canonicalQuery) + if err != nil && !errors.Is(err, fs.ErrNotExist) { return info, err } } @@ -236,38 +156,16 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed return nil, err } return info, nil - } - - if path == Target.Path { - if query != "latest" { - return nil, fmt.Errorf("can't query specific version (%q) for the main module (%s)", query, path) - } - if err := allowed(ctx, Target); err != nil { - return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err) - } - return &modfetch.RevInfo{Version: Target.Version}, nil - } - - if str.HasPathPrefix(path, "std") || str.HasPathPrefix(path, "cmd") { - return nil, fmt.Errorf("explicit requirement on standard-library module %s not allowed", path) + } else if err != nil { + return nil, err } // Load versions and execute query. - repo, err := modfetch.Lookup(proxy, path) + versions, err := repo.Versions(qm.prefix) if err != nil { return nil, err } - versions, err := repo.Versions(prefix) - if err != nil { - return nil, err - } - matchAndAllowed := func(ctx context.Context, m module.Version) error { - if !match(m) { - return ErrDisallowed - } - return allowed(ctx, m) - } - releases, prereleases, err := filterVersions(ctx, path, versions, matchAndAllowed, preferIncompatible) + releases, prereleases, err := qm.filterVersions(ctx, versions) if err != nil { return nil, err } @@ -278,11 +176,30 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed return nil, err } - // For "upgrade" and "patch", make sure we don't accidentally downgrade - // from a newer prerelease or from a chronologically newer pseudoversion. - if current != "" && (query == "upgrade" || query == "patch") { + if (query == "upgrade" || query == "patch") && modfetch.IsPseudoVersion(current) && !rev.Time.IsZero() { + // Don't allow "upgrade" or "patch" to move from a pseudo-version + // to a chronologically older version or pseudo-version. + // + // If the current version is a pseudo-version from an untagged branch, it + // may be semantically lower than the "latest" release or the latest + // pseudo-version on the main branch. A user on such a version is unlikely + // to intend to “upgrade” to a version that already existed at that point + // in time. + // + // We do this only if the current version is a pseudo-version: if the + // version is tagged, the author of the dependency module has given us + // explicit information about their intended precedence of this version + // relative to other versions, and we shouldn't contradict that + // information. (For example, v1.0.1 might be a backport of a fix already + // incorporated into v1.1.0, in which case v1.0.1 would be chronologically + // newer but v1.1.0 is still an “upgrade”; or v1.0.2 might be a revert of + // an unsuccessful fix in v1.0.1, in which case the v1.0.2 commit may be + // older than the v1.0.1 commit despite the tag itself being newer.) currentTime, err := modfetch.PseudoVersionTime(current) - if semver.Compare(rev.Version, current) < 0 || (err == nil && rev.Time.Before(currentTime)) { + if err == nil && rev.Time.Before(currentTime) { + if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) { + return nil, err + } return repo.Stat(current) } } @@ -290,7 +207,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed return rev, nil } - if preferOlder { + if qm.preferLower { if len(releases) > 0 { return lookup(releases[0]) } @@ -306,18 +223,23 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed } } - if mayUseLatest { - // Special case for "latest": if no tags match, use latest commit in repo - // if it is allowed. + if qm.mayUseLatest { latest, err := repo.Latest() if err == nil { - m := module.Version{Path: path, Version: latest.Version} - if err := allowed(ctx, m); !errors.Is(err, ErrDisallowed) { + if qm.allowsVersion(ctx, latest.Version) { return lookup(latest.Version) } - } else if !errors.Is(err, os.ErrNotExist) { + } else if !errors.Is(err, fs.ErrNotExist) { + return nil, err + } + } + + if (query == "upgrade" || query == "patch") && current != "" && current != "none" { + // "upgrade" and "patch" may stay on the current version if allowed. + if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) { return nil, err } + return lookup(current) } return nil, &NoMatchingVersionError{query: query, current: current} @@ -357,10 +279,154 @@ func isSemverPrefix(v string) bool { return true } -// matchSemverPrefix reports whether the shortened semantic version p -// matches the full-width (non-shortened) semantic version v. -func matchSemverPrefix(p, v string) bool { - return len(v) > len(p) && v[len(p)] == '.' && v[:len(p)] == p && semver.Prerelease(v) == "" +type queryMatcher struct { + path string + prefix string + filter func(version string) bool + allowed AllowedFunc + canStat bool // if true, the query can be resolved by repo.Stat + preferLower bool // if true, choose the lowest matching version + mayUseLatest bool + preferIncompatible bool +} + +var errRevQuery = errors.New("query refers to a non-semver revision") + +// newQueryMatcher returns a new queryMatcher that matches the versions +// specified by the given query on the module with the given path. +// +// If the query can only be resolved by statting a non-SemVer revision, +// newQueryMatcher returns errRevQuery. +func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*queryMatcher, error) { + badVersion := func(v string) (*queryMatcher, error) { + return nil, fmt.Errorf("invalid semantic version %q in range %q", v, query) + } + + matchesMajor := func(v string) bool { + _, pathMajor, ok := module.SplitPathVersion(path) + if !ok { + return false + } + return module.CheckPathMajor(v, pathMajor) == nil + } + + qm := &queryMatcher{ + path: path, + allowed: allowed, + preferIncompatible: strings.HasSuffix(current, "+incompatible"), + } + + switch { + case query == "latest": + qm.mayUseLatest = true + + case query == "upgrade": + if current == "" || current == "none" { + qm.mayUseLatest = true + } else { + qm.mayUseLatest = modfetch.IsPseudoVersion(current) + qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 } + } + + case query == "patch": + if current == "none" { + return nil, &NoPatchBaseError{path} + } + if current == "" { + qm.mayUseLatest = true + } else { + qm.mayUseLatest = modfetch.IsPseudoVersion(current) + qm.prefix = semver.MajorMinor(current) + "." + qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 } + } + + case strings.HasPrefix(query, "<="): + v := query[len("<="):] + if !semver.IsValid(v) { + return badVersion(v) + } + if isSemverPrefix(v) { + // Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). + return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) <= 0 } + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, "<"): + v := query[len("<"):] + if !semver.IsValid(v) { + return badVersion(v) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) < 0 } + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, ">="): + v := query[len(">="):] + if !semver.IsValid(v) { + return badVersion(v) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) >= 0 } + qm.preferLower = true + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, ">"): + v := query[len(">"):] + if !semver.IsValid(v) { + return badVersion(v) + } + if isSemverPrefix(v) { + // Refuse to say whether >v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). + return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) > 0 } + qm.preferLower = true + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case semver.IsValid(query): + if isSemverPrefix(query) { + qm.prefix = query + "." + // Do not allow the query "v1.2" to match versions lower than "v1.2.0", + // such as prereleases for that version. (https://golang.org/issue/31972) + qm.filter = func(mv string) bool { return semver.Compare(mv, query) >= 0 } + } else { + qm.canStat = true + qm.filter = func(mv string) bool { return semver.Compare(mv, query) == 0 } + qm.prefix = semver.Canonical(query) + } + if !matchesMajor(query) { + qm.preferIncompatible = true + } + + default: + return nil, errRevQuery + } + + return qm, nil +} + +// allowsVersion reports whether version v is allowed by the prefix, filter, and +// AllowedFunc of qm. +func (qm *queryMatcher) allowsVersion(ctx context.Context, v string) bool { + if qm.prefix != "" && !strings.HasPrefix(v, qm.prefix) { + return false + } + if qm.filter != nil && !qm.filter(v) { + return false + } + if qm.allowed != nil { + if err := qm.allowed(ctx, module.Version{Path: qm.path, Version: v}); errors.Is(err, ErrDisallowed) { + return false + } + } + return true } // filterVersions classifies versions into releases and pre-releases, filtering @@ -371,14 +437,32 @@ func matchSemverPrefix(p, v string) bool { // // If the allowed predicate returns an error not equivalent to ErrDisallowed, // filterVersions returns that error. -func filterVersions(ctx context.Context, path string, versions []string, allowed AllowedFunc, preferIncompatible bool) (releases, prereleases []string, err error) { +func (qm *queryMatcher) filterVersions(ctx context.Context, versions []string) (releases, prereleases []string, err error) { + needIncompatible := qm.preferIncompatible + var lastCompatible string for _, v := range versions { - if err := allowed(ctx, module.Version{Path: path, Version: v}); errors.Is(err, ErrDisallowed) { + if !qm.allowsVersion(ctx, v) { continue } - if !preferIncompatible { + if !needIncompatible { + // We're not yet sure whether we need to include +incomptaible versions. + // Keep track of the last compatible version we've seen, and use the + // presence (or absence) of a go.mod file in that version to decide: a + // go.mod file implies that the module author is supporting modules at a + // compatible version (and we should ignore +incompatible versions unless + // requested explicitly), while a lack of go.mod file implies the + // potential for legacy (pre-modules) versioning without semantic import + // paths (and thus *with* +incompatible versions). + // + // This isn't strictly accurate if the latest compatible version has been + // replaced by a local file path, because we do not allow file-path + // replacements without a go.mod file: the user would have needed to add + // one. However, replacing the last compatible version while + // simultaneously expecting to upgrade implicitly to a +incompatible + // version seems like an extreme enough corner case to ignore for now. + if !strings.HasSuffix(v, "+incompatible") { lastCompatible = v } else if lastCompatible != "" { @@ -386,19 +470,22 @@ func filterVersions(ctx context.Context, path string, versions []string, allowed // ignore any version with a higher (+incompatible) major version. (See // https://golang.org/issue/34165.) Note that we even prefer a // compatible pre-release over an incompatible release. - - ok, err := versionHasGoMod(ctx, module.Version{Path: path, Version: lastCompatible}) + ok, err := versionHasGoMod(ctx, module.Version{Path: qm.path, Version: lastCompatible}) if err != nil { return nil, nil, err } if ok { + // The last compatible version has a go.mod file, so that's the + // highest version we're willing to consider. Don't bother even + // looking at higher versions, because they're all +incompatible from + // here onward. break } // No acceptable compatible release has a go.mod file, so the versioning // for the module might not be module-aware, and we should respect // legacy major-version tags. - preferIncompatible = true + needIncompatible = true } } @@ -418,34 +505,39 @@ type QueryResult struct { Packages []string } -// QueryPackage looks up the module(s) containing path at a revision matching -// query. The results are sorted by module path length in descending order. -// -// If the package is in the main module, QueryPackage considers only the main -// module and only the version "latest", without checking for other possible -// modules. -func QueryPackage(ctx context.Context, path, query string, allowed AllowedFunc) ([]QueryResult, error) { - m := search.NewMatch(path) - if m.IsLocal() || !m.IsLiteral() { - return nil, fmt.Errorf("pattern %s is not an importable package", path) +// QueryPackages is like QueryPattern, but requires that the pattern match at +// least one package and omits the non-package result (if any). +func QueryPackages(ctx context.Context, pattern, query string, current func(string) string, allowed AllowedFunc) ([]QueryResult, error) { + pkgMods, modOnly, err := QueryPattern(ctx, pattern, query, current, allowed) + + if len(pkgMods) == 0 && err == nil { + return nil, &PackageNotInModuleError{ + Mod: modOnly.Mod, + Replacement: Replacement(modOnly.Mod), + Query: query, + Pattern: pattern, + } } - return QueryPattern(ctx, path, query, allowed) + + return pkgMods, err } // QueryPattern looks up the module(s) containing at least one package matching // the given pattern at the given version. The results are sorted by module path -// length in descending order. +// length in descending order. If any proxy provides a non-empty set of candidate +// modules, no further proxies are tried. // -// QueryPattern queries modules with package paths up to the first "..." -// in the pattern. For the pattern "example.com/a/b.../c", QueryPattern would -// consider prefixes of "example.com/a". If multiple modules have versions -// that match the query and packages that match the pattern, QueryPattern -// picks the one with the longest module path. +// For wildcard patterns, QueryPattern looks in modules with package paths up to +// the first "..." in the pattern. For the pattern "example.com/a/b.../c", +// QueryPattern would consider prefixes of "example.com/a". // // If any matching package is in the main module, QueryPattern considers only // the main module and only the version "latest", without checking for other // possible modules. -func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFunc) ([]QueryResult, error) { +// +// QueryPattern always returns at least one QueryResult (which may be only +// modOnly) or a non-nil error. +func QueryPattern(ctx context.Context, pattern, query string, current func(string) string, allowed AllowedFunc) (pkgMods []QueryResult, modOnly *QueryResult, err error) { ctx, span := trace.StartSpan(ctx, "modload.QueryPattern "+pattern+" "+query) defer span.Done() @@ -459,9 +551,13 @@ func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFun } var match func(mod module.Version, root string, isLocal bool) *search.Match + matchPattern := search.MatchPattern(pattern) if i := strings.Index(pattern, "..."); i >= 0 { base = pathpkg.Dir(pattern[:i+3]) + if base == "." { + return nil, nil, &WildcardInFirstElementError{Pattern: pattern, Query: query} + } match = func(mod module.Version, root string, isLocal bool) *search.Match { m := search.NewMatch(pattern) matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{mod}) @@ -483,23 +579,41 @@ func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFun } } + var queryMatchesMainModule bool if HasModRoot() { m := match(Target, modRoot, true) if len(m.Pkgs) > 0 { - if query != "latest" { - return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path) + if query != "upgrade" && query != "patch" { + return nil, nil, &QueryMatchesPackagesInMainModuleError{ + Pattern: pattern, + Query: query, + Packages: m.Pkgs, + } } if err := allowed(ctx, Target); err != nil { - return nil, fmt.Errorf("internal error: package %s is in the main module (%s), but version is not allowed: %w", pattern, Target.Path, err) + return nil, nil, fmt.Errorf("internal error: package %s is in the main module (%s), but version is not allowed: %w", pattern, Target.Path, err) } return []QueryResult{{ Mod: Target, Rev: &modfetch.RevInfo{Version: Target.Version}, Packages: m.Pkgs, - }}, nil + }}, nil, nil } if err := firstError(m); err != nil { - return nil, err + return nil, nil, err + } + + if matchPattern(Target.Path) { + queryMatchesMainModule = true + } + + if (query == "upgrade" || query == "patch") && queryMatchesMainModule { + if err := allowed(ctx, Target); err == nil { + modOnly = &QueryResult{ + Mod: Target, + Rev: &modfetch.RevInfo{Version: Target.Version}, + } + } } } @@ -508,32 +622,42 @@ func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFun candidateModules = modulePrefixesExcludingTarget(base) ) if len(candidateModules) == 0 { - return nil, &PackageNotInModuleError{ - Mod: Target, - Query: query, - Pattern: pattern, + if modOnly != nil { + return nil, modOnly, nil + } else if queryMatchesMainModule { + return nil, nil, &QueryMatchesMainModuleError{ + Pattern: pattern, + Query: query, + } + } else { + return nil, nil, &PackageNotInModuleError{ + Mod: Target, + Query: query, + Pattern: pattern, + } } } - err := modfetch.TryProxies(func(proxy string) error { + err = modfetch.TryProxies(func(proxy string) error { queryModule := func(ctx context.Context, path string) (r QueryResult, err error) { ctx, span := trace.StartSpan(ctx, "modload.QueryPattern.queryModule ["+proxy+"] "+path) defer span.Done() - current := findCurrentVersion(path) + pathCurrent := current(path) r.Mod.Path = path - r.Rev, err = queryProxy(ctx, proxy, path, query, current, allowed) + r.Rev, err = queryProxy(ctx, proxy, path, query, pathCurrent, allowed) if err != nil { return r, err } r.Mod.Version = r.Rev.Version - root, isLocal, err := fetch(ctx, r.Mod) + needSum := true + root, isLocal, err := fetch(ctx, r.Mod, needSum) if err != nil { return r, err } m := match(r.Mod, root, isLocal) r.Packages = m.Pkgs - if len(r.Packages) == 0 { + if len(r.Packages) == 0 && !matchPattern(path) { if err := firstError(m); err != nil { return r, err } @@ -547,12 +671,25 @@ func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFun return r, nil } - var err error - results, err = queryPrefixModules(ctx, candidateModules, queryModule) + allResults, err := queryPrefixModules(ctx, candidateModules, queryModule) + results = allResults[:0] + for _, r := range allResults { + if len(r.Packages) == 0 { + modOnly = &r + } else { + results = append(results, r) + } + } return err }) - return results, err + if queryMatchesMainModule && len(results) == 0 && modOnly == nil && errors.Is(err, fs.ErrNotExist) { + return nil, nil, &QueryMatchesMainModuleError{ + Pattern: pattern, + Query: query, + } + } + return results[:len(results):len(results)], modOnly, err } // modulePrefixesExcludingTarget returns all prefixes of path that may plausibly @@ -578,20 +715,6 @@ func modulePrefixesExcludingTarget(path string) []string { return prefixes } -func findCurrentVersion(path string) string { - for _, m := range buildList { - if m.Path == path { - return m.Version - } - } - return "" -} - -type prefixResult struct { - QueryResult - err error -} - func queryPrefixModules(ctx context.Context, candidateModules []string, queryModule func(ctx context.Context, path string) (QueryResult, error)) (found []QueryResult, err error) { ctx, span := trace.StartSpan(ctx, "modload.queryPrefixModules") defer span.Done() @@ -622,6 +745,7 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod var ( noPackage *PackageNotInModuleError noVersion *NoMatchingVersionError + noPatchBase *NoPatchBaseError notExistErr error ) for _, r := range results { @@ -638,8 +762,12 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod if noVersion == nil { noVersion = rErr } + case *NoPatchBaseError: + if noPatchBase == nil { + noPatchBase = rErr + } default: - if errors.Is(rErr, os.ErrNotExist) { + if errors.Is(rErr, fs.ErrNotExist) { if notExistErr == nil { notExistErr = rErr } @@ -669,6 +797,8 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod err = noPackage case noVersion != nil: err = noVersion + case noPatchBase != nil: + err = noPatchBase case notExistErr != nil: err = notExistErr default: @@ -682,7 +812,7 @@ func queryPrefixModules(ctx context.Context, candidateModules []string, queryMod // A NoMatchingVersionError indicates that Query found a module at the requested // path, but not at any versions satisfying the query string and allow-function. // -// NOTE: NoMatchingVersionError MUST NOT implement Is(os.ErrNotExist). +// NOTE: NoMatchingVersionError MUST NOT implement Is(fs.ErrNotExist). // // If the module came from a proxy, that proxy had to return a successful status // code for the versions it knows about, and thus did not have the opportunity @@ -693,17 +823,39 @@ type NoMatchingVersionError struct { func (e *NoMatchingVersionError) Error() string { currentSuffix := "" - if (e.query == "upgrade" || e.query == "patch") && e.current != "" { + if (e.query == "upgrade" || e.query == "patch") && e.current != "" && e.current != "none" { currentSuffix = fmt.Sprintf(" (current version is %s)", e.current) } return fmt.Sprintf("no matching versions for query %q", e.query) + currentSuffix } +// A NoPatchBaseError indicates that Query was called with the query "patch" +// but with a current version of "" or "none". +type NoPatchBaseError struct { + path string +} + +func (e *NoPatchBaseError) Error() string { + return fmt.Sprintf(`can't query version "patch" of module %s: no existing version is required`, e.path) +} + +// A WildcardInFirstElementError indicates that a pattern passed to QueryPattern +// had a wildcard in its first path element, and therefore had no pattern-prefix +// modules to search in. +type WildcardInFirstElementError struct { + Pattern string + Query string +} + +func (e *WildcardInFirstElementError) Error() string { + return fmt.Sprintf("no modules to query for %s@%s because first path element contains a wildcard", e.Pattern, e.Query) +} + // A PackageNotInModuleError indicates that QueryPattern found a candidate // module at the requested version, but that module did not contain any packages // matching the requested pattern. // -// NOTE: PackageNotInModuleError MUST NOT implement Is(os.ErrNotExist). +// NOTE: PackageNotInModuleError MUST NOT implement Is(fs.ErrNotExist). // // If the module came from a proxy, that proxy had to return a successful status // code for the versions it knows about, and thus did not have the opportunity @@ -753,7 +905,8 @@ func (e *PackageNotInModuleError) ImportPath() string { // ModuleHasRootPackage returns whether module m contains a package m.Path. func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { - root, isLocal, err := fetch(ctx, m) + needSum := false + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { return false, err } @@ -762,10 +915,201 @@ func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { } func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) { - root, _, err := fetch(ctx, m) + needSum := false + root, _, err := fetch(ctx, m, needSum) if err != nil { return false, err } fi, err := os.Stat(filepath.Join(root, "go.mod")) return err == nil && !fi.IsDir(), nil } + +// A versionRepo is a subset of modfetch.Repo that can report information about +// available versions, but cannot fetch specific source files. +type versionRepo interface { + ModulePath() string + Versions(prefix string) ([]string, error) + Stat(rev string) (*modfetch.RevInfo, error) + Latest() (*modfetch.RevInfo, error) +} + +var _ versionRepo = modfetch.Repo(nil) + +func lookupRepo(proxy, path string) (repo versionRepo, err error) { + err = module.CheckPath(path) + if err == nil { + repo = modfetch.Lookup(proxy, path) + } else { + repo = emptyRepo{path: path, err: err} + } + + if index == nil { + return repo, err + } + if _, ok := index.highestReplaced[path]; !ok { + return repo, err + } + + return &replacementRepo{repo: repo}, nil +} + +// An emptyRepo is a versionRepo that contains no versions. +type emptyRepo struct { + path string + err error +} + +var _ versionRepo = emptyRepo{} + +func (er emptyRepo) ModulePath() string { return er.path } +func (er emptyRepo) Versions(prefix string) ([]string, error) { return nil, nil } +func (er emptyRepo) Stat(rev string) (*modfetch.RevInfo, error) { return nil, er.err } +func (er emptyRepo) Latest() (*modfetch.RevInfo, error) { return nil, er.err } + +// A replacementRepo augments a versionRepo to include the replacement versions +// (if any) found in the main module's go.mod file. +// +// A replacementRepo suppresses "not found" errors for otherwise-nonexistent +// modules, so a replacementRepo should only be constructed for a module that +// actually has one or more valid replacements. +type replacementRepo struct { + repo versionRepo +} + +var _ versionRepo = (*replacementRepo)(nil) + +func (rr *replacementRepo) ModulePath() string { return rr.repo.ModulePath() } + +// Versions returns the versions from rr.repo augmented with any matching +// replacement versions. +func (rr *replacementRepo) Versions(prefix string) ([]string, error) { + repoVersions, err := rr.repo.Versions(prefix) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, err + } + + versions := repoVersions + if index != nil && len(index.replace) > 0 { + path := rr.ModulePath() + for m, _ := range index.replace { + if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !modfetch.IsPseudoVersion(m.Version) { + versions = append(versions, m.Version) + } + } + } + + if len(versions) == len(repoVersions) { // No replacement versions added. + return versions, nil + } + + sort.Slice(versions, func(i, j int) bool { + return semver.Compare(versions[i], versions[j]) < 0 + }) + uniq := versions[:1] + for _, v := range versions { + if v != uniq[len(uniq)-1] { + uniq = append(uniq, v) + } + } + return uniq, nil +} + +func (rr *replacementRepo) Stat(rev string) (*modfetch.RevInfo, error) { + info, err := rr.repo.Stat(rev) + if err == nil || index == nil || len(index.replace) == 0 { + return info, err + } + + v := module.CanonicalVersion(rev) + if v != rev { + // The replacements in the go.mod file list only canonical semantic versions, + // so a non-canonical version can't possibly have a replacement. + return info, err + } + + path := rr.ModulePath() + _, pathMajor, ok := module.SplitPathVersion(path) + if ok && pathMajor == "" { + if err := module.CheckPathMajor(v, pathMajor); err != nil && semver.Build(v) == "" { + v += "+incompatible" + } + } + + if r := Replacement(module.Version{Path: path, Version: v}); r.Path == "" { + return info, err + } + return rr.replacementStat(v) +} + +func (rr *replacementRepo) Latest() (*modfetch.RevInfo, error) { + info, err := rr.repo.Latest() + + if index != nil { + path := rr.ModulePath() + if v, ok := index.highestReplaced[path]; ok { + if v == "" { + // The only replacement is a wildcard that doesn't specify a version, so + // synthesize a pseudo-version with an appropriate major version and a + // timestamp below any real timestamp. That way, if the main module is + // used from within some other module, the user will be able to upgrade + // the requirement to any real version they choose. + if _, pathMajor, ok := module.SplitPathVersion(path); ok && len(pathMajor) > 0 { + v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000") + } else { + v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000") + } + } + + if err != nil || semver.Compare(v, info.Version) > 0 { + return rr.replacementStat(v) + } + } + } + + return info, err +} + +func (rr *replacementRepo) replacementStat(v string) (*modfetch.RevInfo, error) { + rev := &modfetch.RevInfo{Version: v} + if modfetch.IsPseudoVersion(v) { + rev.Time, _ = modfetch.PseudoVersionTime(v) + rev.Short, _ = modfetch.PseudoVersionRev(v) + } + return rev, nil +} + +// A QueryMatchesMainModuleError indicates that a query requests +// a version of the main module that cannot be satisfied. +// (The main module's version cannot be changed.) +type QueryMatchesMainModuleError struct { + Pattern string + Query string +} + +func (e *QueryMatchesMainModuleError) Error() string { + if e.Pattern == Target.Path { + return fmt.Sprintf("can't request version %q of the main module (%s)", e.Query, e.Pattern) + } + + return fmt.Sprintf("can't request version %q of pattern %q that includes the main module (%s)", e.Query, e.Pattern, Target.Path) +} + +// A QueryMatchesPackagesInMainModuleError indicates that a query cannot be +// satisfied because it matches one or more packages found in the main module. +type QueryMatchesPackagesInMainModuleError struct { + Pattern string + Query string + Packages []string +} + +func (e *QueryMatchesPackagesInMainModuleError) Error() string { + if len(e.Packages) > 1 { + return fmt.Sprintf("pattern %s matches %d packages in the main module, so can't request version %s", e.Pattern, len(e.Packages), e.Query) + } + + if search.IsMetaPackage(e.Pattern) || strings.Contains(e.Pattern, "...") { + return fmt.Sprintf("pattern %s matches package %s in the main module, so can't request version %s", e.Pattern, e.Packages[0], e.Query) + } + + return fmt.Sprintf("package %s is in the main module, so can't request version %s", e.Packages[0], e.Query) +} diff --git a/src/cmd/go/internal/modload/query_test.go b/src/cmd/go/internal/modload/query_test.go index 351826f2ab..e225a0e71e 100644 --- a/src/cmd/go/internal/modload/query_test.go +++ b/src/cmd/go/internal/modload/query_test.go @@ -7,7 +7,6 @@ package modload import ( "context" "internal/testenv" - "io/ioutil" "log" "os" "path" @@ -27,7 +26,7 @@ func TestMain(m *testing.M) { func testMain(m *testing.M) int { cfg.GOPROXY = "direct" - dir, err := ioutil.TempDir("", "modload-test-") + dir, err := os.MkdirTemp("", "modload-test-") if err != nil { log.Fatal(err) } @@ -45,7 +44,7 @@ var ( queryRepoV3 = queryRepo + "/v3" // Empty version list (no semver tags), not actually empty. - emptyRepo = "vcs-test.golang.org/git/emptytest.git" + emptyRepoPath = "vcs-test.golang.org/git/emptytest.git" ) var queryTests = []struct { @@ -121,14 +120,14 @@ var queryTests = []struct { {path: queryRepo, query: "upgrade", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, {path: queryRepo, query: "upgrade", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"}, {path: queryRepo, query: "upgrade", allow: "NOMATCH", err: `no matching versions for query "upgrade"`}, - {path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "upgrade" (current version is v1.9.9)`}, + {path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `vcs-test.golang.org/git/querytest.git@v1.9.9: disallowed module version`}, {path: queryRepo, query: "upgrade", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`}, {path: queryRepo, query: "patch", current: "", vers: "v1.9.9"}, {path: queryRepo, query: "patch", current: "v0.1.0", vers: "v0.1.2"}, {path: queryRepo, query: "patch", current: "v1.9.0", vers: "v1.9.9"}, {path: queryRepo, query: "patch", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"}, {path: queryRepo, query: "patch", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, - {path: queryRepo, query: "patch", current: "v1.99.99", err: `no matching versions for query "patch" (current version is v1.99.99)`}, + {path: queryRepo, query: "patch", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`}, {path: queryRepo, query: ">v1.9.9", vers: "v1.9.10-pre1"}, {path: queryRepo, query: ">v1.10.0", err: `no matching versions for query ">v1.10.0"`}, {path: queryRepo, query: ">=v1.10.0", err: `no matching versions for query ">=v1.10.0"`}, @@ -171,9 +170,9 @@ var queryTests = []struct { // That should prevent us from resolving any version for the /v3 path. {path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`}, - {path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"}, - {path: emptyRepo, query: ">v0.0.0", err: `no matching versions for query ">v0.0.0"`}, - {path: emptyRepo, query: "<v10.0.0", err: `no matching versions for query "<v10.0.0"`}, + {path: emptyRepoPath, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"}, + {path: emptyRepoPath, query: ">v0.0.0", err: `no matching versions for query ">v0.0.0"`}, + {path: emptyRepoPath, query: "<v10.0.0", err: `no matching versions for query "<v10.0.0"`}, } func TestQuery(t *testing.T) { @@ -189,7 +188,7 @@ func TestQuery(t *testing.T) { } allowed := func(ctx context.Context, m module.Version) error { if ok, _ := path.Match(allow, m.Version); !ok { - return ErrDisallowed + return module.VersionError(m, ErrDisallowed) } return nil } @@ -200,17 +199,17 @@ func TestQuery(t *testing.T) { info, err := Query(ctx, tt.path, tt.query, tt.current, allowed) if tt.err != "" { if err == nil { - t.Errorf("Query(%q, %q, %v) = %v, want error %q", tt.path, tt.query, allow, info.Version, tt.err) + t.Errorf("Query(_, %q, %q, %q, %v) = %v, want error %q", tt.path, tt.query, tt.current, allow, info.Version, tt.err) } else if err.Error() != tt.err { - t.Errorf("Query(%q, %q, %v): %v, want error %q", tt.path, tt.query, allow, err, tt.err) + t.Errorf("Query(_, %q, %q, %q, %v): %v\nwant error %q", tt.path, tt.query, tt.current, allow, err, tt.err) } return } if err != nil { - t.Fatalf("Query(%q, %q, %v): %v", tt.path, tt.query, allow, err) + t.Fatalf("Query(_, %q, %q, %q, %v): %v\nwant %v", tt.path, tt.query, tt.current, allow, err, tt.vers) } if info.Version != tt.vers { - t.Errorf("Query(%q, %q, %v) = %v, want %v", tt.path, tt.query, allow, info.Version, tt.vers) + t.Errorf("Query(_, %q, %q, %q, %v) = %v, want %v", tt.path, tt.query, tt.current, allow, info.Version, tt.vers) } }) } diff --git a/src/cmd/go/internal/modload/search.go b/src/cmd/go/internal/modload/search.go index a9bee0af4e..1fe742dc97 100644 --- a/src/cmd/go/internal/modload/search.go +++ b/src/cmd/go/internal/modload/search.go @@ -7,11 +7,13 @@ package modload import ( "context" "fmt" + "io/fs" "os" "path/filepath" "strings" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/imports" "cmd/go/internal/search" @@ -53,7 +55,7 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f walkPkgs := func(root, importPathRoot string, prune pruning) { root = filepath.Clean(root) - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + err := fsys.Walk(root, func(path string, fi fs.FileInfo, err error) error { if err != nil { m.AddError(err) return nil @@ -84,8 +86,8 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f } if !fi.IsDir() { - if fi.Mode()&os.ModeSymlink != 0 && want { - if target, err := os.Stat(path); err == nil && target.IsDir() { + if fi.Mode()&fs.ModeSymlink != 0 && want { + if target, err := fsys.Stat(path); err == nil && target.IsDir() { fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path) } } @@ -154,7 +156,8 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f isLocal = true } else { var err error - root, isLocal, err = fetch(ctx, mod) + const needSum = true + root, isLocal, err = fetch(ctx, mod, needSum) if err != nil { m.AddError(err) continue @@ -171,3 +174,46 @@ func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, f return } + +// MatchInModule identifies the packages matching the given pattern within the +// given module version, which does not need to be in the build list or module +// requirement graph. +// +// If m is the zero module.Version, MatchInModule matches the pattern +// against the standard library (std and cmd) in GOROOT/src. +func MatchInModule(ctx context.Context, pattern string, m module.Version, tags map[string]bool) *search.Match { + match := search.NewMatch(pattern) + if m == (module.Version{}) { + matchPackages(ctx, match, tags, includeStd, nil) + } + + LoadModFile(ctx) + + if !match.IsLiteral() { + matchPackages(ctx, match, tags, omitStd, []module.Version{m}) + return match + } + + const needSum = true + root, isLocal, err := fetch(ctx, m, needSum) + if err != nil { + match.Errs = []error{err} + return match + } + + dir, haveGoFiles, err := dirInModule(pattern, m.Path, root, isLocal) + if err != nil { + match.Errs = []error{err} + return match + } + if haveGoFiles { + if _, _, err := scanDir(dir, tags); err != imports.ErrNoGo { + // ErrNoGo indicates that the directory is not actually a Go package, + // perhaps due to the tags in use. Any other non-nil error indicates a + // problem with one or more of the Go source files, but such an error does + // not stop the package from existing, so it has no impact on matching. + match.Pkgs = []string{pattern} + } + } + return match +} diff --git a/src/cmd/go/internal/modload/stat_openfile.go b/src/cmd/go/internal/modload/stat_openfile.go index 931aaf1577..5842b858f0 100644 --- a/src/cmd/go/internal/modload/stat_openfile.go +++ b/src/cmd/go/internal/modload/stat_openfile.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix js,wasm plan9 +// +build js,wasm plan9 // On plan9, per http://9p.io/magic/man2html/2/access: “Since file permissions // are checked by the server and group information is not known to the client, @@ -13,12 +13,13 @@ package modload import ( + "io/fs" "os" ) // hasWritePerm reports whether the current user has permission to write to the // file with the given info. -func hasWritePerm(path string, _ os.FileInfo) bool { +func hasWritePerm(path string, _ fs.FileInfo) bool { if f, err := os.OpenFile(path, os.O_WRONLY, 0); err == nil { f.Close() return true diff --git a/src/cmd/go/internal/modload/stat_unix.go b/src/cmd/go/internal/modload/stat_unix.go index ea3b801f2c..f49278ec3a 100644 --- a/src/cmd/go/internal/modload/stat_unix.go +++ b/src/cmd/go/internal/modload/stat_unix.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package modload import ( + "io/fs" "os" "syscall" ) @@ -17,7 +18,7 @@ import ( // Although the root user on most Unix systems can write to files even without // permission, hasWritePerm reports false if no appropriate permission bit is // set even if the current user is root. -func hasWritePerm(path string, fi os.FileInfo) bool { +func hasWritePerm(path string, fi fs.FileInfo) bool { if os.Getuid() == 0 { // The root user can access any file, but we still want to default to // read-only mode if the go.mod file is marked as globally non-writable. diff --git a/src/cmd/go/internal/modload/stat_windows.go b/src/cmd/go/internal/modload/stat_windows.go index d7826cfc6b..0ac2391347 100644 --- a/src/cmd/go/internal/modload/stat_windows.go +++ b/src/cmd/go/internal/modload/stat_windows.go @@ -6,13 +6,11 @@ package modload -import ( - "os" -) +import "io/fs" // hasWritePerm reports whether the current user has permission to write to the // file with the given info. -func hasWritePerm(_ string, fi os.FileInfo) bool { +func hasWritePerm(_ string, fi fs.FileInfo) bool { // Windows has a read-only attribute independent of ACLs, so use that to // determine whether the file is intended to be overwritten. // diff --git a/src/cmd/go/internal/modload/testgo.go b/src/cmd/go/internal/modload/testgo.go deleted file mode 100644 index 6b34f5be39..0000000000 --- a/src/cmd/go/internal/modload/testgo.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build testgo - -package modload - -func init() { - printStackInDie = true -} diff --git a/src/cmd/go/internal/modload/vendor.go b/src/cmd/go/internal/modload/vendor.go index 9f34b829fc..80d49053c6 100644 --- a/src/cmd/go/internal/modload/vendor.go +++ b/src/cmd/go/internal/modload/vendor.go @@ -7,7 +7,7 @@ package modload import ( "errors" "fmt" - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" @@ -40,9 +40,9 @@ func readVendorList() { vendorPkgModule = make(map[string]module.Version) vendorVersion = make(map[string]string) vendorMeta = make(map[module.Version]vendorMetadata) - data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) + data, err := os.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) if err != nil { - if !errors.Is(err, os.ErrNotExist) { + if !errors.Is(err, fs.ErrNotExist) { base.Fatalf("go: %s", err) } return diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go index ea23a9f45e..b630b610f1 100644 --- a/src/cmd/go/internal/mvs/mvs.go +++ b/src/cmd/go/internal/mvs/mvs.go @@ -108,19 +108,23 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m node := &modGraphNode{m: m} mu.Lock() modGraph[m] = node - if v, ok := min[m.Path]; !ok || reqs.Max(v, m.Version) != v { - min[m.Path] = m.Version + if m.Version != "none" { + if v, ok := min[m.Path]; !ok || reqs.Max(v, m.Version) != v { + min[m.Path] = m.Version + } } mu.Unlock() - required, err := reqs.Required(m) - if err != nil { - setErr(node, err) - return - } - node.required = required - for _, r := range node.required { - work.Add(r) + if m.Version != "none" { + required, err := reqs.Required(m) + if err != nil { + setErr(node, err) + return + } + node.required = required + for _, r := range node.required { + work.Add(r) + } } if upgrade != nil { @@ -208,6 +212,9 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m n := modGraph[module.Version{Path: path, Version: vers}] required := n.required for _, r := range required { + if r.Version == "none" { + continue + } v := min[r.Path] if r.Path != target.Path && reqs.Max(v, r.Version) != v { panic(fmt.Sprintf("mistake: version %q does not satisfy requirement %+v", v, r)) // TODO: Don't panic. @@ -328,16 +335,36 @@ func Upgrade(target module.Version, reqs Reqs, upgrade ...module.Version) ([]mod if err != nil { return nil, err } - // TODO: Maybe if an error is given, - // rerun with BuildList(upgrade[0], reqs) etc - // to find which ones are the buggy ones. + + pathInList := make(map[string]bool, len(list)) + for _, m := range list { + pathInList[m.Path] = true + } list = append([]module.Version(nil), list...) - list = append(list, upgrade...) - return BuildList(target, &override{target, list, reqs}) + + upgradeTo := make(map[string]string, len(upgrade)) + for _, u := range upgrade { + if !pathInList[u.Path] { + list = append(list, module.Version{Path: u.Path, Version: "none"}) + } + if prev, dup := upgradeTo[u.Path]; dup { + upgradeTo[u.Path] = reqs.Max(prev, u.Version) + } else { + upgradeTo[u.Path] = u.Version + } + } + + return buildList(target, &override{target, list, reqs}, func(m module.Version) (module.Version, error) { + if v, ok := upgradeTo[m.Path]; ok { + return module.Version{Path: m.Path, Version: v}, nil + } + return m, nil + }) } // Downgrade returns a build list for the target module -// in which the given additional modules are downgraded. +// in which the given additional modules are downgraded, +// potentially overriding the requirements of the target. // // The versions to be downgraded may be unreachable from reqs.Latest and // reqs.Previous, but the methods of reqs must otherwise handle such versions diff --git a/src/cmd/go/internal/mvs/mvs_test.go b/src/cmd/go/internal/mvs/mvs_test.go index 9a30a8c3ac..721cd9635c 100644 --- a/src/cmd/go/internal/mvs/mvs_test.go +++ b/src/cmd/go/internal/mvs/mvs_test.go @@ -54,7 +54,7 @@ build A: A B C D2 E2 name: cross1V A: B2 C D2 E1 -B1: +B1: B2: D1 C: D2 D1: E2 @@ -63,7 +63,7 @@ build A: A B2 C D2 E2 name: cross1U A: B1 C -B1: +B1: B2: D1 C: D2 D1: E2 @@ -72,7 +72,7 @@ build A: A B1 C D2 E1 upgrade A B2: A B2 C D2 E2 name: cross1R -A: B C +A: B C B: D2 C: D1 D1: E2 @@ -165,7 +165,7 @@ M: A1 B1 A1: X1 B1: X2 X1: I1 -X2: +X2: build M: M A1 B1 I1 X2 # Upgrade from B1 to B2 should not drop the transitive dep on D. @@ -229,28 +229,31 @@ E1: F1: downgrade A F1: A B1 E1 -name: down3 -A: +name: downcycle +A: A B2 +B2: A +B1: +downgrade A B1: A B1 # golang.org/issue/25542. name: noprev1 A: B4 C2 -B2.hidden: -C2: +B2.hidden: +C2: downgrade A B2.hidden: A B2.hidden C2 name: noprev2 A: B4 C2 -B2.hidden: -B1: -C2: +B2.hidden: +B1: +C2: downgrade A B2.hidden: A B2.hidden C2 name: noprev3 A: B4 C2 -B3: -B2.hidden: -C2: +B3: +B2.hidden: +C2: downgrade A B2.hidden: A B2.hidden C2 # Cycles involving the target. @@ -315,8 +318,15 @@ M: A1 B1 A1: X1 B1: X2 X1: I1 -X2: +X2: req M: A1 B1 + +name: reqnone +M: Anone B1 D1 E1 +B1: Cnone D1 +E1: Fnone +build M: M B1 D1 E1 +req M: B1 E1 ` func Test(t *testing.T) { @@ -331,6 +341,9 @@ func Test(t *testing.T) { for _, fn := range fns { fn(t) } + if len(fns) == 0 { + t.Errorf("no functions tested") + } }) } } @@ -478,9 +491,9 @@ func (r reqsMap) Max(v1, v2 string) string { } func (r reqsMap) Upgrade(m module.Version) (module.Version, error) { - var u module.Version + u := module.Version{Version: "none"} for k := range r { - if k.Path == m.Path && u.Version < k.Version && !strings.HasSuffix(k.Version, ".hidden") { + if k.Path == m.Path && r.Max(u.Version, k.Version) == k.Version && !strings.HasSuffix(k.Version, ".hidden") { u = k } } diff --git a/src/cmd/go/internal/renameio/renameio.go b/src/cmd/go/internal/renameio/renameio.go index d573cc690d..9788171d6e 100644 --- a/src/cmd/go/internal/renameio/renameio.go +++ b/src/cmd/go/internal/renameio/renameio.go @@ -8,6 +8,7 @@ package renameio import ( "bytes" "io" + "io/fs" "math/rand" "os" "path/filepath" @@ -24,18 +25,18 @@ func Pattern(filename string) string { return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) } -// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary +// WriteFile is like os.WriteFile, but first writes data to an arbitrary // file in the same directory as filename, then renames it atomically to the // final name. // // That ensures that the final location, if it exists, is always a complete file. -func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { +func WriteFile(filename string, data []byte, perm fs.FileMode) (err error) { return WriteToFile(filename, bytes.NewReader(data), perm) } // WriteToFile is a variant of WriteFile that accepts the data as an io.Reader // instead of a slice. -func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) { +func WriteToFile(filename string, data io.Reader, perm fs.FileMode) (err error) { f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm) if err != nil { return err @@ -66,7 +67,7 @@ func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) return robustio.Rename(f.Name(), filename) } -// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that +// ReadFile is like os.ReadFile, but on Windows retries spurious errors that // may occur if the file is concurrently replaced. // // Errors are classified heuristically and retries are bounded, so even this @@ -80,7 +81,7 @@ func ReadFile(filename string) ([]byte, error) { } // tempFile creates a new temporary file with given permission bits. -func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) { +func tempFile(dir, prefix string, perm fs.FileMode) (f *os.File, err error) { for i := 0; i < 10000; i++ { name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix) f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) diff --git a/src/cmd/go/internal/renameio/renameio_test.go b/src/cmd/go/internal/renameio/renameio_test.go index df8ddabdb8..5b2ed83624 100644 --- a/src/cmd/go/internal/renameio/renameio_test.go +++ b/src/cmd/go/internal/renameio/renameio_test.go @@ -10,7 +10,6 @@ import ( "encoding/binary" "errors" "internal/testenv" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -30,7 +29,7 @@ func TestConcurrentReadsAndWrites(t *testing.T) { testenv.SkipFlaky(t, 33041) } - dir, err := ioutil.TempDir("", "renameio") + dir, err := os.MkdirTemp("", "renameio") if err != nil { t.Fatal(err) } @@ -144,10 +143,12 @@ func TestConcurrentReadsAndWrites(t *testing.T) { // As long as those are the only errors and *some* of the reads succeed, we're happy. minReadSuccesses = attempts / 4 - case "darwin": - // The filesystem on macOS 10.14 occasionally fails with "no such file or - // directory" errors. See https://golang.org/issue/33041. The flake rate is - // fairly low, so ensure that at least 75% of attempts succeed. + case "darwin", "ios": + // The filesystem on certain versions of macOS (10.14) and iOS (affected + // versions TBD) occasionally fail with "no such file or directory" errors. + // See https://golang.org/issue/33041 and https://golang.org/issue/42066. + // The flake rate is fairly low, so ensure that at least 75% of attempts + // succeed. minReadSuccesses = attempts - (attempts / 4) } diff --git a/src/cmd/go/internal/renameio/umask_test.go b/src/cmd/go/internal/renameio/umask_test.go index d75d67c9a9..65e4fa587b 100644 --- a/src/cmd/go/internal/renameio/umask_test.go +++ b/src/cmd/go/internal/renameio/umask_test.go @@ -7,7 +7,7 @@ package renameio import ( - "io/ioutil" + "io/fs" "os" "path/filepath" "syscall" @@ -15,7 +15,7 @@ import ( ) func TestWriteFileModeAppliesUmask(t *testing.T) { - dir, err := ioutil.TempDir("", "renameio") + dir, err := os.MkdirTemp("", "renameio") if err != nil { t.Fatalf("Failed to create temporary directory: %v", err) } @@ -36,7 +36,7 @@ func TestWriteFileModeAppliesUmask(t *testing.T) { t.Fatalf("Stat %q (looking for mode %#o): %s", file, mode, err) } - if fi.Mode()&os.ModePerm != 0640 { - t.Errorf("Stat %q: mode %#o want %#o", file, fi.Mode()&os.ModePerm, 0640) + if fi.Mode()&fs.ModePerm != 0640 { + t.Errorf("Stat %q: mode %#o want %#o", file, fi.Mode()&fs.ModePerm, 0640) } } diff --git a/src/cmd/go/internal/robustio/robustio.go b/src/cmd/go/internal/robustio/robustio.go index 76e47ad1ff..ce3dbbde6d 100644 --- a/src/cmd/go/internal/robustio/robustio.go +++ b/src/cmd/go/internal/robustio/robustio.go @@ -22,7 +22,7 @@ func Rename(oldpath, newpath string) error { return rename(oldpath, newpath) } -// ReadFile is like ioutil.ReadFile, but on Windows retries errors that may +// ReadFile is like os.ReadFile, but on Windows retries errors that may // occur if the file is concurrently replaced. // // (See golang.org/issue/31247 and golang.org/issue/32188.) diff --git a/src/cmd/go/internal/robustio/robustio_flaky.go b/src/cmd/go/internal/robustio/robustio_flaky.go index d4cb7e6457..5bd44bd345 100644 --- a/src/cmd/go/internal/robustio/robustio_flaky.go +++ b/src/cmd/go/internal/robustio/robustio_flaky.go @@ -8,7 +8,6 @@ package robustio import ( "errors" - "io/ioutil" "math/rand" "os" "syscall" @@ -70,11 +69,11 @@ func rename(oldpath, newpath string) (err error) { }) } -// readFile is like ioutil.ReadFile, but retries ephemeral errors. +// readFile is like os.ReadFile, but retries ephemeral errors. func readFile(filename string) ([]byte, error) { var b []byte err := retry(func() (err error, mayRetry bool) { - b, err = ioutil.ReadFile(filename) + b, err = os.ReadFile(filename) // Unlike in rename, we do not retry errFileNotFound here: it can occur // as a spurious error, but the file may also genuinely not exist, so the diff --git a/src/cmd/go/internal/robustio/robustio_other.go b/src/cmd/go/internal/robustio/robustio_other.go index 907b556858..6fe7b7e4e4 100644 --- a/src/cmd/go/internal/robustio/robustio_other.go +++ b/src/cmd/go/internal/robustio/robustio_other.go @@ -7,7 +7,6 @@ package robustio import ( - "io/ioutil" "os" ) @@ -16,7 +15,7 @@ func rename(oldpath, newpath string) error { } func readFile(filename string) ([]byte, error) { - return ioutil.ReadFile(filename) + return os.ReadFile(filename) } func removeAll(path string) error { diff --git a/src/cmd/go/internal/search/search.go b/src/cmd/go/internal/search/search.go index 4efef24152..18738cf59e 100644 --- a/src/cmd/go/internal/search/search.go +++ b/src/cmd/go/internal/search/search.go @@ -7,8 +7,10 @@ package search import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "fmt" "go/build" + "io/fs" "os" "path" "path/filepath" @@ -127,7 +129,7 @@ func (m *Match) MatchPackages() { if m.pattern == "cmd" { root += "cmd" + string(filepath.Separator) } - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + err := fsys.Walk(root, func(path string, fi fs.FileInfo, err error) error { if err != nil { return err // Likely a permission error, which could interfere with matching. } @@ -153,8 +155,8 @@ func (m *Match) MatchPackages() { } if !fi.IsDir() { - if fi.Mode()&os.ModeSymlink != 0 && want { - if target, err := os.Stat(path); err == nil && target.IsDir() { + if fi.Mode()&fs.ModeSymlink != 0 && want { + if target, err := fsys.Stat(path); err == nil && target.IsDir() { fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path) } } @@ -263,7 +265,7 @@ func (m *Match) MatchDirs() { } } - err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { + err := fsys.Walk(dir, func(path string, fi fs.FileInfo, err error) error { if err != nil { return err // Likely a permission error, which could interfere with matching. } @@ -272,7 +274,7 @@ func (m *Match) MatchDirs() { } top := false if path == dir { - // filepath.Walk starts at dir and recurses. For the recursive case, + // Walk starts at dir and recurses. For the recursive case, // the path is the result of filepath.Join, which calls filepath.Clean. // The initial case is not Cleaned, though, so we do this explicitly. // @@ -293,7 +295,7 @@ func (m *Match) MatchDirs() { if !top && cfg.ModulesEnabled { // Ignore other modules found in subdirectories. - if fi, err := os.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() { return filepath.SkipDir } } diff --git a/src/cmd/go/internal/str/str_test.go b/src/cmd/go/internal/str/str_test.go new file mode 100644 index 0000000000..147ce1a63e --- /dev/null +++ b/src/cmd/go/internal/str/str_test.go @@ -0,0 +1,27 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package str + +import "testing" + +var foldDupTests = []struct { + list []string + f1, f2 string +}{ + {StringList("math/rand", "math/big"), "", ""}, + {StringList("math", "strings"), "", ""}, + {StringList("strings"), "", ""}, + {StringList("strings", "strings"), "strings", "strings"}, + {StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, +} + +func TestFoldDup(t *testing.T) { + for _, tt := range foldDupTests { + f1, f2 := FoldDup(tt.list) + if f1 != tt.f1 || f2 != tt.f2 { + t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) + } + } +} diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index 5758910a5f..41e58cb7fe 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -12,7 +12,7 @@ import ( "fmt" "go/build" "io" - "io/ioutil" + "io/fs" "os" "os/exec" "path" @@ -29,7 +29,6 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/load" "cmd/go/internal/lockedfile" - "cmd/go/internal/modload" "cmd/go/internal/str" "cmd/go/internal/trace" "cmd/go/internal/work" @@ -150,6 +149,7 @@ In addition to the build flags, the flags handled by 'go test' itself are: -i Install packages that are dependencies of the test. Do not run the test. + The -i flag is deprecated. Compiled packages are cached automatically. -json Convert test output to JSON suitable for automated processing. @@ -569,7 +569,7 @@ var defaultVetFlags = []string{ } func runTest(ctx context.Context, cmd *base.Command, args []string) { - modload.LoadTests = true + load.ModResolveTests = true pkgArgs, testArgs = testFlags(args) @@ -641,6 +641,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) { b.Init() if cfg.BuildI { + fmt.Fprint(os.Stderr, "go test: -i flag is deprecated\n") cfg.BuildV = testV deps := make(map[string]bool) @@ -883,7 +884,7 @@ func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAc if !cfg.BuildN { // writeTestmain writes _testmain.go, // using the test description gathered in t. - if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { + if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { return nil, nil, nil, err } } @@ -1568,13 +1569,18 @@ func hashOpen(name string) (cache.ActionID, error) { } hashWriteStat(h, info) if info.IsDir() { - names, err := ioutil.ReadDir(name) + files, err := os.ReadDir(name) if err != nil { fmt.Fprintf(h, "err %v\n", err) } - for _, f := range names { + for _, f := range files { fmt.Fprintf(h, "file %s ", f.Name()) - hashWriteStat(h, f) + finfo, err := f.Info() + if err != nil { + fmt.Fprintf(h, "err %v\n", err) + } else { + hashWriteStat(h, finfo) + } } } else if info.Mode().IsRegular() { // Because files might be very large, do not attempt @@ -1608,7 +1614,7 @@ func hashStat(name string) cache.ActionID { return h.Sum() } -func hashWriteStat(h io.Writer, info os.FileInfo) { +func hashWriteStat(h io.Writer, info fs.FileInfo) { fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir()) } @@ -1623,7 +1629,7 @@ func (c *runCache) saveOutput(a *work.Action) { } // See comment about two-level lookup in tryCacheWithID above. - testlog, err := ioutil.ReadFile(a.Objdir + "testlog.txt") + testlog, err := os.ReadFile(a.Objdir + "testlog.txt") if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' { if cache.DebugTest { if err != nil { diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go index 620dea646b..bba7ede2b2 100644 --- a/src/cmd/go/internal/test/testflag.go +++ b/src/cmd/go/internal/test/testflag.go @@ -213,6 +213,10 @@ func testFlags(args []string) (packageNames, passToTest []string) { } }) + // firstUnknownFlag helps us report an error when flags not known to 'go + // test' are used along with -i or -c. + firstUnknownFlag := "" + explicitArgs := make([]string, 0, len(args)) inPkgList := false afterFlagWithoutValue := false @@ -289,6 +293,10 @@ func testFlags(args []string) (packageNames, passToTest []string) { break } + if firstUnknownFlag == "" { + firstUnknownFlag = nd.RawArg + } + explicitArgs = append(explicitArgs, nd.RawArg) args = remainingArgs if !nd.HasValue { @@ -313,6 +321,14 @@ func testFlags(args []string) (packageNames, passToTest []string) { args = remainingArgs } + if firstUnknownFlag != "" && (testC || cfg.BuildI) { + buildFlag := "-c" + if !testC { + buildFlag = "-i" + } + fmt.Fprintf(os.Stderr, "flag %s is not a 'go test' flag (unknown flags cannot be used with %s)\n", firstUnknownFlag, buildFlag) + exitWithUsage() + } var injectedFlags []string if testJSON { diff --git a/src/cmd/go/internal/txtar/archive.go b/src/cmd/go/internal/txtar/archive.go index c384f33bdf..1796684877 100644 --- a/src/cmd/go/internal/txtar/archive.go +++ b/src/cmd/go/internal/txtar/archive.go @@ -34,7 +34,7 @@ package txtar import ( "bytes" "fmt" - "io/ioutil" + "os" "strings" ) @@ -66,7 +66,7 @@ func Format(a *Archive) []byte { // ParseFile parses the named file as an archive. func ParseFile(file string) (*Archive, error) { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return nil, err } diff --git a/src/cmd/go/internal/get/discovery.go b/src/cmd/go/internal/vcs/discovery.go index afa6ef455f..327b44cb9a 100644 --- a/src/cmd/go/internal/get/discovery.go +++ b/src/cmd/go/internal/vcs/discovery.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( "encoding/xml" diff --git a/src/cmd/go/internal/get/pkg_test.go b/src/cmd/go/internal/vcs/discovery_test.go index fc6a179c2e..eb99fdf64c 100644 --- a/src/cmd/go/internal/get/pkg_test.go +++ b/src/cmd/go/internal/vcs/discovery_test.go @@ -2,35 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( - "cmd/go/internal/str" "reflect" "strings" "testing" ) -var foldDupTests = []struct { - list []string - f1, f2 string -}{ - {str.StringList("math/rand", "math/big"), "", ""}, - {str.StringList("math", "strings"), "", ""}, - {str.StringList("strings"), "", ""}, - {str.StringList("strings", "strings"), "strings", "strings"}, - {str.StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, -} - -func TestFoldDup(t *testing.T) { - for _, tt := range foldDupTests { - f1, f2 := str.FoldDup(tt.list) - if f1 != tt.f1 || f2 != tt.f2 { - t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) - } - } -} - var parseMetaGoImportsTests = []struct { in string mod ModuleMode diff --git a/src/cmd/go/internal/get/vcs.go b/src/cmd/go/internal/vcs/vcs.go index 24c32935d0..4894ecdc35 100644 --- a/src/cmd/go/internal/get/vcs.go +++ b/src/cmd/go/internal/vcs/vcs.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( "encoding/json" @@ -10,6 +10,7 @@ import ( "fmt" "internal/lazyregexp" "internal/singleflight" + "io/fs" "log" urlpkg "net/url" "os" @@ -21,29 +22,32 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/search" + "cmd/go/internal/str" "cmd/go/internal/web" + + "golang.org/x/mod/module" ) // A vcsCmd describes how to use a version control system // like Mercurial, Git, or Subversion. -type vcsCmd struct { - name string - cmd string // name of binary to invoke command +type Cmd struct { + Name string + Cmd string // name of binary to invoke command - createCmd []string // commands to download a fresh copy of a repository - downloadCmd []string // commands to download updates into an existing repository + CreateCmd []string // commands to download a fresh copy of a repository + DownloadCmd []string // commands to download updates into an existing repository - tagCmd []tagCmd // commands to list tags - tagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd - tagSyncCmd []string // commands to sync to specific tag - tagSyncDefault []string // commands to sync to default tag + TagCmd []tagCmd // commands to list tags + TagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd + TagSyncCmd []string // commands to sync to specific tag + TagSyncDefault []string // commands to sync to default tag - scheme []string - pingCmd string + Scheme []string + PingCmd string - remoteRepo func(v *vcsCmd, rootDir string) (remoteRepo string, err error) - resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error) + RemoteRepo func(v *Cmd, rootDir string) (remoteRepo string, err error) + ResolveRepo func(v *Cmd, rootDir, remoteRepo string) (realRepo string, err error) } var defaultSecureScheme = map[string]bool{ @@ -54,7 +58,7 @@ var defaultSecureScheme = map[string]bool{ "ssh": true, } -func (v *vcsCmd) isSecure(repo string) bool { +func (v *Cmd) IsSecure(repo string) bool { u, err := urlpkg.Parse(repo) if err != nil { // If repo is not a URL, it's not secure. @@ -63,8 +67,8 @@ func (v *vcsCmd) isSecure(repo string) bool { return v.isSecureScheme(u.Scheme) } -func (v *vcsCmd) isSecureScheme(scheme string) bool { - switch v.cmd { +func (v *Cmd) isSecureScheme(scheme string) bool { + switch v.Cmd { case "git": // GIT_ALLOW_PROTOCOL is an environment variable defined by Git. It is a // colon-separated list of schemes that are allowed to be used with git @@ -89,7 +93,7 @@ type tagCmd struct { } // vcsList lists the known version control systems -var vcsList = []*vcsCmd{ +var vcsList = []*Cmd{ vcsHg, vcsGit, vcsSvn, @@ -97,11 +101,15 @@ var vcsList = []*vcsCmd{ vcsFossil, } +// vcsMod is a stub for the "mod" scheme. It's returned by +// repoRootForImportPathDynamic, but is otherwise not treated as a VCS command. +var vcsMod = &Cmd{Name: "mod"} + // vcsByCmd returns the version control system for the given // command name (hg, git, svn, bzr). -func vcsByCmd(cmd string) *vcsCmd { +func vcsByCmd(cmd string) *Cmd { for _, vcs := range vcsList { - if vcs.cmd == cmd { + if vcs.Cmd == cmd { return vcs } } @@ -109,31 +117,31 @@ func vcsByCmd(cmd string) *vcsCmd { } // vcsHg describes how to use Mercurial. -var vcsHg = &vcsCmd{ - name: "Mercurial", - cmd: "hg", +var vcsHg = &Cmd{ + Name: "Mercurial", + Cmd: "hg", - createCmd: []string{"clone -U -- {repo} {dir}"}, - downloadCmd: []string{"pull"}, + CreateCmd: []string{"clone -U -- {repo} {dir}"}, + DownloadCmd: []string{"pull"}, // We allow both tag and branch names as 'tags' // for selecting a version. This lets people have // a go.release.r60 branch and a go1 branch // and make changes in both, without constantly // editing .hgtags. - tagCmd: []tagCmd{ + TagCmd: []tagCmd{ {"tags", `^(\S+)`}, {"branches", `^(\S+)`}, }, - tagSyncCmd: []string{"update -r {tag}"}, - tagSyncDefault: []string{"update default"}, + TagSyncCmd: []string{"update -r {tag}"}, + TagSyncDefault: []string{"update default"}, - scheme: []string{"https", "http", "ssh"}, - pingCmd: "identify -- {scheme}://{repo}", - remoteRepo: hgRemoteRepo, + Scheme: []string{"https", "http", "ssh"}, + PingCmd: "identify -- {scheme}://{repo}", + RemoteRepo: hgRemoteRepo, } -func hgRemoteRepo(vcsHg *vcsCmd, rootDir string) (remoteRepo string, err error) { +func hgRemoteRepo(vcsHg *Cmd, rootDir string) (remoteRepo string, err error) { out, err := vcsHg.runOutput(rootDir, "paths default") if err != nil { return "", err @@ -142,45 +150,45 @@ func hgRemoteRepo(vcsHg *vcsCmd, rootDir string) (remoteRepo string, err error) } // vcsGit describes how to use Git. -var vcsGit = &vcsCmd{ - name: "Git", - cmd: "git", +var vcsGit = &Cmd{ + Name: "Git", + Cmd: "git", - createCmd: []string{"clone -- {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"}, - downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"}, + CreateCmd: []string{"clone -- {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"}, + DownloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"}, - tagCmd: []tagCmd{ + TagCmd: []tagCmd{ // tags/xxx matches a git tag named xxx // origin/xxx matches a git branch named xxx on the default remote repository {"show-ref", `(?:tags|origin)/(\S+)$`}, }, - tagLookupCmd: []tagCmd{ + TagLookupCmd: []tagCmd{ {"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`}, }, - tagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"}, + TagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"}, // both createCmd and downloadCmd update the working dir. // No need to do more here. We used to 'checkout master' // but that doesn't work if the default branch is not named master. // DO NOT add 'checkout master' here. // See golang.org/issue/9032. - tagSyncDefault: []string{"submodule update --init --recursive"}, + TagSyncDefault: []string{"submodule update --init --recursive"}, - scheme: []string{"git", "https", "http", "git+ssh", "ssh"}, + Scheme: []string{"git", "https", "http", "git+ssh", "ssh"}, // Leave out the '--' separator in the ls-remote command: git 2.7.4 does not // support such a separator for that command, and this use should be safe // without it because the {scheme} value comes from the predefined list above. // See golang.org/issue/33836. - pingCmd: "ls-remote {scheme}://{repo}", + PingCmd: "ls-remote {scheme}://{repo}", - remoteRepo: gitRemoteRepo, + RemoteRepo: gitRemoteRepo, } // scpSyntaxRe matches the SCP-like addresses used by Git to access // repositories by SSH. var scpSyntaxRe = lazyregexp.New(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) -func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error) { +func gitRemoteRepo(vcsGit *Cmd, rootDir string) (remoteRepo string, err error) { cmd := "config remote.origin.url" errParse := errors.New("unable to parse output of git " + cmd) errRemoteOriginNotFound := errors.New("remote origin not found") @@ -216,7 +224,7 @@ func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error // Iterate over insecure schemes too, because this function simply // reports the state of the repo. If we can't see insecure schemes then // we can't report the actual repo URL. - for _, s := range vcsGit.scheme { + for _, s := range vcsGit.Scheme { if repoURL.Scheme == s { return repoURL.String(), nil } @@ -225,27 +233,27 @@ func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error } // vcsBzr describes how to use Bazaar. -var vcsBzr = &vcsCmd{ - name: "Bazaar", - cmd: "bzr", +var vcsBzr = &Cmd{ + Name: "Bazaar", + Cmd: "bzr", - createCmd: []string{"branch -- {repo} {dir}"}, + CreateCmd: []string{"branch -- {repo} {dir}"}, // Without --overwrite bzr will not pull tags that changed. // Replace by --overwrite-tags after http://pad.lv/681792 goes in. - downloadCmd: []string{"pull --overwrite"}, + DownloadCmd: []string{"pull --overwrite"}, - tagCmd: []tagCmd{{"tags", `^(\S+)`}}, - tagSyncCmd: []string{"update -r {tag}"}, - tagSyncDefault: []string{"update -r revno:-1"}, + TagCmd: []tagCmd{{"tags", `^(\S+)`}}, + TagSyncCmd: []string{"update -r {tag}"}, + TagSyncDefault: []string{"update -r revno:-1"}, - scheme: []string{"https", "http", "bzr", "bzr+ssh"}, - pingCmd: "info -- {scheme}://{repo}", - remoteRepo: bzrRemoteRepo, - resolveRepo: bzrResolveRepo, + Scheme: []string{"https", "http", "bzr", "bzr+ssh"}, + PingCmd: "info -- {scheme}://{repo}", + RemoteRepo: bzrRemoteRepo, + ResolveRepo: bzrResolveRepo, } -func bzrRemoteRepo(vcsBzr *vcsCmd, rootDir string) (remoteRepo string, err error) { +func bzrRemoteRepo(vcsBzr *Cmd, rootDir string) (remoteRepo string, err error) { outb, err := vcsBzr.runOutput(rootDir, "config parent_location") if err != nil { return "", err @@ -253,7 +261,7 @@ func bzrRemoteRepo(vcsBzr *vcsCmd, rootDir string) (remoteRepo string, err error return strings.TrimSpace(string(outb)), nil } -func bzrResolveRepo(vcsBzr *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error) { +func bzrResolveRepo(vcsBzr *Cmd, rootDir, remoteRepo string) (realRepo string, err error) { outb, err := vcsBzr.runOutput(rootDir, "info "+remoteRepo) if err != nil { return "", err @@ -287,22 +295,22 @@ func bzrResolveRepo(vcsBzr *vcsCmd, rootDir, remoteRepo string) (realRepo string } // vcsSvn describes how to use Subversion. -var vcsSvn = &vcsCmd{ - name: "Subversion", - cmd: "svn", +var vcsSvn = &Cmd{ + Name: "Subversion", + Cmd: "svn", - createCmd: []string{"checkout -- {repo} {dir}"}, - downloadCmd: []string{"update"}, + CreateCmd: []string{"checkout -- {repo} {dir}"}, + DownloadCmd: []string{"update"}, // There is no tag command in subversion. // The branch information is all in the path names. - scheme: []string{"https", "http", "svn", "svn+ssh"}, - pingCmd: "info -- {scheme}://{repo}", - remoteRepo: svnRemoteRepo, + Scheme: []string{"https", "http", "svn", "svn+ssh"}, + PingCmd: "info -- {scheme}://{repo}", + RemoteRepo: svnRemoteRepo, } -func svnRemoteRepo(vcsSvn *vcsCmd, rootDir string) (remoteRepo string, err error) { +func svnRemoteRepo(vcsSvn *Cmd, rootDir string) (remoteRepo string, err error) { outb, err := vcsSvn.runOutput(rootDir, "info") if err != nil { return "", err @@ -337,22 +345,22 @@ func svnRemoteRepo(vcsSvn *vcsCmd, rootDir string) (remoteRepo string, err error const fossilRepoName = ".fossil" // vcsFossil describes how to use Fossil (fossil-scm.org) -var vcsFossil = &vcsCmd{ - name: "Fossil", - cmd: "fossil", +var vcsFossil = &Cmd{ + Name: "Fossil", + Cmd: "fossil", - createCmd: []string{"-go-internal-mkdir {dir} clone -- {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"}, - downloadCmd: []string{"up"}, + CreateCmd: []string{"-go-internal-mkdir {dir} clone -- {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"}, + DownloadCmd: []string{"up"}, - tagCmd: []tagCmd{{"tag ls", `(.*)`}}, - tagSyncCmd: []string{"up tag:{tag}"}, - tagSyncDefault: []string{"up trunk"}, + TagCmd: []tagCmd{{"tag ls", `(.*)`}}, + TagSyncCmd: []string{"up tag:{tag}"}, + TagSyncDefault: []string{"up trunk"}, - scheme: []string{"https", "http"}, - remoteRepo: fossilRemoteRepo, + Scheme: []string{"https", "http"}, + RemoteRepo: fossilRemoteRepo, } -func fossilRemoteRepo(vcsFossil *vcsCmd, rootDir string) (remoteRepo string, err error) { +func fossilRemoteRepo(vcsFossil *Cmd, rootDir string) (remoteRepo string, err error) { out, err := vcsFossil.runOutput(rootDir, "remote-url") if err != nil { return "", err @@ -360,8 +368,8 @@ func fossilRemoteRepo(vcsFossil *vcsCmd, rootDir string) (remoteRepo string, err return strings.TrimSpace(string(out)), nil } -func (v *vcsCmd) String() string { - return v.name +func (v *Cmd) String() string { + return v.Name } // run runs the command line cmd in the given directory. @@ -371,24 +379,24 @@ func (v *vcsCmd) String() string { // If an error occurs, run prints the command line and the // command's combined stdout+stderr to standard error. // Otherwise run discards the command's output. -func (v *vcsCmd) run(dir string, cmd string, keyval ...string) error { +func (v *Cmd) run(dir string, cmd string, keyval ...string) error { _, err := v.run1(dir, cmd, keyval, true) return err } // runVerboseOnly is like run but only generates error output to standard error in verbose mode. -func (v *vcsCmd) runVerboseOnly(dir string, cmd string, keyval ...string) error { +func (v *Cmd) runVerboseOnly(dir string, cmd string, keyval ...string) error { _, err := v.run1(dir, cmd, keyval, false) return err } // runOutput is like run but returns the output of the command. -func (v *vcsCmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) { +func (v *Cmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) { return v.run1(dir, cmd, keyval, true) } // run1 is the generalized implementation of run and runOutput. -func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) { +func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) { m := make(map[string]string) for i := 0; i < len(keyval); i += 2 { m[keyval[i]] = keyval[i+1] @@ -401,9 +409,9 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) if len(args) >= 2 && args[0] == "-go-internal-mkdir" { var err error if filepath.IsAbs(args[1]) { - err = os.Mkdir(args[1], os.ModePerm) + err = os.Mkdir(args[1], fs.ModePerm) } else { - err = os.Mkdir(filepath.Join(dir, args[1]), os.ModePerm) + err = os.Mkdir(filepath.Join(dir, args[1]), fs.ModePerm) } if err != nil { return nil, err @@ -420,25 +428,25 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) args = args[2:] } - _, err := exec.LookPath(v.cmd) + _, err := exec.LookPath(v.Cmd) if err != nil { fmt.Fprintf(os.Stderr, "go: missing %s command. See https://golang.org/s/gogetcmd\n", - v.name) + v.Name) return nil, err } - cmd := exec.Command(v.cmd, args...) + cmd := exec.Command(v.Cmd, args...) cmd.Dir = dir cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) if cfg.BuildX { fmt.Fprintf(os.Stderr, "cd %s\n", dir) - fmt.Fprintf(os.Stderr, "%s %s\n", v.cmd, strings.Join(args, " ")) + fmt.Fprintf(os.Stderr, "%s %s\n", v.Cmd, strings.Join(args, " ")) } out, err := cmd.Output() if err != nil { if verbose || cfg.BuildV { - fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " ")) + fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.Cmd, strings.Join(args, " ")) if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { os.Stderr.Write(ee.Stderr) } else { @@ -449,15 +457,15 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) return out, err } -// ping pings to determine scheme to use. -func (v *vcsCmd) ping(scheme, repo string) error { - return v.runVerboseOnly(".", v.pingCmd, "scheme", scheme, "repo", repo) +// Ping pings to determine scheme to use. +func (v *Cmd) Ping(scheme, repo string) error { + return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo) } -// create creates a new copy of repo in dir. +// Create creates a new copy of repo in dir. // The parent of dir must exist; dir must not. -func (v *vcsCmd) create(dir, repo string) error { - for _, cmd := range v.createCmd { +func (v *Cmd) Create(dir, repo string) error { + for _, cmd := range v.CreateCmd { if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil { return err } @@ -465,9 +473,9 @@ func (v *vcsCmd) create(dir, repo string) error { return nil } -// download downloads any new changes for the repo in dir. -func (v *vcsCmd) download(dir string) error { - for _, cmd := range v.downloadCmd { +// Download downloads any new changes for the repo in dir. +func (v *Cmd) Download(dir string) error { + for _, cmd := range v.DownloadCmd { if err := v.run(dir, cmd); err != nil { return err } @@ -475,10 +483,10 @@ func (v *vcsCmd) download(dir string) error { return nil } -// tags returns the list of available tags for the repo in dir. -func (v *vcsCmd) tags(dir string) ([]string, error) { +// Tags returns the list of available tags for the repo in dir. +func (v *Cmd) Tags(dir string) ([]string, error) { var tags []string - for _, tc := range v.tagCmd { + for _, tc := range v.TagCmd { out, err := v.runOutput(dir, tc.cmd) if err != nil { return nil, err @@ -493,12 +501,12 @@ func (v *vcsCmd) tags(dir string) ([]string, error) { // tagSync syncs the repo in dir to the named tag, // which either is a tag returned by tags or is v.tagDefault. -func (v *vcsCmd) tagSync(dir, tag string) error { - if v.tagSyncCmd == nil { +func (v *Cmd) TagSync(dir, tag string) error { + if v.TagSyncCmd == nil { return nil } if tag != "" { - for _, tc := range v.tagLookupCmd { + for _, tc := range v.TagLookupCmd { out, err := v.runOutput(dir, tc.cmd, "tag", tag) if err != nil { return err @@ -512,8 +520,8 @@ func (v *vcsCmd) tagSync(dir, tag string) error { } } - if tag == "" && v.tagSyncDefault != nil { - for _, cmd := range v.tagSyncDefault { + if tag == "" && v.TagSyncDefault != nil { + for _, cmd := range v.TagSyncDefault { if err := v.run(dir, cmd); err != nil { return err } @@ -521,7 +529,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error { return nil } - for _, cmd := range v.tagSyncCmd { + for _, cmd := range v.TagSyncCmd { if err := v.run(dir, cmd, "tag", tag); err != nil { return err } @@ -532,7 +540,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error { // A vcsPath describes how to convert an import path into a // version control system and repository name. type vcsPath struct { - prefix string // prefix this description applies to + pathPrefix string // prefix this description applies to regexp *lazyregexp.Regexp // compiled pattern for import path repo string // repository to use (expand with match of re) vcs string // version control system to use (expand with match of re) @@ -540,11 +548,11 @@ type vcsPath struct { schemelessRepo bool // if true, the repo pattern lacks a scheme } -// vcsFromDir inspects dir and its parents to determine the +// FromDir inspects dir and its parents to determine the // version control system and code repository to use. // On return, root is the import path // corresponding to the root of the repository. -func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { +func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) { // Clean and double-check that dir is in (a subdirectory of) srcRoot. dir = filepath.Clean(dir) srcRoot = filepath.Clean(srcRoot) @@ -552,13 +560,13 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot) } - var vcsRet *vcsCmd + var vcsRet *Cmd var rootRet string origDir := dir for len(dir) > len(srcRoot) { for _, vcs := range vcsList { - if _, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil { + if _, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil { root := filepath.ToSlash(dir[len(srcRoot)+1:]) // Record first VCS we find, but keep looking, // to detect mistakes like one kind of VCS inside another. @@ -568,12 +576,12 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { continue } // Allow .git inside .git, which can arise due to submodules. - if vcsRet == vcs && vcs.cmd == "git" { + if vcsRet == vcs && vcs.Cmd == "git" { continue } // Otherwise, we have one VCS inside a different VCS. return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s", - filepath.Join(srcRoot, rootRet), vcsRet.cmd, filepath.Join(srcRoot, root), vcs.cmd) + filepath.Join(srcRoot, rootRet), vcsRet.Cmd, filepath.Join(srcRoot, root), vcs.Cmd) } } @@ -587,15 +595,149 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { } if vcsRet != nil { + if err := checkGOVCS(vcsRet, rootRet); err != nil { + return nil, "", err + } return vcsRet, rootRet, nil } return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir) } -// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS +// A govcsRule is a single GOVCS rule like private:hg|svn. +type govcsRule struct { + pattern string + allowed []string +} + +// A govcsConfig is a full GOVCS configuration. +type govcsConfig []govcsRule + +func parseGOVCS(s string) (govcsConfig, error) { + s = strings.TrimSpace(s) + if s == "" { + return nil, nil + } + var cfg govcsConfig + have := make(map[string]string) + for _, item := range strings.Split(s, ",") { + item = strings.TrimSpace(item) + if item == "" { + return nil, fmt.Errorf("empty entry in GOVCS") + } + i := strings.Index(item, ":") + if i < 0 { + return nil, fmt.Errorf("malformed entry in GOVCS (missing colon): %q", item) + } + pattern, list := strings.TrimSpace(item[:i]), strings.TrimSpace(item[i+1:]) + if pattern == "" { + return nil, fmt.Errorf("empty pattern in GOVCS: %q", item) + } + if list == "" { + return nil, fmt.Errorf("empty VCS list in GOVCS: %q", item) + } + if search.IsRelativePath(pattern) { + return nil, fmt.Errorf("relative pattern not allowed in GOVCS: %q", pattern) + } + if old := have[pattern]; old != "" { + return nil, fmt.Errorf("unreachable pattern in GOVCS: %q after %q", item, old) + } + have[pattern] = item + allowed := strings.Split(list, "|") + for i, a := range allowed { + a = strings.TrimSpace(a) + if a == "" { + return nil, fmt.Errorf("empty VCS name in GOVCS: %q", item) + } + allowed[i] = a + } + cfg = append(cfg, govcsRule{pattern, allowed}) + } + return cfg, nil +} + +func (c *govcsConfig) allow(path string, private bool, vcs string) bool { + for _, rule := range *c { + match := false + switch rule.pattern { + case "private": + match = private + case "public": + match = !private + default: + // Note: rule.pattern is known to be comma-free, + // so MatchPrefixPatterns is only matching a single pattern for us. + match = module.MatchPrefixPatterns(rule.pattern, path) + } + if !match { + continue + } + for _, allow := range rule.allowed { + if allow == vcs || allow == "all" { + return true + } + } + return false + } + + // By default, nothing is allowed. + return false +} + +var ( + govcs govcsConfig + govcsErr error + govcsOnce sync.Once +) + +// defaultGOVCS is the default setting for GOVCS. +// Setting GOVCS adds entries ahead of these but does not remove them. +// (They are appended to the parsed GOVCS setting.) +// +// The rationale behind allowing only Git and Mercurial is that +// these two systems have had the most attention to issues +// of being run as clients of untrusted servers. In contrast, +// Bazaar, Fossil, and Subversion have primarily been used +// in trusted, authenticated environments and are not as well +// scrutinized as attack surfaces. +// +// See golang.org/issue/41730 for details. +var defaultGOVCS = govcsConfig{ + {"private", []string{"all"}}, + {"public", []string{"git", "hg"}}, +} + +func checkGOVCS(vcs *Cmd, root string) error { + if vcs == vcsMod { + // Direct module (proxy protocol) fetches don't + // involve an external version control system + // and are always allowed. + return nil + } + + govcsOnce.Do(func() { + govcs, govcsErr = parseGOVCS(os.Getenv("GOVCS")) + govcs = append(govcs, defaultGOVCS...) + }) + if govcsErr != nil { + return govcsErr + } + + private := module.MatchPrefixPatterns(cfg.GOPRIVATE, root) + if !govcs.allow(root, private, vcs.Cmd) { + what := "public" + if private { + what = "private" + } + return fmt.Errorf("GOVCS disallows using %s for %s %s", vcs.Cmd, what, root) + } + + return nil +} + +// CheckNested checks for an incorrectly-nested VCS-inside-VCS // situation for dir, checking parents up until srcRoot. -func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error { +func CheckNested(vcs *Cmd, dir, srcRoot string) error { if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator { return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot) } @@ -603,17 +745,17 @@ func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error { otherDir := dir for len(otherDir) > len(srcRoot) { for _, otherVCS := range vcsList { - if _, err := os.Stat(filepath.Join(otherDir, "."+otherVCS.cmd)); err == nil { + if _, err := os.Stat(filepath.Join(otherDir, "."+otherVCS.Cmd)); err == nil { // Allow expected vcs in original dir. if otherDir == dir && otherVCS == vcs { continue } // Allow .git inside .git, which can arise due to submodules. - if otherVCS == vcs && vcs.cmd == "git" { + if otherVCS == vcs && vcs.Cmd == "git" { continue } // Otherwise, we have one VCS inside a different VCS. - return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.cmd, otherDir, otherVCS.cmd) + return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd) } } // Move to parent. @@ -633,9 +775,7 @@ type RepoRoot struct { Repo string // repository URL, including scheme Root string // import path corresponding to root of repo IsCustom bool // defined by served <meta> tags (as opposed to hard-coded pattern) - VCS string // vcs type ("mod", "git", ...) - - vcs *vcsCmd // internal: vcs command access + VCS *Cmd } func httpPrefix(s string) string { @@ -662,7 +802,7 @@ func RepoRootForImportPath(importPath string, mod ModuleMode, security web.Secur if err == errUnknownSite { rr, err = repoRootForImportDynamic(importPath, mod, security) if err != nil { - err = load.ImportErrorf(importPath, "unrecognized import path %q: %v", importPath, err) + err = importErrorf(importPath, "unrecognized import path %q: %v", importPath, err) } } if err != nil { @@ -677,7 +817,7 @@ func RepoRootForImportPath(importPath string, mod ModuleMode, security web.Secur if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") { // Do not allow wildcards in the repo root. rr = nil - err = load.ImportErrorf(importPath, "cannot expand ... in %q", importPath) + err = importErrorf(importPath, "cannot expand ... in %q", importPath) } return rr, err } @@ -687,6 +827,20 @@ var errUnknownSite = errors.New("dynamic lookup required to find mapping") // repoRootFromVCSPaths attempts to map importPath to a repoRoot // using the mappings defined in vcsPaths. func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths []*vcsPath) (*RepoRoot, error) { + if str.HasPathPrefix(importPath, "example.net") { + // TODO(rsc): This should not be necessary, but it's required to keep + // tests like ../../testdata/script/mod_get_extra.txt from using the network. + // That script has everything it needs in the replacement set, but it is still + // doing network calls. + return nil, fmt.Errorf("no modules on example.net") + } + if importPath == "rsc.io" { + // This special case allows tests like ../../testdata/script/govcs.txt + // to avoid making any network calls. The module lookup for a path + // like rsc.io/nonexist.svn/foo needs to not make a network call for + // a lookup on rsc.io. + return nil, fmt.Errorf("rsc.io is not a module") + } // A common error is to use https://packagepath because that's what // hg and git require. Diagnose this helpfully. if prefix := httpPrefix(importPath); prefix != "" { @@ -695,20 +849,20 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths return nil, fmt.Errorf("%q not allowed in import path", prefix+"//") } for _, srv := range vcsPaths { - if !strings.HasPrefix(importPath, srv.prefix) { + if !str.HasPathPrefix(importPath, srv.pathPrefix) { continue } m := srv.regexp.FindStringSubmatch(importPath) if m == nil { - if srv.prefix != "" { - return nil, load.ImportErrorf(importPath, "invalid %s import path %q", srv.prefix, importPath) + if srv.pathPrefix != "" { + return nil, importErrorf(importPath, "invalid %s import path %q", srv.pathPrefix, importPath) } continue } // Build map of named subexpression matches for expand. match := map[string]string{ - "prefix": srv.prefix, + "prefix": srv.pathPrefix + "/", "import": importPath, } for i, name := range srv.regexp.SubexpNames() { @@ -731,19 +885,22 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths if vcs == nil { return nil, fmt.Errorf("unknown version control system %q", match["vcs"]) } + if err := checkGOVCS(vcs, match["root"]); err != nil { + return nil, err + } var repoURL string if !srv.schemelessRepo { repoURL = match["repo"] } else { - scheme := vcs.scheme[0] // default to first scheme + scheme := vcs.Scheme[0] // default to first scheme repo := match["repo"] - if vcs.pingCmd != "" { + if vcs.PingCmd != "" { // If we know how to test schemes, scan to find one. - for _, s := range vcs.scheme { + for _, s := range vcs.Scheme { if security == web.SecureOnly && !vcs.isSecureScheme(s) { continue } - if vcs.ping(s, repo) == nil { + if vcs.Ping(s, repo) == nil { scheme = s break } @@ -754,8 +911,7 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths rr := &RepoRoot{ Repo: repoURL, Root: match["root"], - VCS: vcs.cmd, - vcs: vcs, + VCS: vcs, } return rr, nil } @@ -846,17 +1002,25 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se if err := validateRepoRoot(mmi.RepoRoot); err != nil { return nil, fmt.Errorf("%s: invalid repo root %q: %v", resp.URL, mmi.RepoRoot, err) } - vcs := vcsByCmd(mmi.VCS) - if vcs == nil && mmi.VCS != "mod" { - return nil, fmt.Errorf("%s: unknown vcs %q", resp.URL, mmi.VCS) + var vcs *Cmd + if mmi.VCS == "mod" { + vcs = vcsMod + } else { + vcs = vcsByCmd(mmi.VCS) + if vcs == nil { + return nil, fmt.Errorf("%s: unknown vcs %q", resp.URL, mmi.VCS) + } + } + + if err := checkGOVCS(vcs, mmi.Prefix); err != nil { + return nil, err } rr := &RepoRoot{ Repo: mmi.RepoRoot, Root: mmi.Prefix, IsCustom: true, - VCS: mmi.VCS, - vcs: vcs, + VCS: vcs, } return rr, nil } @@ -949,18 +1113,6 @@ type metaImport struct { Prefix, VCS, RepoRoot string } -// pathPrefix reports whether sub is a prefix of s, -// only considering entire path components. -func pathPrefix(s, sub string) bool { - // strings.HasPrefix is necessary but not sufficient. - if !strings.HasPrefix(s, sub) { - return false - } - // The remainder after the prefix must either be empty or start with a slash. - rem := s[len(sub):] - return rem == "" || rem[0] == '/' -} - // A ImportMismatchError is returned where metaImport/s are present // but none match our import path. type ImportMismatchError struct { @@ -984,7 +1136,7 @@ func matchGoImport(imports []metaImport, importPath string) (metaImport, error) errImportMismatch := ImportMismatchError{importPath: importPath} for i, im := range imports { - if !pathPrefix(importPath, im.Prefix) { + if !str.HasPathPrefix(importPath, im.Prefix) { errImportMismatch.mismatches = append(errImportMismatch.mismatches, im.Prefix) continue } @@ -1026,52 +1178,52 @@ func expand(match map[string]string, s string) string { var vcsPaths = []*vcsPath{ // Github { - prefix: "github.com/", - regexp: lazyregexp.New(`^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", - check: noVCSSuffix, + pathPrefix: "github.com", + regexp: lazyregexp.New(`^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", + check: noVCSSuffix, }, // Bitbucket { - prefix: "bitbucket.org/", - regexp: lazyregexp.New(`^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), - repo: "https://{root}", - check: bitbucketVCS, + pathPrefix: "bitbucket.org", + regexp: lazyregexp.New(`^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), + repo: "https://{root}", + check: bitbucketVCS, }, // IBM DevOps Services (JazzHub) { - prefix: "hub.jazz.net/git/", - regexp: lazyregexp.New(`^(?P<root>hub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", - check: noVCSSuffix, + pathPrefix: "hub.jazz.net/git", + regexp: lazyregexp.New(`^(?P<root>hub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", + check: noVCSSuffix, }, // Git at Apache { - prefix: "git.apache.org/", - regexp: lazyregexp.New(`^(?P<root>git\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", + pathPrefix: "git.apache.org", + regexp: lazyregexp.New(`^(?P<root>git\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", }, // Git at OpenStack { - prefix: "git.openstack.org/", - regexp: lazyregexp.New(`^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", + pathPrefix: "git.openstack.org", + regexp: lazyregexp.New(`^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", }, // chiselapp.com for fossil { - prefix: "chiselapp.com/", - regexp: lazyregexp.New(`^(?P<root>chiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`), - vcs: "fossil", - repo: "https://{root}", + pathPrefix: "chiselapp.com", + regexp: lazyregexp.New(`^(?P<root>chiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`), + vcs: "fossil", + repo: "https://{root}", }, // General syntax for any server. @@ -1089,11 +1241,11 @@ var vcsPaths = []*vcsPath{ var vcsPathsAfterDynamic = []*vcsPath{ // Launchpad. See golang.org/issue/11436. { - prefix: "launchpad.net/", - regexp: lazyregexp.New(`^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), - vcs: "bzr", - repo: "https://{root}", - check: launchpadVCS, + pathPrefix: "launchpad.net", + regexp: lazyregexp.New(`^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), + vcs: "bzr", + repo: "https://{root}", + check: launchpadVCS, }, } @@ -1103,7 +1255,7 @@ var vcsPathsAfterDynamic = []*vcsPath{ func noVCSSuffix(match map[string]string) error { repo := match["repo"] for _, vcs := range vcsList { - if strings.HasSuffix(repo, "."+vcs.cmd) { + if strings.HasSuffix(repo, "."+vcs.Cmd) { return fmt.Errorf("invalid version control suffix in %s path", match["prefix"]) } } @@ -1133,7 +1285,7 @@ func bitbucketVCS(match map[string]string) error { // VCS it uses. See issue 5375. root := match["root"] for _, vcs := range []string{"git", "hg"} { - if vcsByCmd(vcs).ping("https", root) == nil { + if vcsByCmd(vcs).Ping("https", root) == nil { resp.SCM = vcs break } @@ -1180,3 +1332,32 @@ func launchpadVCS(match map[string]string) error { } return nil } + +// importError is a copy of load.importError, made to avoid a dependency cycle +// on cmd/go/internal/load. It just needs to satisfy load.ImportPathError. +type importError struct { + importPath string + err error +} + +func importErrorf(path, format string, args ...interface{}) error { + err := &importError{importPath: path, err: fmt.Errorf(format, args...)} + if errStr := err.Error(); !strings.Contains(errStr, path) { + panic(fmt.Sprintf("path %q not in error %q", path, errStr)) + } + return err +} + +func (e *importError) Error() string { + return e.err.Error() +} + +func (e *importError) Unwrap() error { + // Don't return e.err directly, since we're only wrapping an error if %w + // was passed to ImportErrorf. + return errors.Unwrap(e.err) +} + +func (e *importError) ImportPath() string { + return e.importPath +} diff --git a/src/cmd/go/internal/get/vcs_test.go b/src/cmd/go/internal/vcs/vcs_test.go index 195bc231eb..c5c7a3283b 100644 --- a/src/cmd/go/internal/get/vcs_test.go +++ b/src/cmd/go/internal/vcs/vcs_test.go @@ -2,20 +2,28 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( "errors" "internal/testenv" - "io/ioutil" "os" "path" "path/filepath" + "strings" "testing" "cmd/go/internal/web" ) +func init() { + // GOVCS defaults to public:git|hg,private:all, + // which breaks many tests here - they can't use non-git, non-hg VCS at all! + // Change to fully permissive. + // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt. + os.Setenv("GOVCS", "*:all") +} + // Test that RepoRootForImportPath determines the correct RepoRoot for a given importPath. // TODO(cmang): Add tests for SVN and BZR. func TestRepoRootForImportPath(t *testing.T) { @@ -28,7 +36,7 @@ func TestRepoRootForImportPath(t *testing.T) { { "github.com/golang/groupcache", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://github.com/golang/groupcache", }, }, @@ -41,14 +49,14 @@ func TestRepoRootForImportPath(t *testing.T) { { "hub.jazz.net/git/user1/pkgname", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user1/pkgname", }, }, { "hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user1/pkgname", }, }, @@ -89,7 +97,7 @@ func TestRepoRootForImportPath(t *testing.T) { { "hub.jazz.net/git/user/pkg.name", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user/pkg.name", }, }, @@ -102,7 +110,7 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.openstack.org/openstack/swift", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift", }, }, @@ -112,14 +120,14 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.openstack.org/openstack/swift.git", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift.git", }, }, { "git.openstack.org/openstack/swift/go/hummingbird", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift", }, }, @@ -148,21 +156,21 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.apache.org/package-name.git", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.apache.org/package-name.git", }, }, { "git.apache.org/package-name_2.x.git/path/to/lib", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.apache.org/package-name_2.x.git", }, }, { "chiselapp.com/user/kyle/repository/fossilgg", &RepoRoot{ - vcs: vcsFossil, + VCS: vcsFossil, Repo: "https://chiselapp.com/user/kyle/repository/fossilgg", }, }, @@ -191,22 +199,22 @@ func TestRepoRootForImportPath(t *testing.T) { t.Errorf("RepoRootForImportPath(%q): %v", test.path, err) continue } - if got.vcs.name != want.vcs.name || got.Repo != want.Repo { - t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.Repo, want.vcs, want.Repo) + if got.VCS.Name != want.VCS.Name || got.Repo != want.Repo { + t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.VCS, got.Repo, want.VCS, want.Repo) } } } // Test that vcsFromDir correctly inspects a given directory and returns the right VCS and root. func TestFromDir(t *testing.T) { - tempDir, err := ioutil.TempDir("", "vcstest") + tempDir, err := os.MkdirTemp("", "vcstest") if err != nil { t.Fatal(err) } defer os.RemoveAll(tempDir) for j, vcs := range vcsList { - dir := filepath.Join(tempDir, "example.com", vcs.name, "."+vcs.cmd) + dir := filepath.Join(tempDir, "example.com", vcs.Name, "."+vcs.Cmd) if j&1 == 0 { err := os.MkdirAll(dir, 0755) if err != nil { @@ -225,24 +233,24 @@ func TestFromDir(t *testing.T) { } want := RepoRoot{ - vcs: vcs, - Root: path.Join("example.com", vcs.name), + VCS: vcs, + Root: path.Join("example.com", vcs.Name), } var got RepoRoot - got.vcs, got.Root, err = vcsFromDir(dir, tempDir) + got.VCS, got.Root, err = FromDir(dir, tempDir) if err != nil { t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err) continue } - if got.vcs.name != want.vcs.name || got.Root != want.Root { - t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.vcs, got.Root, want.vcs, want.Root) + if got.VCS.Name != want.VCS.Name || got.Root != want.Root { + t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.VCS, got.Root, want.VCS, want.Root) } } } func TestIsSecure(t *testing.T) { tests := []struct { - vcs *vcsCmd + vcs *Cmd url string secure bool }{ @@ -267,7 +275,7 @@ func TestIsSecure(t *testing.T) { } for _, test := range tests { - secure := test.vcs.isSecure(test.url) + secure := test.vcs.IsSecure(test.url) if secure != test.secure { t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure, test.secure) } @@ -276,7 +284,7 @@ func TestIsSecure(t *testing.T) { func TestIsSecureGitAllowProtocol(t *testing.T) { tests := []struct { - vcs *vcsCmd + vcs *Cmd url string secure bool }{ @@ -307,7 +315,7 @@ func TestIsSecureGitAllowProtocol(t *testing.T) { defer os.Unsetenv("GIT_ALLOW_PROTOCOL") os.Setenv("GIT_ALLOW_PROTOCOL", "https:foo") for _, test := range tests { - secure := test.vcs.isSecure(test.url) + secure := test.vcs.IsSecure(test.url) if secure != test.secure { t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure, test.secure) } @@ -473,3 +481,98 @@ func TestValidateRepoRoot(t *testing.T) { } } } + +var govcsTests = []struct { + govcs string + path string + vcs string + ok bool +}{ + {"private:all", "is-public.com/foo", "zzz", false}, + {"private:all", "is-private.com/foo", "zzz", true}, + {"public:all", "is-public.com/foo", "zzz", true}, + {"public:all", "is-private.com/foo", "zzz", false}, + {"public:all,private:none", "is-public.com/foo", "zzz", true}, + {"public:all,private:none", "is-private.com/foo", "zzz", false}, + {"*:all", "is-public.com/foo", "zzz", true}, + {"golang.org:git", "golang.org/x/text", "zzz", false}, + {"golang.org:git", "golang.org/x/text", "git", true}, + {"golang.org:zzz", "golang.org/x/text", "zzz", true}, + {"golang.org:zzz", "golang.org/x/text", "git", false}, + {"golang.org:zzz", "golang.org/x/text", "zzz", true}, + {"golang.org:zzz", "golang.org/x/text", "git", false}, + {"golang.org:git|hg", "golang.org/x/text", "hg", true}, + {"golang.org:git|hg", "golang.org/x/text", "git", true}, + {"golang.org:git|hg", "golang.org/x/text", "zzz", false}, + {"golang.org:all", "golang.org/x/text", "hg", true}, + {"golang.org:all", "golang.org/x/text", "git", true}, + {"golang.org:all", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:git", "other.xyz/p/x", "git", false}, + {"other.xyz/p:none,golang.org/x:git", "unexpected.com", "git", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/x/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/x/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "hg", true}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "hg", true}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "hg", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "hg", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "zzz", false}, +} + +func TestGOVCS(t *testing.T) { + for _, tt := range govcsTests { + cfg, err := parseGOVCS(tt.govcs) + if err != nil { + t.Errorf("parseGOVCS(%q): %v", tt.govcs, err) + continue + } + private := strings.HasPrefix(tt.path, "is-private") + ok := cfg.allow(tt.path, private, tt.vcs) + if ok != tt.ok { + t.Errorf("parseGOVCS(%q).allow(%q, %v, %q) = %v, want %v", + tt.govcs, tt.path, private, tt.vcs, ok, tt.ok) + } + } +} + +var govcsErrors = []struct { + s string + err string +}{ + {`,`, `empty entry in GOVCS`}, + {`,x`, `empty entry in GOVCS`}, + {`x,`, `malformed entry in GOVCS (missing colon): "x"`}, + {`x:y,`, `empty entry in GOVCS`}, + {`x`, `malformed entry in GOVCS (missing colon): "x"`}, + {`x:`, `empty VCS list in GOVCS: "x:"`}, + {`x:|`, `empty VCS name in GOVCS: "x:|"`}, + {`x:y|`, `empty VCS name in GOVCS: "x:y|"`}, + {`x:|y`, `empty VCS name in GOVCS: "x:|y"`}, + {`x:y,z:`, `empty VCS list in GOVCS: "z:"`}, + {`x:y,z:|`, `empty VCS name in GOVCS: "z:|"`}, + {`x:y,z:|w`, `empty VCS name in GOVCS: "z:|w"`}, + {`x:y,z:w|`, `empty VCS name in GOVCS: "z:w|"`}, + {`x:y,z:w||v`, `empty VCS name in GOVCS: "z:w||v"`}, + {`x:y,x:z`, `unreachable pattern in GOVCS: "x:z" after "x:y"`}, +} + +func TestGOVCSErrors(t *testing.T) { + for _, tt := range govcsErrors { + _, err := parseGOVCS(tt.s) + if err == nil || !strings.Contains(err.Error(), tt.err) { + t.Errorf("parseGOVCS(%s): err=%v, want %v", tt.s, err, tt.err) + } + } +} diff --git a/src/cmd/go/internal/version/version.go b/src/cmd/go/internal/version/version.go index c2de8d326d..58cbd32e78 100644 --- a/src/cmd/go/internal/version/version.go +++ b/src/cmd/go/internal/version/version.go @@ -10,6 +10,7 @@ import ( "context" "encoding/binary" "fmt" + "io/fs" "os" "path/filepath" "runtime" @@ -54,7 +55,14 @@ var ( func runVersion(ctx context.Context, cmd *base.Command, args []string) { if len(args) == 0 { - if *versionM || *versionV { + // If any of this command's flags were passed explicitly, error + // out, because they only make sense with arguments. + // + // Don't error if the flags came from GOFLAGS, since that can be + // a reasonable use case. For example, imagine GOFLAGS=-v to + // turn "verbose mode" on for all Go commands, which should not + // break "go version". + if (!base.InGOFLAGS("-m") && *versionM) || (!base.InGOFLAGS("-v") && *versionV) { fmt.Fprintf(os.Stderr, "go version: flags can only be used with arguments\n") base.SetExitStatus(2) return @@ -80,8 +88,15 @@ func runVersion(ctx context.Context, cmd *base.Command, args []string) { // scanDir scans a directory for executables to run scanFile on. func scanDir(dir string) { - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 { + filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 { + info, err := d.Info() + if err != nil { + if *versionV { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + } + return nil + } scanFile(path, info, *versionV) } return nil @@ -89,7 +104,7 @@ func scanDir(dir string) { } // isExe reports whether the file should be considered executable. -func isExe(file string, info os.FileInfo) bool { +func isExe(file string, info fs.FileInfo) bool { if runtime.GOOS == "windows" { return strings.HasSuffix(strings.ToLower(file), ".exe") } @@ -100,8 +115,8 @@ func isExe(file string, info os.FileInfo) bool { // If mustPrint is true, scanFile will report any error reading file. // Otherwise (mustPrint is false, because scanFile is being called // by scanDir) scanFile prints nothing for non-Go executables. -func scanFile(file string, info os.FileInfo, mustPrint bool) { - if info.Mode()&os.ModeSymlink != 0 { +func scanFile(file string, info fs.FileInfo, mustPrint bool) { + if info.Mode()&fs.ModeSymlink != 0 { // Accept file symlinks only. i, err := os.Stat(file) if err != nil || !i.Mode().IsRegular() { @@ -112,6 +127,7 @@ func scanFile(file string, info os.FileInfo, mustPrint bool) { } info = i } + if !isExe(file, info) { if mustPrint { fmt.Fprintf(os.Stderr, "%s: not executable file\n", file) diff --git a/src/cmd/go/internal/vet/vet.go b/src/cmd/go/internal/vet/vet.go index cf2c8d59e8..b1bf806e46 100644 --- a/src/cmd/go/internal/vet/vet.go +++ b/src/cmd/go/internal/vet/vet.go @@ -13,7 +13,6 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/load" - "cmd/go/internal/modload" "cmd/go/internal/trace" "cmd/go/internal/work" ) @@ -54,7 +53,7 @@ See also: go fmt, go fix. } func runVet(ctx context.Context, cmd *base.Command, args []string) { - modload.LoadTests = true + load.ModResolveTests = true vetFlags, pkgArgs := vetFlags(args) diff --git a/src/cmd/go/internal/web/api.go b/src/cmd/go/internal/web/api.go index 570818843b..9053b16b62 100644 --- a/src/cmd/go/internal/web/api.go +++ b/src/cmd/go/internal/web/api.go @@ -13,9 +13,8 @@ import ( "bytes" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" - "os" "strings" "unicode" "unicode/utf8" @@ -56,7 +55,7 @@ func (e *HTTPError) Error() string { } if err := e.Err; err != nil { - if pErr, ok := e.Err.(*os.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) { + if pErr, ok := e.Err.(*fs.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) { // Remove the redundant copy of the path. err = pErr.Err } @@ -67,7 +66,7 @@ func (e *HTTPError) Error() string { } func (e *HTTPError) Is(target error) bool { - return target == os.ErrNotExist && (e.StatusCode == 404 || e.StatusCode == 410) + return target == fs.ErrNotExist && (e.StatusCode == 404 || e.StatusCode == 410) } func (e *HTTPError) Unwrap() error { @@ -87,7 +86,7 @@ func GetBytes(u *url.URL) ([]byte, error) { if err := resp.Err(); err != nil { return nil, err } - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading %s: %v", u.Redacted(), err) } @@ -130,7 +129,7 @@ func (r *Response) formatErrorDetail() string { } // Ensure that r.errorDetail has been populated. - _, _ = io.Copy(ioutil.Discard, r.Body) + _, _ = io.Copy(io.Discard, r.Body) s := r.errorDetail.buf.String() if !utf8.ValidString(s) { diff --git a/src/cmd/go/internal/web/file_test.go b/src/cmd/go/internal/web/file_test.go index 6339469045..3734df5c4e 100644 --- a/src/cmd/go/internal/web/file_test.go +++ b/src/cmd/go/internal/web/file_test.go @@ -6,7 +6,7 @@ package web import ( "errors" - "io/ioutil" + "io/fs" "os" "path/filepath" "testing" @@ -15,7 +15,7 @@ import ( func TestGetFileURL(t *testing.T) { const content = "Hello, file!\n" - f, err := ioutil.TempFile("", "web-TestGetFileURL") + f, err := os.CreateTemp("", "web-TestGetFileURL") if err != nil { t.Fatal(err) } @@ -54,7 +54,7 @@ func TestGetNonexistentFile(t *testing.T) { } b, err := GetBytes(u) - if !errors.Is(err, os.ErrNotExist) { - t.Fatalf("GetBytes(%v) = %q, %v; want _, os.ErrNotExist", u, b, err) + if !errors.Is(err, fs.ErrNotExist) { + t.Fatalf("GetBytes(%v) = %q, %v; want _, fs.ErrNotExist", u, b, err) } } diff --git a/src/cmd/go/internal/web/http.go b/src/cmd/go/internal/web/http.go index e0509808d6..72fa2b2ca6 100644 --- a/src/cmd/go/internal/web/http.go +++ b/src/cmd/go/internal/web/http.go @@ -80,6 +80,13 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { return res, nil } + if url.Host == "localhost.localdev" { + return nil, fmt.Errorf("no such host localhost.localdev") + } + if os.Getenv("TESTGONETWORK") == "panic" && !strings.HasPrefix(url.Host, "127.0.0.1") && !strings.HasPrefix(url.Host, "0.0.0.0") { + panic("use of network: " + url.String()) + } + fetch := func(url *urlpkg.URL) (*urlpkg.URL, *http.Response, error) { // Note: The -v build flag does not mean "print logging information", // despite its historical misuse for this in GOPATH-based go get. diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index 825e763c03..9d141ae233 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -14,7 +14,6 @@ import ( "debug/elf" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -93,11 +92,12 @@ type Action struct { output []byte // output redirect buffer (nil means use b.Print) // Execution state. - pending int // number of deps yet to complete - priority int // relative execution priority - Failed bool // whether the action failed - json *actionJSON // action graph information - traceSpan *trace.Span + pending int // number of deps yet to complete + priority int // relative execution priority + Failed bool // whether the action failed + json *actionJSON // action graph information + nonGoOverlay map[string]string // map from non-.go source files to copied files in objdir. Nil if no overlay is used. + traceSpan *trace.Span } // BuildActionID returns the action ID section of a's build ID. @@ -252,7 +252,7 @@ func (b *Builder) Init() { if cfg.BuildN { b.WorkDir = "$WORK" } else { - tmp, err := ioutil.TempDir(cfg.Getenv("GOTMPDIR"), "go-build") + tmp, err := os.MkdirTemp(cfg.Getenv("GOTMPDIR"), "go-build") if err != nil { base.Fatalf("go: creating work dir: %v", err) } diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go index d020aa6e9f..be5532d7aa 100644 --- a/src/cmd/go/internal/work/build.go +++ b/src/cmd/go/internal/work/build.go @@ -9,21 +9,29 @@ import ( "errors" "fmt" "go/build" + "internal/goroot" "os" "os/exec" + "path" "path/filepath" "runtime" "strings" "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" + "cmd/go/internal/modfetch" + "cmd/go/internal/modload" "cmd/go/internal/search" "cmd/go/internal/trace" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) var CmdBuild = &base.Command{ - UsageLine: "go build [-o output] [-i] [build flags] [packages]", + UsageLine: "go build [-o output] [build flags] [packages]", Short: "compile packages and dependencies", Long: ` Build compiles the packages named by the import paths, @@ -46,10 +54,12 @@ serving only as a check that the packages can be built. The -o flag forces build to write the resulting executable or object to the named output file or directory, instead of the default behavior described -in the last two paragraphs. If the named output is a directory that exists, -then any resulting executables will be written to that directory. +in the last two paragraphs. If the named output is an existing directory or +ends with a slash or backslash, then any resulting executables +will be written to that directory. The -i flag installs the packages that are dependencies of the target. +The -i flag is deprecated. Compiled packages are cached automatically. The build flags are shared by the build, clean, get, install, list, run, and test commands: @@ -114,6 +124,17 @@ and test commands: directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the ".mod" extension and appending ".sum". + -overlay file + read a JSON config file that provides an overlay for build operations. + The file is a JSON struct with a single field, named 'Replace', that + maps each disk file path (a string) to its backing file path, so that + a build will run as if the disk file path exists with the contents + given by the backing file paths, or as if the disk file path does not + exist if its backing file path is empty. Support for the -overlay flag + has some limitations:importantly, cgo files included from outside the + include path must be in the same directory as the Go package they are + included from, and overlays will not appear when binaries and tests are + run through go run and go test respectively. -pkgdir dir install and load all packages from dir instead of the usual locations. For example, when building with a non-standard configuration, @@ -240,13 +261,12 @@ const ( // AddBuildFlags adds the flags common to the build, clean, get, // install, list, run, and test commands. func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { + base.AddBuildFlagsNX(&cmd.Flag) cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "") - cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "") cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "") if mask&OmitVFlag == 0 { cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "") } - cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "") cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "") cmd.Flag.Var(buildCompiler{}, "compiler", "") @@ -254,10 +274,15 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.Var(&load.BuildGcflags, "gcflags", "") cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "") if mask&OmitModFlag == 0 { - cmd.Flag.StringVar(&cfg.BuildMod, "mod", "", "") + base.AddModFlag(&cmd.Flag) } if mask&OmitModCommonFlags == 0 { - AddModCommonFlags(cmd) + base.AddModCommonFlags(&cmd.Flag) + } else { + // Add the overlay flag even when we don't add the rest of the mod common flags. + // This only affects 'go get' in GOPATH mode, but add the flag anyway for + // consistency. + cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "") } cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "") cmd.Flag.Var(&load.BuildLdflags, "ldflags", "") @@ -275,13 +300,6 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "") } -// AddModCommonFlags adds the module-related flags common to build commands -// and 'go mod' subcommands. -func AddModCommonFlags(cmd *base.Command) { - cmd.Flag.BoolVar(&cfg.ModCacheRW, "modcacherw", false, "") - cmd.Flag.StringVar(&cfg.ModFile, "modfile", "", "") -} - // tagsFlag is the implementation of the -tags flag. type tagsFlag []string @@ -378,6 +396,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) { depMode := ModeBuild if cfg.BuildI { depMode = ModeInstall + fmt.Fprint(os.Stderr, "go build: -i flag is deprecated\n") } pkgs = omitTestOnly(pkgsFilter(load.Packages(ctx, args))) @@ -388,10 +407,13 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) { } if cfg.BuildO != "" { - // If the -o name exists and is a directory, then + // If the -o name exists and is a directory or + // ends with a slash or backslash, then // write all main packages to that directory. // Otherwise require only a single package be built. - if fi, err := os.Stat(cfg.BuildO); err == nil && fi.IsDir() { + if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) || + strings.HasSuffix(cfg.BuildO, "/") || + strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) { if !explicitO { base.Fatalf("go build: build output %q already exists and is a directory", cfg.BuildO) } @@ -438,7 +460,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) { } var CmdInstall = &base.Command{ - UsageLine: "go install [-i] [build flags] [packages]", + UsageLine: "go install [build flags] [packages]", Short: "compile and install packages and dependencies", Long: ` Install compiles and installs the packages named by the import paths. @@ -448,11 +470,39 @@ variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. Executables in $GOROOT are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN. +If the arguments have version suffixes (like @latest or @v1.0.0), "go install" +builds packages in module-aware mode, ignoring the go.mod file in the current +directory or any parent directory, if there is one. This is useful for +installing executables without affecting the dependencies of the main module. +To eliminate ambiguity about which module versions are used in the build, the +arguments must satisfy the following constraints: + +- Arguments must be package paths or package patterns (with "..." wildcards). + They must not be standard packages (like fmt), meta-patterns (std, cmd, + all), or relative or absolute file paths. +- All arguments must have the same version suffix. Different queries are not + allowed, even if they refer to the same version. +- All arguments must refer to packages in the same module at the same version. +- No module is considered the "main" module. If the module containing + packages named on the command line has a go.mod file, it must not contain + directives (replace and exclude) that would cause it to be interpreted + differently than if it were the main module. The module must not require + a higher version of itself. +- Package path arguments must refer to main packages. Pattern arguments + will only match main packages. + +If the arguments don't have version suffixes, "go install" may run in +module-aware mode or GOPATH mode, depending on the GO111MODULE environment +variable and the presence of a go.mod file. See 'go help modules' for details. +If module-aware mode is enabled, "go install" runs in the context of the main +module. + When module-aware mode is disabled, other packages are installed in the directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled, other packages are built and cached but not installed. The -i flag installs the dependencies of the named packages as well. +The -i flag is deprecated. Compiled packages are cached automatically. For more about the build flags, see 'go help build'. For more about specifying packages, see 'go help packages'. @@ -518,8 +568,35 @@ func libname(args []string, pkgs []*load.Package) (string, error) { } func runInstall(ctx context.Context, cmd *base.Command, args []string) { + // TODO(golang.org/issue/41696): print a deprecation message for the -i flag + // whenever it's set (or just remove it). For now, we don't print a message + // if all named packages are in GOROOT. cmd/dist (run by make.bash) uses + // 'go install -i' when bootstrapping, and we don't want to show deprecation + // messages in that case. + for _, arg := range args { + if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) { + if cfg.BuildI { + fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n") + } + installOutsideModule(ctx, args) + return + } + } BuildInit() - InstallPackages(ctx, args, load.PackagesForBuild(ctx, args)) + pkgs := load.PackagesForBuild(ctx, args) + if cfg.BuildI { + allGoroot := true + for _, pkg := range pkgs { + if !pkg.Goroot { + allGoroot = false + break + } + } + if !allGoroot { + fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n") + } + } + InstallPackages(ctx, args, pkgs) } // omitTestOnly returns pkgs with test-only packages removed. @@ -642,6 +719,156 @@ func InstallPackages(ctx context.Context, patterns []string, pkgs []*load.Packag } } +// installOutsideModule implements 'go install pkg@version'. It builds and +// installs one or more main packages in module mode while ignoring any go.mod +// in the current directory or parent directories. +// +// See golang.org/issue/40276 for details and rationale. +func installOutsideModule(ctx context.Context, args []string) { + modload.ForceUseModules = true + modload.RootMode = modload.NoRoot + modload.AllowMissingModuleImports() + modload.Init() + + // Check that the arguments satisfy syntactic constraints. + var version string + for _, arg := range args { + if i := strings.Index(arg, "@"); i >= 0 { + version = arg[i+1:] + if version == "" { + base.Fatalf("go install %s: version must not be empty", arg) + } + break + } + } + patterns := make([]string, len(args)) + for i, arg := range args { + if !strings.HasSuffix(arg, "@"+version) { + base.Errorf("go install %s: all arguments must have the same version (@%s)", arg, version) + continue + } + p := arg[:len(arg)-len(version)-1] + switch { + case build.IsLocalImport(p): + base.Errorf("go install %s: argument must be a package path, not a relative path", arg) + case filepath.IsAbs(p): + base.Errorf("go install %s: argument must be a package path, not an absolute path", arg) + case search.IsMetaPackage(p): + base.Errorf("go install %s: argument must be a package path, not a meta-package", arg) + case path.Clean(p) != p: + base.Errorf("go install %s: argument must be a clean package path", arg) + case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p): + base.Errorf("go install %s: argument must not be a package in the standard library", arg) + default: + patterns[i] = p + } + } + base.ExitIfErrors() + BuildInit() + + // Query the module providing the first argument, load its go.mod file, and + // check that it doesn't contain directives that would cause it to be + // interpreted differently if it were the main module. + // + // If multiple modules match the first argument, accept the longest match + // (first result). It's possible this module won't provide packages named by + // later arguments, and other modules would. Let's not try to be too + // magical though. + allowed := modload.CheckAllowed + if modload.IsRevisionQuery(version) { + // Don't check for retractions if a specific revision is requested. + allowed = nil + } + noneSelected := func(path string) (version string) { return "none" } + qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed) + if err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + installMod := qrs[0].Mod + data, err := modfetch.GoMod(installMod.Path, installMod.Version) + if err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + f, err := modfile.Parse("go.mod", data, nil) + if err != nil { + base.Fatalf("go install %s: %s: %v", args[0], installMod, err) + } + directiveFmt := "go install %s: %s\n" + + "\tThe go.mod file for the module providing named packages contains one or\n" + + "\tmore %s directives. It must not contain directives that would cause\n" + + "\tit to be interpreted differently than if it were the main module." + if len(f.Replace) > 0 { + base.Fatalf(directiveFmt, args[0], installMod, "replace") + } + if len(f.Exclude) > 0 { + base.Fatalf(directiveFmt, args[0], installMod, "exclude") + } + + // Since we are in NoRoot mode, the build list initially contains only + // the dummy command-line-arguments module. Add a requirement on the + // module that provides the packages named on the command line. + if err := modload.EditBuildList(ctx, nil, []module.Version{installMod}); err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + + // Load packages for all arguments. Ignore non-main packages. + // Print a warning if an argument contains "..." and matches no main packages. + // PackagesForBuild already prints warnings for patterns that don't match any + // packages, so be careful not to double print. + matchers := make([]func(string) bool, len(patterns)) + for i, p := range patterns { + if strings.Contains(p, "...") { + matchers[i] = search.MatchPattern(p) + } + } + + // TODO(golang.org/issue/40276): don't report errors loading non-main packages + // matched by a pattern. + pkgs := load.PackagesForBuild(ctx, patterns) + mainPkgs := make([]*load.Package, 0, len(pkgs)) + mainCount := make([]int, len(patterns)) + nonMainCount := make([]int, len(patterns)) + for _, pkg := range pkgs { + if pkg.Name == "main" { + mainPkgs = append(mainPkgs, pkg) + for i := range patterns { + if matchers[i] != nil && matchers[i](pkg.ImportPath) { + mainCount[i]++ + } + } + } else { + for i := range patterns { + if matchers[i] == nil && patterns[i] == pkg.ImportPath { + base.Errorf("go install: package %s is not a main package", pkg.ImportPath) + } else if matchers[i] != nil && matchers[i](pkg.ImportPath) { + nonMainCount[i]++ + } + } + } + } + base.ExitIfErrors() + for i, p := range patterns { + if matchers[i] != nil && mainCount[i] == 0 && nonMainCount[i] > 0 { + fmt.Fprintf(os.Stderr, "go: warning: %q matched no main packages\n", p) + } + } + + // Check that named packages are all provided by the same module. + for _, pkg := range mainPkgs { + if pkg.Module == nil { + // Packages in std, cmd, and their vendored dependencies + // don't have this field set. + base.Errorf("go install: package %s not provided by module %s", pkg.ImportPath, installMod) + } else if pkg.Module.Path != installMod.Path || pkg.Module.Version != installMod.Version { + base.Errorf("go install: package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, installMod) + } + } + base.ExitIfErrors() + + // Build and install the packages. + InstallPackages(ctx, patterns, mainPkgs) +} + // ExecCmd is the command to use to run user binaries. // Normally it is empty, meaning run the binaries directly. // If cross-compiling and running on a remote system or diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go index c33de2635d..eaf2639e9e 100644 --- a/src/cmd/go/internal/work/build_test.go +++ b/src/cmd/go/internal/work/build_test.go @@ -7,7 +7,7 @@ package work import ( "bytes" "fmt" - "io/ioutil" + "io/fs" "os" "path/filepath" "reflect" @@ -169,7 +169,7 @@ func TestSharedLibName(t *testing.T) { for _, data := range testData { func() { if data.rootedAt != "" { - tmpGopath, err := ioutil.TempDir("", "gopath") + tmpGopath, err := os.MkdirTemp("", "gopath") if err != nil { t.Fatal(err) } @@ -221,10 +221,8 @@ func pkgImportPath(pkgpath string) *load.Package { // See https://golang.org/issue/18878. func TestRespectSetgidDir(t *testing.T) { switch runtime.GOOS { - case "darwin": - if runtime.GOARCH == "arm64" { - t.Skip("can't set SetGID bit with chmod on iOS") - } + case "ios": + t.Skip("can't set SetGID bit with chmod on iOS") case "windows", "plan9": t.Skip("chown/chmod setgid are not supported on Windows or Plan 9") } @@ -239,7 +237,7 @@ func TestRespectSetgidDir(t *testing.T) { return cmdBuf.WriteString(fmt.Sprint(a...)) } - setgiddir, err := ioutil.TempDir("", "SetGroupID") + setgiddir, err := os.MkdirTemp("", "SetGroupID") if err != nil { t.Fatal(err) } @@ -255,13 +253,13 @@ func TestRespectSetgidDir(t *testing.T) { } // Change setgiddir's permissions to include the SetGID bit. - if err := os.Chmod(setgiddir, 0755|os.ModeSetgid); err != nil { + if err := os.Chmod(setgiddir, 0755|fs.ModeSetgid); err != nil { t.Fatal(err) } - pkgfile, err := ioutil.TempFile("", "pkgfile") + pkgfile, err := os.CreateTemp("", "pkgfile") if err != nil { - t.Fatalf("ioutil.TempFile(\"\", \"pkgfile\"): %v", err) + t.Fatalf("os.CreateTemp(\"\", \"pkgfile\"): %v", err) } defer os.Remove(pkgfile.Name()) defer pkgfile.Close() diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go index 6613b6fe3f..d76988145b 100644 --- a/src/cmd/go/internal/work/buildid.go +++ b/src/cmd/go/internal/work/buildid.go @@ -7,7 +7,6 @@ package work import ( "bytes" "fmt" - "io/ioutil" "os" "os/exec" "strings" @@ -15,6 +14,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cache" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/str" "cmd/internal/buildid" ) @@ -31,7 +31,7 @@ import ( // // actionID/[.../]contentID // -// where the actionID and contentID are prepared by hashToString below. +// where the actionID and contentID are prepared by buildid.HashToString below. // and are found by looking for the first or last slash. // Usually the buildID is simply actionID/contentID, but see below for an // exception. @@ -108,31 +108,6 @@ func contentID(buildID string) string { return buildID[strings.LastIndex(buildID, buildIDSeparator)+1:] } -// hashToString converts the hash h to a string to be recorded -// in package archives and binaries as part of the build ID. -// We use the first 96 bits of the hash and encode it in base64, -// resulting in a 16-byte string. Because this is only used for -// detecting the need to rebuild installed files (not for lookups -// in the object file cache), 96 bits are sufficient to drive the -// probability of a false "do not need to rebuild" decision to effectively zero. -// We embed two different hashes in archives and four in binaries, -// so cutting to 16 bytes is a significant savings when build IDs are displayed. -// (16*4+3 = 67 bytes compared to 64*4+3 = 259 bytes for the -// more straightforward option of printing the entire h in hex). -func hashToString(h [cache.HashSize]byte) string { - const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" - const chunks = 5 - var dst [chunks * 4]byte - for i := 0; i < chunks; i++ { - v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) - dst[4*i+0] = b64[(v>>18)&0x3F] - dst[4*i+1] = b64[(v>>12)&0x3F] - dst[4*i+2] = b64[(v>>6)&0x3F] - dst[4*i+3] = b64[v&0x3F] - } - return string(dst[:]) -} - // toolID returns the unique ID to use for the current copy of the // named tool (asm, compile, cover, link). // @@ -368,7 +343,7 @@ func (b *Builder) gccgoBuildIDFile(a *Action) (string, error) { } } - if err := ioutil.WriteFile(sfile, buf.Bytes(), 0666); err != nil { + if err := os.WriteFile(sfile, buf.Bytes(), 0666); err != nil { return "", err } @@ -400,11 +375,12 @@ func (b *Builder) buildID(file string) string { // fileHash returns the content hash of the named file. func (b *Builder) fileHash(file string) string { + file, _ = fsys.OverlayPath(file) sum, err := cache.FileHash(file) if err != nil { return "" } - return hashToString(sum) + return buildid.HashToString(sum) } // useCache tries to satisfy the action a, which has action ID actionHash, @@ -425,9 +401,9 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) // It's important that the overall buildID be unlikely verging on impossible // to appear in the output by chance, but that should be taken care of by // the actionID half; if it also appeared in the input that would be like an - // engineered 96-bit partial SHA256 collision. + // engineered 120-bit partial SHA256 collision. a.actionID = actionHash - actionID := hashToString(actionHash) + actionID := buildid.HashToString(actionHash) if a.json != nil { a.json.ActionID = actionID } @@ -480,7 +456,7 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) // build IDs of completed actions. oldBuildID := a.buildID a.buildID = id[1] + buildIDSeparator + id[2] - linkID := hashToString(b.linkActionID(a.triggers[0])) + linkID := buildid.HashToString(b.linkActionID(a.triggers[0])) if id[0] == linkID { // Best effort attempt to display output from the compile and link steps. // If it doesn't work, it doesn't work: reusing the cached binary is more @@ -654,7 +630,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { if err != nil { return err } - newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + hashToString(hash) + newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + buildid.HashToString(hash) if len(newID) != len(a.buildID) { return fmt.Errorf("internal error: build ID length mismatch %q vs %q", a.buildID, newID) } @@ -670,7 +646,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { } if rewrite { - w, err := os.OpenFile(target, os.O_WRONLY, 0) + w, err := os.OpenFile(target, os.O_RDWR, 0) if err != nil { return err } @@ -713,6 +689,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { return err } a.Package.Export = c.OutputFile(outputID) + a.Package.BuildID = a.buildID } } } diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index d975c36306..feb2299d40 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -8,13 +8,14 @@ package work import ( "bytes" + "cmd/go/internal/fsys" "context" "encoding/json" "errors" "fmt" "internal/lazyregexp" "io" - "io/ioutil" + "io/fs" "log" "math/rand" "os" @@ -31,6 +32,7 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/go/internal/modload" "cmd/go/internal/str" "cmd/go/internal/trace" ) @@ -91,7 +93,7 @@ func (b *Builder) Do(ctx context.Context, root *Action) { base.Fatalf("go: refusing to write action graph to %v\n", file) } js := actionGraphJSON(root) - if err := ioutil.WriteFile(file, []byte(js), 0666); err != nil { + if err := os.WriteFile(file, []byte(js), 0666); err != nil { fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err) base.SetExitStatus(1) } @@ -270,7 +272,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags) } - // GO386, GOARM, GOMIPS, etc. + // GOARM, GOMIPS, etc. key, val := cfg.GetArchEnv() fmt.Fprintf(h, "%s=%s\n", key, val) @@ -337,6 +339,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { p.SysoFiles, p.SwigFiles, p.SwigCXXFiles, + p.EmbedFiles, ) for _, file := range inputFiles { fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file))) @@ -431,6 +434,7 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { need &^= needBuild if b.NeedExport { p.Export = a.built + p.BuildID = a.buildID } if need&needCompiledGoFiles != 0 { if err := b.loadCachedSrcFiles(a); err == nil { @@ -533,6 +537,34 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { } } + // Compute overlays for .c/.cc/.h/etc. and if there are any overlays + // put correct contents of all those files in the objdir, to ensure + // the correct headers are included. nonGoOverlay is the overlay that + // points from nongo files to the copied files in objdir. + nonGoFileLists := [][]string{a.Package.CFiles, a.Package.SFiles, a.Package.CXXFiles, a.Package.HFiles, a.Package.FFiles} +OverlayLoop: + for _, fs := range nonGoFileLists { + for _, f := range fs { + if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok { + a.nonGoOverlay = make(map[string]string) + break OverlayLoop + } + } + } + if a.nonGoOverlay != nil { + for _, fs := range nonGoFileLists { + for i := range fs { + from := mkAbs(p.Dir, fs[i]) + opath, _ := fsys.OverlayPath(from) + dst := objdir + filepath.Base(fs[i]) + if err := b.copyFile(dst, opath, 0666, false); err != nil { + return err + } + a.nonGoOverlay[from] = dst + } + } + } + // Run SWIG on each .swig and .swigcxx file. // Each run will generate two files, a .go file and a .c or .cxx file. // The .go file will use import "C" and is to be processed by cgo. @@ -603,7 +635,7 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles) } else { for _, sfile := range sfiles { - data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile)) + data, err := os.ReadFile(filepath.Join(a.Package.Dir, sfile)) if err == nil { if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) || bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) || @@ -691,8 +723,28 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) } + // Prepare Go embed config if needed. + // Unlike the import config, it's okay for the embed config to be empty. + var embedcfg []byte + if len(p.Internal.Embed) > 0 { + var embed struct { + Patterns map[string][]string + Files map[string]string + } + embed.Patterns = p.Internal.Embed + embed.Files = make(map[string]string) + for _, file := range p.EmbedFiles { + embed.Files[file] = filepath.Join(p.Dir, file) + } + js, err := json.MarshalIndent(&embed, "", "\t") + if err != nil { + return fmt.Errorf("marshal embedcfg: %v", err) + } + embedcfg = js + } + if p.Internal.BuildInfo != "" && cfg.ModulesEnabled { - if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil { + if err := b.writeFile(objdir+"_gomod_.go", modload.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil { return err } gofiles = append(gofiles, objdir+"_gomod_.go") @@ -700,7 +752,7 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { // Compile Go. objpkg := objdir + "_pkg_.a" - ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), symabis, len(sfiles) > 0, gofiles) + ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), embedcfg, symabis, len(sfiles) > 0, gofiles) if len(out) > 0 { output := b.processOutput(out) if p.Module != nil && !allowedVersion(p.Module.GoVersion) { @@ -713,7 +765,7 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { } if err != nil { if p.Module != nil && !allowedVersion(p.Module.GoVersion) { - b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion) + b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion+"\n") } return err } @@ -921,12 +973,13 @@ func (b *Builder) loadCachedSrcFiles(a *Action) error { // vetConfig is the configuration passed to vet describing a single package. type vetConfig struct { - ID string // package ID (example: "fmt [fmt.test]") - Compiler string // compiler name (gc, gccgo) - Dir string // directory containing package - ImportPath string // canonical import path ("package path") - GoFiles []string // absolute paths to package source files - NonGoFiles []string // absolute paths to package non-Go files + ID string // package ID (example: "fmt [fmt.test]") + Compiler string // compiler name (gc, gccgo) + Dir string // directory containing package + ImportPath string // canonical import path ("package path") + GoFiles []string // absolute paths to package source files + NonGoFiles []string // absolute paths to package non-Go files + IgnoredFiles []string // absolute paths to ignored source files ImportMap map[string]string // map import path in source code to package path PackageFile map[string]string // map package path to .a file with export data @@ -950,20 +1003,23 @@ func buildVetConfig(a *Action, srcfiles []string) { } } + ignored := str.StringList(a.Package.IgnoredGoFiles, a.Package.IgnoredOtherFiles) + // Pass list of absolute paths to vet, // so that vet's error messages will use absolute paths, // so that we can reformat them relative to the directory // in which the go command is invoked. vcfg := &vetConfig{ - ID: a.Package.ImportPath, - Compiler: cfg.BuildToolchainName, - Dir: a.Package.Dir, - GoFiles: mkAbsFiles(a.Package.Dir, gofiles), - NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles), - ImportPath: a.Package.ImportPath, - ImportMap: make(map[string]string), - PackageFile: make(map[string]string), - Standard: make(map[string]bool), + ID: a.Package.ImportPath, + Compiler: cfg.BuildToolchainName, + Dir: a.Package.Dir, + GoFiles: mkAbsFiles(a.Package.Dir, gofiles), + NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles), + IgnoredFiles: mkAbsFiles(a.Package.Dir, ignored), + ImportPath: a.Package.ImportPath, + ImportMap: make(map[string]string), + PackageFile: make(map[string]string), + Standard: make(map[string]bool), } a.vetCfg = vcfg for i, raw := range a.Package.Internal.RawImports { @@ -1051,17 +1107,28 @@ func (b *Builder) vet(ctx context.Context, a *Action) error { // This is OK as long as the packages that are farther down the // dependency tree turn on *more* analysis, as here. // (The unsafeptr check does not write any facts for use by - // later vet runs.) + // later vet runs, nor does unreachable.) if a.Package.Goroot && !VetExplicit && VetTool == "" { + // Turn off -unsafeptr checks. + // There's too much unsafe.Pointer code + // that vet doesn't like in low-level packages + // like runtime, sync, and reflect. // Note that $GOROOT/src/buildall.bash // does the same for the misc-compile trybots // and should be updated if these flags are // changed here. - // - // There's too much unsafe.Pointer code - // that vet doesn't like in low-level packages - // like runtime, sync, and reflect. vetFlags = []string{"-unsafeptr=false"} + + // Also turn off -unreachable checks during go test. + // During testing it is very common to make changes + // like hard-coded forced returns or panics that make + // code unreachable. It's unreasonable to insist on files + // not having any unreachable code during "go test". + // (buildall.bash still runs with -unreachable enabled + // for the overall whole-tree scan.) + if cfg.CmdName == "test" { + vetFlags = append(vetFlags, "-unreachable=false") + } } // Note: We could decide that vet should compute export data for @@ -1174,12 +1241,17 @@ func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) { fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags) } - // GO386, GOARM, GOMIPS, etc. + // GOARM, GOMIPS, etc. key, val := cfg.GetArchEnv() fmt.Fprintf(h, "%s=%s\n", key, val) - // The linker writes source file paths that say GOROOT_FINAL. - fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL) + // The linker writes source file paths that say GOROOT_FINAL, but + // only if -trimpath is not specified (see ld() in gc.go). + gorootFinal := cfg.GOROOT_FINAL + if cfg.BuildTrimpath { + gorootFinal = trimPathGoRootFinal + } + fmt.Fprintf(h, "GOROOT=%s\n", gorootFinal) // GO_EXTLINK_ENABLED controls whether the external linker is used. fmt.Fprintf(h, "GO_EXTLINK_ENABLED=%s\n", cfg.Getenv("GO_EXTLINK_ENABLED")) @@ -1398,7 +1470,7 @@ func (b *Builder) installShlibname(ctx context.Context, a *Action) error { // TODO: BuildN a1 := a.Deps[0] - err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) + err := os.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) if err != nil { return err } @@ -1539,7 +1611,7 @@ func BuildInstallFunc(b *Builder, ctx context.Context, a *Action) (err error) { return err } - perm := os.FileMode(0666) + perm := fs.FileMode(0666) if a1.Mode == "link" { switch cfg.BuildBuildmode { case "c-archive", "c-shared", "plugin": @@ -1588,7 +1660,7 @@ func (b *Builder) cleanup(a *Action) { } // moveOrCopyFile is like 'mv src dst' or 'cp src dst'. -func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) error { +func (b *Builder) moveOrCopyFile(dst, src string, perm fs.FileMode, force bool) error { if cfg.BuildN { b.Showcmd("", "mv %s %s", src, dst) return nil @@ -1614,7 +1686,7 @@ func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) // we have to copy the file to retain the correct permissions. // https://golang.org/issue/18878 if fi, err := os.Stat(filepath.Dir(dst)); err == nil { - if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 { + if fi.IsDir() && (fi.Mode()&fs.ModeSetgid) != 0 { return b.copyFile(dst, src, perm, force) } } @@ -1649,7 +1721,7 @@ func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) } // copyFile is like 'cp src dst'. -func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error { +func (b *Builder) copyFile(dst, src string, perm fs.FileMode, force bool) error { if cfg.BuildN || cfg.BuildX { b.Showcmd("", "cp %s %s", src, dst) if cfg.BuildN { @@ -1715,7 +1787,7 @@ func (b *Builder) writeFile(file string, text []byte) error { if cfg.BuildN { return nil } - return ioutil.WriteFile(file, text, 0666) + return os.WriteFile(file, text, 0666) } // Install the cgo export header file, if there is one. @@ -1978,6 +2050,13 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa defer cleanup() cmd.Dir = dir cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) + + // Add the TOOLEXEC_IMPORTPATH environment variable for -toolexec tools. + // It doesn't really matter if -toolexec isn't being used. + if a != nil && a.Package != nil { + cmd.Env = append(cmd.Env, "TOOLEXEC_IMPORTPATH="+a.Package.ImportPath) + } + cmd.Env = append(cmd.Env, env...) start := time.Now() err := cmd.Run() @@ -2095,9 +2174,7 @@ func mkAbs(dir, f string) string { type toolchain interface { // gc runs the compiler in a specific directory on a set of files // and returns the name of the generated output file. - // - // TODO: This argument list is long. Consider putting it in a struct. - gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) + gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) // cc runs the toolchain's C compiler in a directory on a C file // to produce an output file. cc(b *Builder, a *Action, ofile, cfile string) error @@ -2137,7 +2214,7 @@ func (noToolchain) linker() string { return "" } -func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) { +func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) { return "", nil, noCompiler() } @@ -2219,7 +2296,11 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s } } - output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file)) + overlayPath := file + if p, ok := a.nonGoOverlay[overlayPath]; ok { + overlayPath = p + } + output, err := b.runOut(a, filepath.Dir(overlayPath), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(overlayPath)) if len(output) > 0 { // On FreeBSD 11, when we pass -g to clang 3.8 it // invokes its internal assembler with -dwarf-version=2. @@ -2262,7 +2343,8 @@ func (b *Builder) gccld(a *Action, p *load.Package, objdir, outfile string, flag cmdargs := []interface{}{cmd, "-o", outfile, objs, flags} dir := p.Dir - out, err := b.runOut(a, dir, b.cCompilerEnv(), cmdargs...) + out, err := b.runOut(a, base.Cwd, b.cCompilerEnv(), cmdargs...) + if len(out) > 0 { // Filter out useless linker warnings caused by bugs outside Go. // See also cmd/link/internal/ld's hostlink method. @@ -2418,7 +2500,7 @@ func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []strin // On OS X, some of the compilers behave as if -fno-common // is always set, and the Mach-O linker in 6l/8l assumes this. // See https://golang.org/issue/3253. - if cfg.Goos == "darwin" { + if cfg.Goos == "darwin" || cfg.Goos == "ios" { a = append(a, "-fno-common") } @@ -2454,7 +2536,7 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { tmp := os.DevNull if runtime.GOOS == "windows" { - f, err := ioutil.TempFile(b.WorkDir, "") + f, err := os.CreateTemp(b.WorkDir, "") if err != nil { return false } @@ -2590,7 +2672,8 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...) } - // Allows including _cgo_export.h from .[ch] files in the package. + // Allows including _cgo_export.h, as well as the user's .h files, + // from .[ch] files in the package. cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir) // cgo @@ -2647,7 +2730,23 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h") } - if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { + execdir := p.Dir + + // Rewrite overlaid paths in cgo files. + // cgo adds //line and #line pragmas in generated files with these paths. + var trimpath []string + for i := range cgofiles { + path := mkAbs(p.Dir, cgofiles[i]) + if opath, ok := fsys.OverlayPath(path); ok { + cgofiles[i] = opath + trimpath = append(trimpath, opath+"=>"+path) + } + } + if len(trimpath) > 0 { + cgoflags = append(cgoflags, "-trimpath", strings.Join(trimpath, ";")) + } + + if err := b.run(a, execdir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { return nil, nil, err } outGo = append(outGo, gofiles...) @@ -2728,6 +2827,81 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo noCompiler() } + // Double check the //go:cgo_ldflag comments in the generated files. + // The compiler only permits such comments in files whose base name + // starts with "_cgo_". Make sure that the comments in those files + // are safe. This is a backstop against people somehow smuggling + // such a comment into a file generated by cgo. + if cfg.BuildToolchainName == "gc" && !cfg.BuildN { + var flags []string + for _, f := range outGo { + if !strings.HasPrefix(filepath.Base(f), "_cgo_") { + continue + } + + src, err := os.ReadFile(f) + if err != nil { + return nil, nil, err + } + + const cgoLdflag = "//go:cgo_ldflag" + idx := bytes.Index(src, []byte(cgoLdflag)) + for idx >= 0 { + // We are looking at //go:cgo_ldflag. + // Find start of line. + start := bytes.LastIndex(src[:idx], []byte("\n")) + if start == -1 { + start = 0 + } + + // Find end of line. + end := bytes.Index(src[idx:], []byte("\n")) + if end == -1 { + end = len(src) + } else { + end += idx + } + + // Check for first line comment in line. + // We don't worry about /* */ comments, + // which normally won't appear in files + // generated by cgo. + commentStart := bytes.Index(src[start:], []byte("//")) + commentStart += start + // If that line comment is //go:cgo_ldflag, + // it's a match. + if bytes.HasPrefix(src[commentStart:], []byte(cgoLdflag)) { + // Pull out the flag, and unquote it. + // This is what the compiler does. + flag := string(src[idx+len(cgoLdflag) : end]) + flag = strings.TrimSpace(flag) + flag = strings.Trim(flag, `"`) + flags = append(flags, flag) + } + src = src[end:] + idx = bytes.Index(src, []byte(cgoLdflag)) + } + } + + // We expect to find the contents of cgoLDFLAGS in flags. + if len(cgoLDFLAGS) > 0 { + outer: + for i := range flags { + for j, f := range cgoLDFLAGS { + if f != flags[i+j] { + continue outer + } + } + flags = append(flags[:i], flags[i+len(cgoLDFLAGS):]...) + break + } + } + + if err := checkLinkerFlags("LDFLAGS", "go:cgo_ldflag", flags); err != nil { + return nil, nil, err + } + } + return outGo, outObj, nil } @@ -2741,7 +2915,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe return err } - linkobj := str.StringList(ofile, outObj, p.SysoFiles) + linkobj := str.StringList(ofile, outObj, mkAbsFiles(p.Dir, p.SysoFiles)) dynobj := objdir + "_cgo_.o" // we need to use -pie for Linux/ARM to get accurate imported sym @@ -2766,7 +2940,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe if p.Standard && p.ImportPath == "runtime/cgo" { cgoflags = []string{"-dynlinker"} // record path to dynamic linker } - return b.run(a, p.Dir, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) + return b.run(a, base.Cwd, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) } // Run SWIG on all SWIG input files. @@ -2895,14 +3069,14 @@ func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) { return "$INTBITS", nil } src := filepath.Join(b.WorkDir, "swig_intsize.go") - if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil { + if err = os.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil { return } srcs := []string{src} p := load.GoFilesPackage(context.TODO(), srcs) - if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, "", false, srcs); e != nil { + if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, nil, "", false, srcs); e != nil { return "32", nil } return "64", nil @@ -3055,14 +3229,14 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { return } - tf, err := ioutil.TempFile("", "args") + tf, err := os.CreateTemp("", "args") if err != nil { log.Fatalf("error writing long arguments to response file: %v", err) } cleanup = func() { os.Remove(tf.Name()) } var buf bytes.Buffer for _, arg := range cmd.Args[1:] { - fmt.Fprintf(&buf, "%s\n", arg) + fmt.Fprintf(&buf, "%s\n", encodeArg(arg)) } if _, err := tf.Write(buf.Bytes()); err != nil { tf.Close() @@ -3077,6 +3251,12 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { return cleanup } +// Windows has a limit of 32 KB arguments. To be conservative and not worry +// about whether that includes spaces or not, just use 30 KB. Darwin's limit is +// less clear. The OS claims 256KB, but we've seen failures with arglen as +// small as 50KB. +const ArgLengthForResponseFile = (30 << 10) + func useResponseFile(path string, argLen int) bool { // Unless the program uses objabi.Flagparse, which understands // response files, don't use response files. @@ -3088,11 +3268,7 @@ func useResponseFile(path string, argLen int) bool { return false } - // Windows has a limit of 32 KB arguments. To be conservative and not - // worry about whether that includes spaces or not, just use 30 KB. - // Darwin's limit is less clear. The OS claims 256KB, but we've seen - // failures with arglen as small as 50KB. - if argLen > (30 << 10) { + if argLen > ArgLengthForResponseFile { return true } @@ -3105,3 +3281,25 @@ func useResponseFile(path string, argLen int) bool { return false } + +// encodeArg encodes an argument for response file writing. +func encodeArg(arg string) string { + // If there aren't any characters we need to reencode, fastpath out. + if !strings.ContainsAny(arg, "\\\n") { + return arg + } + var b strings.Builder + for _, r := range arg { + switch r { + case '\\': + b.WriteByte('\\') + b.WriteByte('\\') + case '\n': + b.WriteByte('\\') + b.WriteByte('n') + default: + b.WriteRune(r) + } + } + return b.String() +} diff --git a/src/cmd/go/internal/work/exec_test.go b/src/cmd/go/internal/work/exec_test.go new file mode 100644 index 0000000000..4eb762cb28 --- /dev/null +++ b/src/cmd/go/internal/work/exec_test.go @@ -0,0 +1,86 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package work + +import ( + "bytes" + "cmd/internal/objabi" + "fmt" + "math/rand" + "testing" + "time" + "unicode/utf8" +) + +func TestEncodeArgs(t *testing.T) { + t.Parallel() + tests := []struct { + arg, want string + }{ + {"", ""}, + {"hello", "hello"}, + {"hello\n", "hello\\n"}, + {"hello\\", "hello\\\\"}, + {"hello\nthere", "hello\\nthere"}, + {"\\\n", "\\\\\\n"}, + } + for _, test := range tests { + if got := encodeArg(test.arg); got != test.want { + t.Errorf("encodeArg(%q) = %q, want %q", test.arg, got, test.want) + } + } +} + +func TestEncodeDecode(t *testing.T) { + t.Parallel() + tests := []string{ + "", + "hello", + "hello\\there", + "hello\nthere", + "hello 中国", + "hello \n中\\国", + } + for _, arg := range tests { + if got := objabi.DecodeArg(encodeArg(arg)); got != arg { + t.Errorf("objabi.DecodeArg(encodeArg(%q)) = %q", arg, got) + } + } +} + +func TestEncodeDecodeFuzz(t *testing.T) { + if testing.Short() { + t.Skip("fuzz test is slow") + } + t.Parallel() + + nRunes := ArgLengthForResponseFile + 100 + rBuffer := make([]rune, nRunes) + buf := bytes.NewBuffer([]byte(string(rBuffer))) + + seed := time.Now().UnixNano() + t.Logf("rand seed: %v", seed) + rng := rand.New(rand.NewSource(seed)) + + for i := 0; i < 50; i++ { + // Generate a random string of runes. + buf.Reset() + for buf.Len() < ArgLengthForResponseFile+1 { + var r rune + for { + r = rune(rng.Intn(utf8.MaxRune + 1)) + if utf8.ValidRune(r) { + break + } + } + fmt.Fprintf(buf, "%c", r) + } + arg := buf.String() + + if got := objabi.DecodeArg(encodeArg(arg)); got != arg { + t.Errorf("[%d] objabi.DecodeArg(encodeArg(%q)) = %q [seed: %v]", i, arg, got, seed) + } + } +} diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go index 6031897f88..cc4e2b2b2b 100644 --- a/src/cmd/go/internal/work/gc.go +++ b/src/cmd/go/internal/work/gc.go @@ -9,7 +9,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -18,6 +17,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/str" "cmd/internal/objabi" @@ -25,6 +25,9 @@ import ( "crypto/sha1" ) +// The 'path' used for GOROOT_FINAL when -trimpath is specified +const trimPathGoRootFinal = "go" + // The Go toolchain. type gcToolchain struct{} @@ -48,7 +51,7 @@ func pkgPath(a *Action) string { return ppath } -func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { +func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { p := a.Package objdir := a.Objdir if archive != "" { @@ -85,7 +88,11 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles) if p.Standard { switch p.ImportPath { - case "bytes", "internal/poll", "net", "os", "runtime/pprof", "runtime/trace", "sync", "syscall", "time": + case "bytes", "internal/poll", "net", "os": + fallthrough + case "runtime/metrics", "runtime/pprof", "runtime/trace": + fallthrough + case "sync", "syscall", "time": extFiles++ } } @@ -129,6 +136,12 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s } args = append(args, "-importcfg", objdir+"importcfg") } + if embedcfg != nil { + if err := b.writeFile(objdir+"embedcfg", embedcfg); err != nil { + return "", nil, err + } + args = append(args, "-embedcfg", objdir+"embedcfg") + } if ofile == archive { args = append(args, "-pack") } @@ -142,10 +155,26 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s } for _, f := range gofiles { - args = append(args, mkAbs(p.Dir, f)) + f := mkAbs(p.Dir, f) + + // Handle overlays. Convert path names using OverlayPath + // so these paths can be handed directly to tools. + // Deleted files won't show up in when scanning directories earlier, + // so OverlayPath will never return "" (meaning a deleted file) here. + // TODO(#39958): Handle cases where the package directory + // doesn't exist on disk (this can happen when all the package's + // files are in an overlay): the code expects the package directory + // to exist and runs some tools in that directory. + // TODO(#39958): Process the overlays when the + // gofiles, cgofiles, cfiles, sfiles, and cxxfiles variables are + // created in (*Builder).build. Doing that requires rewriting the + // code that uses those values to expect absolute paths. + f, _ = fsys.OverlayPath(f) + + args = append(args, f) } - output, err = b.runOut(a, p.Dir, nil, args...) + output, err = b.runOut(a, base.Cwd, nil, args...) return ofile, output, err } @@ -232,18 +261,64 @@ func (a *Action) trimpath() string { if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator { objdir = objdir[:len(objdir)-1] } - rewrite := objdir + "=>" + rewrite := "" - // For "go build -trimpath", rewrite package source directory - // to a file system-independent path (just the import path). + rewriteDir := a.Package.Dir if cfg.BuildTrimpath { if m := a.Package.Module; m != nil && m.Version != "" { - rewrite += ";" + a.Package.Dir + "=>" + m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path) + rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path) } else { - rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath + rewriteDir = a.Package.ImportPath } + rewrite += a.Package.Dir + "=>" + rewriteDir + ";" + } + + // Add rewrites for overlays. The 'from' and 'to' paths in overlays don't need to have + // same basename, so go from the overlay contents file path (passed to the compiler) + // to the path the disk path would be rewritten to. + + cgoFiles := make(map[string]bool) + for _, f := range a.Package.CgoFiles { + cgoFiles[f] = true } + // TODO(matloob): Higher up in the stack, when the logic for deciding when to make copies + // of c/c++/m/f/hfiles is consolidated, use the same logic that Build uses to determine + // whether to create the copies in objdir to decide whether to rewrite objdir to the + // package directory here. + var overlayNonGoRewrites string // rewrites for non-go files + hasCgoOverlay := false + if fsys.OverlayFile != "" { + for _, filename := range a.Package.AllFiles() { + path := filename + if !filepath.IsAbs(path) { + path = filepath.Join(a.Package.Dir, path) + } + base := filepath.Base(path) + isGo := strings.HasSuffix(filename, ".go") || strings.HasSuffix(filename, ".s") + isCgo := cgoFiles[filename] || !isGo + overlayPath, isOverlay := fsys.OverlayPath(path) + if isCgo && isOverlay { + hasCgoOverlay = true + } + if !isCgo && isOverlay { + rewrite += overlayPath + "=>" + filepath.Join(rewriteDir, base) + ";" + } else if isCgo { + // Generate rewrites for non-Go files copied to files in objdir. + if filepath.Dir(path) == a.Package.Dir { + // This is a file copied to objdir. + overlayNonGoRewrites += filepath.Join(objdir, base) + "=>" + filepath.Join(rewriteDir, base) + ";" + } + } else { + // Non-overlay Go files are covered by the a.Package.Dir rewrite rule above. + } + } + } + if hasCgoOverlay { + rewrite += overlayNonGoRewrites + } + rewrite += objdir + "=>" + return rewrite } @@ -259,14 +334,20 @@ func asmArgs(a *Action, p *load.Package) []interface{} { } } } - if p.ImportPath == "runtime" && objabi.Regabi_enabled != 0 { - // In order to make it easier to port runtime assembly - // to the register ABI, we introduce a macro - // indicating the experiment is enabled. - // - // TODO(austin): Remove this once we commit to the - // register ABI (#40724). - args = append(args, "-D=GOEXPERIMENT_REGABI=1") + if objabi.IsRuntimePackagePath(pkgpath) { + args = append(args, "-compiling-runtime") + if objabi.Regabi_enabled != 0 { + // In order to make it easier to port runtime assembly + // to the register ABI, we introduce a macro + // indicating the experiment is enabled. + // + // Note: a similar change also appears in + // cmd/dist/build.go. + // + // TODO(austin): Remove this once we commit to the + // register ABI (#40724). + args = append(args, "-D=GOEXPERIMENT_REGABI=1") + } } if cfg.Goarch == "mips" || cfg.Goarch == "mipsle" { @@ -288,9 +369,10 @@ func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) var ofiles []string for _, sfile := range sfiles { + overlayPath, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile)) ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o" ofiles = append(ofiles, ofile) - args1 := append(args, "-o", ofile, mkAbs(p.Dir, sfile)) + args1 := append(args, "-o", ofile, overlayPath) if err := b.run(a, p.Dir, p.ImportPath, nil, args1...); err != nil { return nil, err } @@ -306,7 +388,8 @@ func (gcToolchain) symabis(b *Builder, a *Action, sfiles []string) (string, erro if p.ImportPath == "runtime/cgo" && strings.HasPrefix(sfile, "gcc_") { continue } - args = append(args, mkAbs(p.Dir, sfile)) + op, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile)) + args = append(args, op) } // Supply an empty go_asm.h as if the compiler had been run. @@ -342,11 +425,11 @@ func toolVerify(a *Action, b *Builder, p *load.Package, newTool string, ofile st if err := b.run(a, p.Dir, p.ImportPath, nil, newArgs...); err != nil { return err } - data1, err := ioutil.ReadFile(ofile) + data1, err := os.ReadFile(ofile) if err != nil { return err } - data2, err := ioutil.ReadFile(ofile + ".new") + data2, err := os.ReadFile(ofile + ".new") if err != nil { return err } @@ -496,7 +579,7 @@ func pluginPath(a *Action) string { } fmt.Fprintf(h, "build ID: %s\n", buildID) for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) { - data, err := ioutil.ReadFile(filepath.Join(p.Dir, file)) + data, err := os.ReadFile(filepath.Join(p.Dir, file)) if err != nil { base.Fatalf("go: %s", err) } @@ -569,7 +652,7 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) env := []string{} if cfg.BuildTrimpath { - env = append(env, "GOROOT_FINAL=go") + env = append(env, "GOROOT_FINAL="+trimPathGoRootFinal) } return b.run(root, dir, root.Package.ImportPath, env, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg) } diff --git a/src/cmd/go/internal/work/gccgo.go b/src/cmd/go/internal/work/gccgo.go index 4c1f36dbd6..3ffd01c473 100644 --- a/src/cmd/go/internal/work/gccgo.go +++ b/src/cmd/go/internal/work/gccgo.go @@ -6,16 +6,18 @@ package work import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/str" + "cmd/internal/pkgpath" ) // The Gccgo toolchain. @@ -60,7 +62,7 @@ func checkGccgoBin() { base.Exit() } -func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { +func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { p := a.Package objdir := a.Objdir out := "_go_.o" @@ -91,13 +93,37 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg args = append(args, "-I", root) } } - if cfg.BuildTrimpath && b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") { - args = append(args, "-ffile-prefix-map="+base.Cwd+"=.") - args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build") + + if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") { + if cfg.BuildTrimpath { + args = append(args, "-ffile-prefix-map="+base.Cwd+"=.") + args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build") + } + if fsys.OverlayFile != "" { + for _, name := range gofiles { + absPath := mkAbs(p.Dir, name) + overlayPath, ok := fsys.OverlayPath(absPath) + if !ok { + continue + } + toPath := absPath + // gccgo only applies the last matching rule, so also handle the case where + // BuildTrimpath is true and the path is relative to base.Cwd. + if cfg.BuildTrimpath && str.HasFilePathPrefix(toPath, base.Cwd) { + toPath = "." + toPath[len(base.Cwd):] + } + args = append(args, "-ffile-prefix-map="+overlayPath+"="+toPath) + } + } } + args = append(args, a.Package.Internal.Gccgoflags...) for _, f := range gofiles { - args = append(args, mkAbs(p.Dir, f)) + f := mkAbs(p.Dir, f) + // Overlay files if necessary. + // See comment on gctoolchain.gc about overlay TODOs + f, _ = fsys.OverlayPath(f) + args = append(args, f) } output, err = b.runOut(a, p.Dir, nil, args) @@ -172,9 +198,9 @@ func (tools gccgoToolchain) asm(b *Builder, a *Action, sfiles []string) ([]strin base := filepath.Base(sfile) ofile := a.Objdir + base[:len(base)-len(".s")] + ".o" ofiles = append(ofiles, ofile) - sfile = mkAbs(p.Dir, sfile) + sfile, _ = fsys.OverlayPath(mkAbs(p.Dir, sfile)) defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch} - if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath) } defs = tools.maybePIC(defs) @@ -244,7 +270,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string } readCgoFlags := func(flagsFile string) error { - flags, err := ioutil.ReadFile(flagsFile) + flags, err := os.ReadFile(flagsFile) if err != nil { return err } @@ -531,7 +557,7 @@ func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error cfile = mkAbs(p.Dir, cfile) defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch} defs = append(defs, b.gccArchArgs()...) - if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) } compiler := envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch)) @@ -568,14 +594,19 @@ func gccgoPkgpath(p *load.Package) string { return p.ImportPath } -func gccgoCleanPkgpath(p *load.Package) string { - clean := func(r rune) rune { - switch { - case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', - '0' <= r && r <= '9': - return r +var gccgoToSymbolFuncOnce sync.Once +var gccgoToSymbolFunc func(string) string + +func (tools gccgoToolchain) gccgoCleanPkgpath(b *Builder, p *load.Package) string { + gccgoToSymbolFuncOnce.Do(func() { + fn, err := pkgpath.ToSymbolFunc(tools.compiler(), b.WorkDir) + if err != nil { + fmt.Fprintf(os.Stderr, "cmd/go: %v\n", err) + base.SetExitStatus(2) + base.Exit() } - return '_' - } - return strings.Map(clean, gccgoPkgpath(p)) + gccgoToSymbolFunc = fn + }) + + return gccgoToSymbolFunc(gccgoPkgpath(p)) } diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go index dad3b10111..ba7c7c2fbb 100644 --- a/src/cmd/go/internal/work/init.go +++ b/src/cmd/go/internal/work/init.go @@ -9,7 +9,8 @@ package work import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" + "cmd/go/internal/modload" "cmd/internal/objabi" "cmd/internal/sys" "flag" @@ -21,9 +22,12 @@ import ( ) func BuildInit() { - load.ModInit() + modload.Init() instrumentInit() buildModeInit() + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } // Make sure -pkgdir is absolute, because we run commands // in different directories. @@ -37,6 +41,13 @@ func BuildInit() { cfg.BuildPkgdir = p } + // Make sure CC and CXX are absolute paths + for _, key := range []string{"CC", "CXX"} { + if path := cfg.Getenv(key); !filepath.IsAbs(path) && path != "" && path != filepath.Base(path) { + base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path) + } + } + // For each experiment that has been enabled in the toolchain, define a // build tag with the same name but prefixed by "goexperiment." which can be // used for compiling alternative files for the experiment. This allows @@ -68,7 +79,7 @@ func instrumentInit() { } if cfg.BuildRace { if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) { - fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) + fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64\n", flag.Args()[0]) base.SetExitStatus(2) base.Exit() } @@ -121,7 +132,7 @@ func buildModeInit() { codegenArg = "-fPIC" } else { switch cfg.Goos { - case "darwin": + case "darwin", "ios": switch cfg.Goarch { case "arm64": codegenArg = "-shared" @@ -157,6 +168,9 @@ func buildModeInit() { ldBuildmode = "pie" case "windows": ldBuildmode = "pie" + case "ios": + codegenArg = "-shared" + ldBuildmode = "pie" case "darwin": switch cfg.Goarch { case "arm64": @@ -227,7 +241,8 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") + forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1", + "-linkshared") codegenArg = "-dynlink" forcedGcflags = append(forcedGcflags, "-linkshared") // TODO(mwhudson): remove -w when that gets fixed in linker. @@ -252,36 +267,20 @@ func buildModeInit() { switch cfg.BuildMod { case "": - // ok + // Behavior will be determined automatically, as if no flag were passed. case "readonly", "vendor", "mod": - if !cfg.ModulesEnabled && !inGOFLAGS("-mod") { + if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") { base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod) } default: base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod) } if !cfg.ModulesEnabled { - if cfg.ModCacheRW && !inGOFLAGS("-modcacherw") { + if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") { base.Fatalf("build flag -modcacherw only valid when using modules") } - if cfg.ModFile != "" && !inGOFLAGS("-mod") { + if cfg.ModFile != "" && !base.InGOFLAGS("-mod") { base.Fatalf("build flag -modfile only valid when using modules") } } } - -func inGOFLAGS(flag string) bool { - for _, goflag := range base.GOFLAGS() { - name := goflag - if strings.HasPrefix(name, "--") { - name = name[1:] - } - if i := strings.Index(name, "="); i >= 0 { - name = name[:i] - } - if name == flag { - return true - } - } - return false -} diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go index d2a2697f0f..36bbab37ee 100644 --- a/src/cmd/go/internal/work/security.go +++ b/src/cmd/go/internal/work/security.go @@ -42,8 +42,8 @@ import ( var re = lazyregexp.New var validCompilerFlags = []*lazyregexp.Regexp{ - re(`-D([A-Za-z_].*)`), - re(`-U([A-Za-z_]*)`), + re(`-D([A-Za-z_][A-Za-z0-9_]*)(=[^@\-]*)?`), + re(`-U([A-Za-z_][A-Za-z0-9_]*)`), re(`-F([^@\-].*)`), re(`-I([^@\-].*)`), re(`-O`), @@ -51,8 +51,8 @@ var validCompilerFlags = []*lazyregexp.Regexp{ re(`-W`), re(`-W([^@,]+)`), // -Wall but not -Wa,-foo. re(`-Wa,-mbig-obj`), - re(`-Wp,-D([A-Za-z_].*)`), - re(`-Wp,-U([A-Za-z_]*)`), + re(`-Wp,-D([A-Za-z_][A-Za-z0-9_]*)(=[^@,\-]*)?`), + re(`-Wp,-U([A-Za-z_][A-Za-z0-9_]*)`), re(`-ansi`), re(`-f(no-)?asynchronous-unwind-tables`), re(`-f(no-)?blocks`), @@ -132,6 +132,7 @@ var validCompilerFlagsWithNextArg = []string{ "-U", "-I", "-framework", + "-include", "-isysroot", "-isystem", "--sysroot", @@ -178,7 +179,7 @@ var validLinkerFlags = []*lazyregexp.Regexp{ re(`-Wl,-berok`), re(`-Wl,-Bstatic`), re(`-Wl,-Bsymbolic-functions`), - re(`-WL,-O([^@,\-][^,]*)?`), + re(`-Wl,-O([^@,\-][^,]*)?`), re(`-Wl,-d[ny]`), re(`-Wl,--disable-new-dtags`), re(`-Wl,-e[=,][a-zA-Z0-9]*`), diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go index 11e74f29c6..4f2e0eb21a 100644 --- a/src/cmd/go/internal/work/security_test.go +++ b/src/cmd/go/internal/work/security_test.go @@ -13,6 +13,7 @@ var goodCompilerFlags = [][]string{ {"-DFOO"}, {"-Dfoo=bar"}, {"-Ufoo"}, + {"-Ufoo1"}, {"-F/Qt"}, {"-I/"}, {"-I/etc/passwd"}, @@ -24,6 +25,8 @@ var goodCompilerFlags = [][]string{ {"-Wall"}, {"-Wp,-Dfoo=bar"}, {"-Wp,-Ufoo"}, + {"-Wp,-Dfoo1"}, + {"-Wp,-Ufoo1"}, {"-fobjc-arc"}, {"-fno-objc-arc"}, {"-fomit-frame-pointer"}, @@ -62,6 +65,8 @@ var goodCompilerFlags = [][]string{ {"-I", "=/usr/include/libxml2"}, {"-I", "dir"}, {"-I", "$SYSROOT/dir"}, + {"-isystem", "/usr/include/mozjs-68"}, + {"-include", "/usr/include/mozjs-68/RequiredDefines.h"}, {"-framework", "Chocolate"}, {"-x", "c"}, {"-v"}, @@ -78,6 +83,8 @@ var badCompilerFlags = [][]string{ {"-O@1"}, {"-Wa,-foo"}, {"-W@foo"}, + {"-Wp,-DX,-D@X"}, + {"-Wp,-UX,-U@X"}, {"-g@gdb"}, {"-g-gdb"}, {"-march=@dawn"}, @@ -91,6 +98,7 @@ var badCompilerFlags = [][]string{ {"-I", "@foo"}, {"-I", "-foo"}, {"-I", "=@obj"}, + {"-include", "@foo"}, {"-framework", "-Caffeine"}, {"-framework", "@Home"}, {"-x", "--c"}, diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go index 37bb7d6d27..9cc44da84d 100644 --- a/src/cmd/go/main.go +++ b/src/cmd/go/main.go @@ -75,10 +75,11 @@ func init() { modload.HelpModules, modget.HelpModuleGet, modfetch.HelpModuleAuth, - modfetch.HelpModulePrivate, help.HelpPackages, + modfetch.HelpPrivate, test.HelpTestflag, test.HelpTestfunc, + modget.HelpVCS, } } diff --git a/src/cmd/go/proxy_test.go b/src/cmd/go/proxy_test.go index 42972f5b2a..e390c73a9c 100644 --- a/src/cmd/go/proxy_test.go +++ b/src/cmd/go/proxy_test.go @@ -12,7 +12,7 @@ import ( "flag" "fmt" "io" - "io/ioutil" + "io/fs" "log" "net" "net/http" @@ -74,12 +74,12 @@ func StartProxy() { var modList []module.Version func readModList() { - infos, err := ioutil.ReadDir("testdata/mod") + files, err := os.ReadDir("testdata/mod") if err != nil { log.Fatal(err) } - for _, info := range infos { - name := info.Name() + for _, f := range files { + name := f.Name() if !strings.HasSuffix(name, ".txt") { continue } @@ -335,7 +335,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { if testing.Verbose() { fmt.Fprintf(os.Stderr, "go proxy: no archive %s %s: %v\n", path, vers, err) } - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { http.NotFound(w, r) } else { http.Error(w, "cannot load archive", 500) @@ -443,7 +443,7 @@ func readArchive(path, vers string) (*txtar.Archive, error) { return a }).(*txtar.Archive) if a == nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return a, nil } @@ -470,13 +470,13 @@ func proxyGoSum(path, vers string) ([]byte, error) { } h1, err := dirhash.Hash1(names, func(name string) (io.ReadCloser, error) { data := files[name] - return ioutil.NopCloser(bytes.NewReader(data)), nil + return io.NopCloser(bytes.NewReader(data)), nil }) if err != nil { return nil, err } h1mod, err := dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(gomod)), nil + return io.NopCloser(bytes.NewReader(gomod)), nil }) if err != nil { return nil, err diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go index 986646252a..dfaa40548e 100644 --- a/src/cmd/go/script_test.go +++ b/src/cmd/go/script_test.go @@ -14,7 +14,7 @@ import ( "fmt" "go/build" "internal/testenv" - "io/ioutil" + "io/fs" "os" "os/exec" "path/filepath" @@ -39,9 +39,7 @@ import ( // TestScript runs the tests in testdata/script/*.txt. func TestScript(t *testing.T) { testenv.MustHaveGoBuild(t) - if skipExternal { - t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) - } + testenv.SkipIfShortAndSlow(t) files, err := filepath.Glob("testdata/script/*.txt") if err != nil { @@ -136,12 +134,16 @@ func (ts *testScript) setup() { "GOSUMDB=" + testSumDBVerifierKey, "GONOPROXY=", "GONOSUMDB=", + "GOVCS=*:all", "PWD=" + ts.cd, tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"), "devnull=" + os.DevNull, "goversion=" + goVersion(ts), ":=" + string(os.PathListSeparator), } + if !testenv.HasExternalNetwork() { + ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic") + } if runtime.GOOS == "plan9" { ts.env = append(ts.env, "path="+testBin+string(filepath.ListSeparator)+os.Getenv("path")) @@ -217,7 +219,7 @@ func (ts *testScript) run() { for _, f := range a.Files { name := ts.mkabs(ts.expand(f.Name, false)) ts.check(os.MkdirAll(filepath.Dir(name), 0777)) - ts.check(ioutil.WriteFile(name, f.Data, 0666)) + ts.check(os.WriteFile(name, f.Data, 0666)) } // With -v or -testwork, start log with full environment. @@ -374,19 +376,19 @@ var ( func isCaseSensitive(t *testing.T) bool { onceCaseSensitive.Do(func() { - tmpdir, err := ioutil.TempDir("", "case-sensitive") + tmpdir, err := os.MkdirTemp("", "case-sensitive") if err != nil { t.Fatal("failed to create directory to determine case-sensitivity:", err) } defer os.RemoveAll(tmpdir) fcap := filepath.Join(tmpdir, "FILE") - if err := ioutil.WriteFile(fcap, []byte{}, 0644); err != nil { + if err := os.WriteFile(fcap, []byte{}, 0644); err != nil { t.Fatal("error writing file to determine case-sensitivity:", err) } flow := filepath.Join(tmpdir, "file") - _, err = ioutil.ReadFile(flow) + _, err = os.ReadFile(flow) switch { case err == nil: caseSensitive = false @@ -447,9 +449,9 @@ func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) { for _, file := range args { file = ts.mkabs(file) - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) ts.check(err) - ts.check(ioutil.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666)) + ts.check(os.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666)) } } @@ -500,7 +502,7 @@ func (ts *testScript) cmdChmod(want simpleStatus, args []string) { ts.fatalf("usage: chmod perm paths...") } perm, err := strconv.ParseUint(args[0], 0, 32) - if err != nil || perm&uint64(os.ModePerm) != perm { + if err != nil || perm&uint64(fs.ModePerm) != perm { ts.fatalf("invalid mode: %s", args[0]) } for _, arg := range args[1:] { @@ -508,7 +510,7 @@ func (ts *testScript) cmdChmod(want simpleStatus, args []string) { if !filepath.IsAbs(path) { path = filepath.Join(ts.cd, arg) } - err := os.Chmod(path, os.FileMode(perm)) + err := os.Chmod(path, fs.FileMode(perm)) ts.check(err) } } @@ -554,12 +556,12 @@ func (ts *testScript) doCmdCmp(args []string, env, quiet bool) { } else if name1 == "stderr" { text1 = ts.stderr } else { - data, err := ioutil.ReadFile(ts.mkabs(name1)) + data, err := os.ReadFile(ts.mkabs(name1)) ts.check(err) text1 = string(data) } - data, err := ioutil.ReadFile(ts.mkabs(name2)) + data, err := os.ReadFile(ts.mkabs(name2)) ts.check(err) text2 = string(data) @@ -595,7 +597,7 @@ func (ts *testScript) cmdCp(want simpleStatus, args []string) { var ( src string data []byte - mode os.FileMode + mode fs.FileMode ) switch arg { case "stdout": @@ -611,14 +613,14 @@ func (ts *testScript) cmdCp(want simpleStatus, args []string) { info, err := os.Stat(src) ts.check(err) mode = info.Mode() & 0777 - data, err = ioutil.ReadFile(src) + data, err = os.ReadFile(src) ts.check(err) } targ := dst if dstDir { targ = filepath.Join(dst, filepath.Base(src)) } - err := ioutil.WriteFile(targ, data, mode) + err := os.WriteFile(targ, data, mode) switch want { case failure: if err == nil { @@ -894,7 +896,7 @@ func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name st isGrep := name == "grep" if isGrep { name = args[1] // for error messages - data, err := ioutil.ReadFile(ts.mkabs(args[1])) + data, err := os.ReadFile(ts.mkabs(args[1])) ts.check(err) text = string(data) } @@ -1256,7 +1258,12 @@ func (ts *testScript) parse(line string) command { if cmd.name != "" { cmd.args = append(cmd.args, arg) - isRegexp = false // Commands take only one regexp argument, so no subsequent args are regexps. + // Commands take only one regexp argument (after the optional flags), + // so no subsequent args are regexps. Liberally assume an argument that + // starts with a '-' is a flag. + if len(arg) == 0 || arg[0] != '-' { + isRegexp = false + } return } diff --git a/src/cmd/go/testdata/addmod.go b/src/cmd/go/testdata/addmod.go index d9c3aab9c4..58376b7ed4 100644 --- a/src/cmd/go/testdata/addmod.go +++ b/src/cmd/go/testdata/addmod.go @@ -22,7 +22,7 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" + "io/fs" "log" "os" "os/exec" @@ -57,7 +57,7 @@ func main() { log.SetFlags(0) var err error - tmpdir, err = ioutil.TempDir("", "addmod-") + tmpdir, err = os.MkdirTemp("", "addmod-") if err != nil { log.Fatal(err) } @@ -81,7 +81,7 @@ func main() { exitCode := 0 for _, arg := range flag.Args() { - if err := ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { fatalf("%v", err) } run(goCmd, "get", "-d", arg) @@ -97,13 +97,13 @@ func main() { continue } path, vers, dir := f[0], f[1], f[2] - mod, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) + mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } - info, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) + info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 @@ -121,13 +121,13 @@ func main() { {Name: ".info", Data: info}, } dir = filepath.Clean(dir) - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if !info.Mode().IsRegular() { + err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { + if !info.Type().IsRegular() { return nil } name := info.Name() if name == "go.mod" || strings.HasSuffix(name, ".go") { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return err } @@ -143,7 +143,7 @@ func main() { data := txtar.Format(a) target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt") - if err := ioutil.WriteFile(target, data, 0666); err != nil { + if err := os.WriteFile(target, data, 0666); err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue diff --git a/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt b/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt new file mode 100644 index 0000000000..a86951981e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt @@ -0,0 +1,12 @@ +Module example.com/ambiguous/a/b is a suffix of example.com/a. +This version contains no package. +-- .mod -- +module example.com/ambiguous/a/b + +go 1.16 +-- .info -- +{"Version":"v0.0.0-empty"} +-- go.mod -- +module example.com/ambiguous/a/b + +go 1.16 diff --git a/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt new file mode 100644 index 0000000000..bb438262e1 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt @@ -0,0 +1,18 @@ +Module example.com/ambiguous/a is a prefix of example.com/a/b. +It contains package example.com/a/b. +-- .mod -- +module example.com/ambiguous/a + +go 1.16 + +require example.com/ambiguous/a/b v0.0.0-empty +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/ambiguous/a + +go 1.16 + +require example.com/ambiguous/a/b v0.0.0-empty +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt new file mode 100644 index 0000000000..c883d8a774 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-exclude"} +-- .mod -- +module example.com/cmd + +go 1.16 + +exclude rsc.io/quote v1.5.2 +-- go.mod -- +module example.com/cmd + +go 1.16 + +exclude rsc.io/quote v1.5.2 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt new file mode 100644 index 0000000000..7670f29ffd --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-newerself"} +-- .mod -- +module example.com/cmd + +go 1.16 + +require example.com/cmd v1.0.0 +-- go.mod -- +module example.com/cmd + +go 1.16 + +require example.com/cmd v1.0.0 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt new file mode 100644 index 0000000000..581a496035 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-replace"} +-- .mod -- +module example.com/cmd + +go 1.16 + +replace rsc.io/quote => rsc.io/quote v1.5.2 +-- go.mod -- +module example.com/cmd + +go 1.16 + +replace rsc.io/quote => rsc.io/quote v1.5.2 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt new file mode 100644 index 0000000000..ee439384d2 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt @@ -0,0 +1,27 @@ +example.com/cmd contains main packages. + +v1.0.0 is the latest non-retracted version. Other versions contain errors or +detectable problems. + +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/cmd + +go 1.16 +-- go.mod -- +module example.com/cmd + +go 1.16 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt new file mode 100644 index 0000000000..9298afb1fb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt @@ -0,0 +1,30 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.9.0"} +-- .mod -- +module example.com/cmd + +go 1.16 + +// this is a bad version +retract v1.9.0 +-- go.mod -- +module example.com/cmd + +go 1.16 + +// this is a bad version +retract v1.9.0 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt new file mode 100644 index 0000000000..f8e623d56f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt @@ -0,0 +1,10 @@ +-- .mod -- +module example.com/retract/ambiguous/nested + +go 1.16 + +retract v1.9.0-bad // nested modules are bad +-- .info -- +{"Version":"v1.9.0-bad"} +-- nested.go -- +package nested diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt new file mode 100644 index 0000000000..5ee01391a2 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .mod -- +module example.com/retract/ambiguous/other + +go 1.16 + +require example.com/retract/ambiguous v1.0.0 +-- .info -- +{"Version":"v1.0.0"} +-- other.go -- +package other + +import _ "example.com/retract/ambiguous/nested" diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt new file mode 100644 index 0000000000..c8eeb1654f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt @@ -0,0 +1,9 @@ +-- .mod -- +module example.com/retract/ambiguous + +go 1.16 +-- .info -- +{"Version":"v1.0.0"} +-- nested/nested.go -- +package nested + diff --git a/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt new file mode 100644 index 0000000000..a987685e24 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt @@ -0,0 +1,19 @@ +The v1.0.0 release of example.com/retract/incompatible retracts +v2.0.0+incompatible. + +-- .mod -- +module example.com/retract/incompatible + +go 1.16 + +retract v2.0.0+incompatible +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/retract/incompatible + +go 1.16 + +retract v2.0.0+incompatible +-- incompatible.go -- +package incompatible diff --git a/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt new file mode 100644 index 0000000000..c668dbb7a9 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt @@ -0,0 +1,9 @@ +The v1.0.0 release of example.com/retract/incompatible retracts +v2.0.0+incompatible. + +-- .mod -- +module example.com/retract/incompatible +-- .info -- +{"Version":"v2.0.0+incompatible"} +-- incompatible.go -- +package incompatible diff --git a/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt index 2023c7b096..1d8d81071e 100644 --- a/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt +++ b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt @@ -6,3 +6,5 @@ module example.com/retract/missingmod go 1.14 -- .info -- {"Version":"v1.0.0"} +-- missingmod.go -- +package missingmod diff --git a/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt new file mode 100644 index 0000000000..25c4ff1b1f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt @@ -0,0 +1,16 @@ +Module example.com/retract/rename is renamed in a later version. + +This happens frequently when a repository is renamed or when a go.mod file +is added for the first time with a custom module path. +-- .info -- +{"Version":"v1.0.0-bad"} +-- .mod -- +module example.com/retract/rename + +go 1.16 +-- go.mod -- +module example.com/retract/rename + +go 1.16 +-- rename.go -- +package rename diff --git a/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt new file mode 100644 index 0000000000..9c08f713c4 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt @@ -0,0 +1,22 @@ +Module example.com/retract/rename is renamed in this version. + +This happens frequently when a repository is renamed or when a go.mod file +is added for the first time with a custom module path. +-- .info -- +{"Version":"v1.9.0-new"} +-- .mod -- +module example.com/retract/newname + +go 1.16 + +// bad +retract v1.0.0-bad +-- go.mod -- +module example.com/retract/newname + +go 1.16 + +// bad +retract v1.0.0-bad +-- newname.go -- +package newname diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt new file mode 100644 index 0000000000..8f9e49176c --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt @@ -0,0 +1,14 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible verison (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible/subpkg +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.com/split-incompatible/subpkg + +go 1.16 +-- subpkg.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt new file mode 100644 index 0000000000..35c3f27710 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt @@ -0,0 +1,10 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible verison (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible +-- .info -- +{"Version": "v2.0.0+incompatible"} +-- subpkg/subpkg.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt new file mode 100644 index 0000000000..917fc0f559 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt @@ -0,0 +1,10 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible verison (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible +-- .info -- +{"Version": "v2.1.0-pre+incompatible"} +-- README.txt -- +subpkg has moved to module example.com/split-incompatible/subpkg diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt new file mode 100644 index 0000000000..8c9de7a5f4 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous/nested + +go 1.16 +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.net/ambiguous/nested + +go 1.16 +-- pkg/pkg.go -- +// Package pkg exists in both example.net/ambiguous v0.1.0 +// and example.net/ambiguous/nested v0.1.0 +package pkg diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt new file mode 100644 index 0000000000..8fa6d83346 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous + +go 1.16 +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.net/ambiguous + +go 1.16 +-- nested/pkg/pkg.go -- +// Package pkg exists in both example.net/ambiguous v0.1.0 +// and example.net/ambiguous/nested v0.1.0 +package pkg diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt new file mode 100644 index 0000000000..7589ad76a3 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt @@ -0,0 +1,18 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous + +go 1.16 +-- .info -- +{"Version": "v0.2.0"} +-- go.mod -- +module example.net/ambiguous + +go 1.16 +-- nested/pkg/README.txt -- +// Package pkg no longer exists in this module at v0.2.0. +// Find it in module example.net/ambiguous/nested instead. diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt new file mode 100644 index 0000000000..207e86a73c --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt @@ -0,0 +1,17 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- README.txt -- +We will add the package example.net/pkgadded in v1.1.0, +and example.net/pkgadded/subpkg in v1.2.0. diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt new file mode 100644 index 0000000000..1c88de2dd6 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.1.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- README.txt -- +We will add the package example.net/pkgadded/subpkg in v1.2.0. +-- pkgadded.go -- +// Package pkgadded was added in v1.1.0. +package pkgadded diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt new file mode 100644 index 0000000000..922951ac37 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt @@ -0,0 +1,20 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.2.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- pkgadded.go -- +// Package pkgadded was added in v1.1.0. +package pkgadded +-- subpkg/subpkg.go -- +// Package subpkg was added in v1.2.0. +package subpkg diff --git a/src/cmd/go/testdata/savedir.go b/src/cmd/go/testdata/savedir.go index 48a6318860..d469c31a91 100644 --- a/src/cmd/go/testdata/savedir.go +++ b/src/cmd/go/testdata/savedir.go @@ -17,7 +17,7 @@ package main import ( "flag" "fmt" - "io/ioutil" + "io/fs" "log" "os" "path/filepath" @@ -48,7 +48,7 @@ func main() { a := new(txtar.Archive) dir = filepath.Clean(dir) - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { if path == dir { return nil } @@ -59,10 +59,10 @@ func main() { } return nil } - if !info.Mode().IsRegular() { + if !info.Type().IsRegular() { return nil } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { log.Fatal(err) } diff --git a/src/cmd/go/testdata/script/build_cache_arch_mode.txt b/src/cmd/go/testdata/script/build_cache_arch_mode.txt index 7e751d02b9..931827fbde 100644 --- a/src/cmd/go/testdata/script/build_cache_arch_mode.txt +++ b/src/cmd/go/testdata/script/build_cache_arch_mode.txt @@ -1,18 +1,8 @@ -# Issue 9737: verify that GOARM and GO386 affect the computed build ID +# Issue 9737: verify that GOARM affects the computed build ID [short] skip -# 386 -cd $GOPATH/src/mycmd -env GOOS=linux -env GOARCH=386 -env GO386=387 -go install mycmd -env GO386=sse2 -stale mycmd - # arm -cd $GOPATH/src/mycmd env GOOS=linux env GOARCH=arm env GOARM=5 @@ -21,7 +11,11 @@ env GOARM=7 stale mycmd --- mycmd/x.go -- +-- go.mod -- +module mycmd + +go 1.16 +-- x.go -- package main -func main() {}
\ No newline at end of file +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_disabled.txt b/src/cmd/go/testdata/script/build_cache_disabled.txt index 2e1327880b..8b005c857f 100644 --- a/src/cmd/go/testdata/script/build_cache_disabled.txt +++ b/src/cmd/go/testdata/script/build_cache_disabled.txt @@ -18,8 +18,6 @@ env GOCACHE=off go doc fmt stdout Printf -go fmt . - ! go tool compile -h stderr usage: @@ -40,6 +38,12 @@ stdout rsc.io/quote go mod verify + +# Commands that load but don't build packages should work. +go fmt . + +go doc . + -- main.go -- package main diff --git a/src/cmd/go/testdata/script/build_cd_gopath_different.txt b/src/cmd/go/testdata/script/build_cd_gopath_different.txt index 698b3d70f4..a7a4bf412d 100644 --- a/src/cmd/go/testdata/script/build_cd_gopath_different.txt +++ b/src/cmd/go/testdata/script/build_cd_gopath_different.txt @@ -1,4 +1,5 @@ [gccgo] skip 'gccgo does not support -ldflags -X' +env GO111MODULE=off go build run_go.go # Apply identity function to GOPATH diff --git a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt index 42f1cc1a74..88a24de814 100644 --- a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt +++ b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt @@ -11,7 +11,11 @@ go build -x -o $WORK/exe2$GOEXE cgotest cmp $WORK/exe1$GOEXE $WORK/exe2$GOEXE --- cgotest/m.go -- +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- package cgotest import "C" diff --git a/src/cmd/go/testdata/script/build_dash_x.txt b/src/cmd/go/testdata/script/build_dash_x.txt index 3082095c5c..6fd5bbe182 100644 --- a/src/cmd/go/testdata/script/build_dash_x.txt +++ b/src/cmd/go/testdata/script/build_dash_x.txt @@ -46,4 +46,4 @@ func main() { -- header.txt -- set -e -- hello.txt -- -hello
\ No newline at end of file +hello diff --git a/src/cmd/go/testdata/script/build_exe.txt b/src/cmd/go/testdata/script/build_exe.txt index fd13259fcc..a994d17088 100644 --- a/src/cmd/go/testdata/script/build_exe.txt +++ b/src/cmd/go/testdata/script/build_exe.txt @@ -1,12 +1,16 @@ -# go build with -o and -buildmode=exe should on a non-main package should throw an error +# go build with -o and -buildmode=exe should report an error on a non-main package. -! go build -buildmode=exe -o out$GOEXE not_main +! go build -buildmode=exe -o out$GOEXE ./not_main stderr '-buildmode=exe requires exactly one main package' ! exists out$GOEXE -! go build -buildmode=exe -o out$GOEXE main_one main_two +! go build -buildmode=exe -o out$GOEXE ./main_one ./main_two stderr '-buildmode=exe requires exactly one main package' ! exists out$GOEXE +-- go.mod -- +module m + +go 1.16 -- not_main/not_main.go -- package not_main @@ -18,4 +22,4 @@ func main() {} -- main_two/main_two.go -- package main -func main() {}
\ No newline at end of file +func main() {} diff --git a/src/cmd/go/testdata/script/build_gopath_order.txt b/src/cmd/go/testdata/script/build_gopath_order.txt index ac26c28a9f..caf25022e4 100644 --- a/src/cmd/go/testdata/script/build_gopath_order.txt +++ b/src/cmd/go/testdata/script/build_gopath_order.txt @@ -3,6 +3,7 @@ # -I arguments to compiler could end up not in GOPATH order, # leading to unexpected import resolution in the compiler. +env GO111MODULE=off env GOPATH=$WORK/p1${:}$WORK/p2 mkdir $WORK/p1/src/foo $WORK/p2/src/baz mkdir $WORK/p2/pkg/${GOOS}_${GOARCH} $WORK/p1/src/bar @@ -32,4 +33,4 @@ bad -- bar.go -- package bar import _ "baz" -import _ "foo"
\ No newline at end of file +import _ "foo" diff --git a/src/cmd/go/testdata/script/build_i_deprecate.txt b/src/cmd/go/testdata/script/build_i_deprecate.txt new file mode 100644 index 0000000000..71356e5321 --- /dev/null +++ b/src/cmd/go/testdata/script/build_i_deprecate.txt @@ -0,0 +1,24 @@ +# Check that deprecation warnings are printed when the -i flag is used. +# TODO(golang.org/issue/41696): remove the -i flag after Go 1.16, and this test. + +go build -n -i +stderr '^go build: -i flag is deprecated$' + +go install -n -i +stderr '^go install: -i flag is deprecated$' + +go test -n -i +stderr '^go test: -i flag is deprecated$' + + +# 'go clean -i' should not print a deprecation warning. +# It will continue working. +go clean -i . +! stderr . + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m diff --git a/src/cmd/go/testdata/script/build_import_comment.txt b/src/cmd/go/testdata/script/build_import_comment.txt index 0ab643914d..b500340bfb 100644 --- a/src/cmd/go/testdata/script/build_import_comment.txt +++ b/src/cmd/go/testdata/script/build_import_comment.txt @@ -1,6 +1,6 @@ -# TODO: add a go.mod file and test with GO111MODULE explicitly on and off. -# We only report the 'expects import' error when modules are disabled. -# Do we report comment parse errors or conflicts in module mode? We shouldn't. +# Test in GOPATH mode first. +env GO111MODULE=off +cd m # Import comment matches go build -n works.go @@ -17,31 +17,52 @@ stderr 'cannot parse import comment' ! go build -n conflict.go stderr 'found import comments' --- bad.go -- + +# Test in module mode. +# We ignore import comments, so these commands should succeed. +env GO111MODULE=on + +# Import comment matches +go build -n works.go + +# Import comment mismatch +go build -n wrongplace.go + +# Import comment syntax error +go build -n bad.go + +# Import comment conflict +go build -n conflict.go + +-- m/go.mod -- +module m + +go 1.16 +-- m/bad.go -- package p -import "bad" --- conflict.go -- +import "m/bad" +-- m/conflict.go -- package p -import "conflict" --- works.go -- +import "m/conflict" +-- m/works.go -- package p -import _ "works/x" --- wrongplace.go -- +import _ "m/works/x" +-- m/wrongplace.go -- package p -import "wrongplace" --- bad/bad.go -- +import "m/wrongplace" +-- m/bad/bad.go -- package bad // import --- conflict/a.go -- +-- m/conflict/a.go -- package conflict // import "a" --- conflict/b.go -- +-- m/conflict/b.go -- package conflict /* import "b" */ --- works/x/x.go -- -package x // import "works/x" --- works/x/x1.go -- +-- m/works/x/x.go -- +package x // import "m/works/x" +-- m/works/x/x1.go -- package x // important! not an import comment --- wrongplace/x.go -- +-- m/wrongplace/x.go -- package x // import "my/x" diff --git a/src/cmd/go/testdata/script/build_import_cycle.txt b/src/cmd/go/testdata/script/build_import_cycle.txt index 0154305c27..16e4e87dae 100644 --- a/src/cmd/go/testdata/script/build_import_cycle.txt +++ b/src/cmd/go/testdata/script/build_import_cycle.txt @@ -1,3 +1,6 @@ +# mod_import_cycle covers this error in module mode. +env GO111MODULE=off + ! go build selfimport stderr -count=1 'import cycle not allowed' diff --git a/src/cmd/go/testdata/script/build_internal.txt b/src/cmd/go/testdata/script/build_internal.txt index 6fcc4e02aa..25aa18cfcb 100644 --- a/src/cmd/go/testdata/script/build_internal.txt +++ b/src/cmd/go/testdata/script/build_internal.txt @@ -1,44 +1,63 @@ # Test internal package errors are handled -go list ./testinternal3 +cd testinternal3 +go list . stdout 'testinternal3' # Test internal cache -env GOPATH=$WORK/gopath/src/testinternal4 -! go build p +cd ../testinternal4 +! go build testinternal4/p stderr 'internal' # Test internal packages outside GOROOT are respected -! go build -v ./testinternal2 -stderr 'testinternal2(\/|\\)p\.go\:3\:8\: use of internal package .*internal/w not allowed' +cd ../testinternal2 +! go build -v . +stderr 'p\.go:3:8: use of internal package .*internal/w not allowed' [gccgo] skip # gccgo does not have GOROOT -! go build -v ./testinternal -stderr 'testinternal(\/|\\)p\.go\:3\:8\: use of internal package net/http/internal not allowed' +cd ../testinternal +! go build -v . +stderr 'p\.go:3:8: use of internal package net/http/internal not allowed' +-- testinternal/go.mod -- +module testinternal + +go 1.16 -- testinternal/p.go -- package p import _ "net/http/internal" +-- testinternal2/go.mod -- +module testinternal2 + +go 1.16 -- testinternal2/p.go -- package p import _ "./x/y/z/internal/w" -- testinternal2/x/y/z/internal/w/w.go -- package w +-- testinternal3/go.mod -- +module testinternal3 + +go 1.16 -- testinternal3/t.go -- package t import _ "internal/does-not-exist" --- testinternal4/src/p/p.go -- +-- testinternal4/go.mod -- +module testinternal4 + +go 1.16 +-- testinternal4/p/p.go -- package p import ( - _ "q/internal/x" - _ "q/j" + _ "testinternal4/q/internal/x" + _ "testinternal4/q/j" ) --- testinternal4/src/q/internal/x/x.go -- +-- testinternal4/q/internal/x/x.go -- package x --- testinternal4/src/q/j/j.go -- +-- testinternal4/q/j/j.go -- package j -import _ "q/internal/x" +import _ "testinternal4/q/internal/x" diff --git a/src/cmd/go/testdata/script/build_issue6480.txt b/src/cmd/go/testdata/script/build_issue6480.txt index 857f364e81..cf1e9ea6c2 100644 --- a/src/cmd/go/testdata/script/build_issue6480.txt +++ b/src/cmd/go/testdata/script/build_issue6480.txt @@ -8,7 +8,7 @@ # Install some commands to compare mtimes env GOBIN=$WORK/tmp/bin -go install now mtime before +go install m/now m/mtime m/before # Initial builds go test -c -test.bench=XXX errors @@ -34,6 +34,10 @@ exec $GOBIN/mtime errors2.test cp stdout errors2_mod_time.txt exec $GOBIN/before start_time.txt errors2_mod_time.txt +-- go.mod -- +module m + +go 1.16 -- now/now.go -- // Writes time.Now() to a file package main @@ -77,7 +81,6 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" "os" "time" ) @@ -96,7 +99,7 @@ func truncateLike(t, p time.Time) time.Time { func main() { var t1 time.Time - b1, err := ioutil.ReadFile(os.Args[1]) + b1, err := os.ReadFile(os.Args[1]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -107,7 +110,7 @@ func main() { } var t2 time.Time - b2, err := ioutil.ReadFile(os.Args[2]) + b2, err := os.ReadFile(os.Args[2]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -122,4 +125,4 @@ func main() { fmt.Fprintf(os.Stderr, "time in %v (%v) is not before time in %v (%v)", os.Args[1], t1, os.Args[2], t2) os.Exit(1) } -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt index daa544d3f0..f1de1e4c71 100644 --- a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt +++ b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt @@ -4,7 +4,11 @@ go build -o linkx$GOEXE -ldflags -X=my.pkg.Text=linkXworked my.pkg/main exec ./linkx$GOEXE stderr '^linkXworked$' --- my.pkg/main/main.go -- +-- go.mod -- +module my.pkg + +go 1.16 +-- main/main.go -- package main import "my.pkg" @@ -12,7 +16,7 @@ import "my.pkg" func main() { println(pkg.Text) } --- my.pkg/pkg.go -- +-- pkg.go -- package pkg var Text = "unset" diff --git a/src/cmd/go/testdata/script/build_n_cgo.txt b/src/cmd/go/testdata/script/build_n_cgo.txt index 200d13760e..7aa77aea42 100644 --- a/src/cmd/go/testdata/script/build_n_cgo.txt +++ b/src/cmd/go/testdata/script/build_n_cgo.txt @@ -5,6 +5,10 @@ go build -n ! stderr '[/\\]\$WORK' +-- go.mod -- +module m + +go 1.16 -- main.go -- package main diff --git a/src/cmd/go/testdata/script/build_no_go.txt b/src/cmd/go/testdata/script/build_no_go.txt index 3fd7739fbb..b61d752274 100644 --- a/src/cmd/go/testdata/script/build_no_go.txt +++ b/src/cmd/go/testdata/script/build_no_go.txt @@ -16,6 +16,10 @@ stderr 'no Go files in ' ! go build ./exclude/empty stderr 'no Go files in ' +-- go.mod -- +module m + +go 1.16 -- empty/test/test_test.go -- package p -- empty/testxtest/test_test.go -- diff --git a/src/cmd/go/testdata/script/build_output.txt b/src/cmd/go/testdata/script/build_output.txt index e5a4852346..1e82950dbc 100644 --- a/src/cmd/go/testdata/script/build_output.txt +++ b/src/cmd/go/testdata/script/build_output.txt @@ -5,7 +5,7 @@ [windows] env NONEXE='' env GOBIN=$WORK/tmp/bin -go install isarchive & +go install m/isarchive & go build x.go exists -exec x$GOEXE @@ -18,6 +18,32 @@ go build -o myprog x.go exists -exec myprog ! exists myprogr.exe +! exists bin +go build -o bin/x x.go +exists -exec bin/x +rm bin + +! exists bin +go build -o bin/ x.go +exists -exec bin/x$GOEXE +rm bin + +[windows] ! exists bin +[windows] go build -o bin\x x.go +[windows] exists -exec bin\x +[windows] rm bin + +[windows] ! exists bin +[windows] go build -o bin\ x.go +[windows] exists -exec bin\x.exe +[windows] rm bin + +! exists bin +mkdir bin +go build -o bin x.go +exists -exec bin/x$GOEXE +rm bin + go build p.go ! exists p ! exists p.a @@ -55,6 +81,10 @@ exec $GOBIN/isarchive myatomic.a ! go build -o whatever cmd/gofmt sync/atomic stderr 'multiple packages' +-- go.mod -- +module m + +go 1.16 -- x.go -- package main @@ -84,4 +114,4 @@ func main() { fmt.Fprintf(os.Stderr, "file %s exists but is not an archive\n", os.Args[1]) os.Exit(1) } -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt new file mode 100644 index 0000000000..b11cd96014 --- /dev/null +++ b/src/cmd/go/testdata/script/build_overlay.txt @@ -0,0 +1,308 @@ +[short] skip + +# Test building in overlays. +# TODO(#39958): add a test case where the destination file in the replace map +# isn't a go file. Either completely exclude that case in fs.IsDirWithGoFiles +# if the compiler doesn't allow it, or test that it works all the way. +# TODO(#39958): add a test that both gc and gccgo assembly files can include .h +# files. + +# The main package (m) is contained in an overlay. It imports m/dir2 which has one +# file in an overlay and one file outside the overlay, which in turn imports m/dir, +# which only has source files in the overlay. + +cd m + +! go build . +go build -overlay overlay.json -o main$GOEXE . +exec ./main$goexe +stdout '^hello$' + +go build -overlay overlay.json -o print_abspath$GOEXE ./printpath +exec ./print_abspath$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath$GOEXE -trimpath ./printpath +exec ./print_trimpath$GOEXE +stdout ^m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath_two_files$GOEXE printpath/main.go printpath/other.go +exec ./print_trimpath_two_files$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]other.go + +go build -overlay overlay.json -o main_cgo_replace$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_quote$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_cgo_angle$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle$GOEXE +stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_call_asm$GOEXE ./call_asm +exec ./main_call_asm$GOEXE +! stdout . + +# Change the contents of a file in the overlay and ensure that makes the target stale +go install -overlay overlay.json ./test_cache +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^false$' +cp overlay/test_cache_different.go overlay/test_cache.go +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^true$' + +go list -compiled -overlay overlay.json -f '{{range .CompiledGoFiles}}{{. | printf "%s\n"}}{{end}}' ./cgo_hello_replace +cp stdout compiled_cgo_sources.txt +go run ../print_line_comments.go compiled_cgo_sources.txt +stdout $GOPATH[/\\]src[/\\]m[/\\]cgo_hello_replace[/\\]cgo_hello_replace.go +! stdout $GOPATH[/\\]src[/\\]m[/\\]overlay[/\\]hello.c + +# Run same tests but with gccgo. +env GO111MODULE=off +[!exec:gccgo] stop + +! go build -compiler=gccgo . +go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE . +exec ./main_gccgo$goexe +stdout '^hello$' + +go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath +exec ./print_abspath_gccgo$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath +exec ./print_trimpath_gccgo$GOEXE +stdout ^\.[/\\]printpath[/\\]main.go + + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_replace_gccgo$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_quote_gccgo$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_angle_gccgo$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_call_asm_gccgo$GOEXE ./call_asm +exec ./main_call_asm_gccgo$GOEXE +! stdout . + + +-- m/go.mod -- +// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) +module m + +go 1.16 + +-- m/dir2/h.go -- +package dir2 + +func PrintMessage() { + printMessage() +} +-- m/dir/foo.txt -- +The build action code currently expects the package directory +to exist, so it can run the compiler in that directory. +TODO(matloob): Remove this requirement. +-- m/printpath/about.txt -- +the actual code is in the overlay +-- m/overlay.json -- +{ + "Replace": { + "f.go": "overlay/f.go", + "dir/g.go": "overlay/dir_g.go", + "dir2/i.go": "overlay/dir2_i.go", + "printpath/main.go": "overlay/printpath.go", + "printpath/other.go": "overlay2/printpath2.go", + "call_asm/asm_gc.s": "overlay/asm_gc.s", + "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", + "test_cache/main.go": "overlay/test_cache.go", + "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", + "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", + "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", + "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + } +} +-- m/cgo_hello_replace/cgo_hello_replace.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/cgo_hello_replace/cgo_header.h -- + // Test that this header is replaced with one that has the proper declaration. +void say_goodbye(); + +-- m/cgo_hello_replace/hello.c -- +#include <stdio.h> + +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } + +-- m/overlay/f.go -- +package main + +import "m/dir2" + +func main() { + dir2.PrintMessage() +} +-- m/call_asm/main.go -- +package main + +func foo() // There will be a "missing function body" error if the assembly file isn't found. + +func main() { + foo() +} +-- m/overlay/dir_g.go -- +package dir + +import "fmt" + +func PrintMessage() { + fmt.Println("hello") +} +-- m/overlay/printpath.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func main() { + _, file, _, _ := runtime.Caller(0) + + // Since https://golang.org/cl/214286, the runtime's debug paths are + // slash-separated regardless of platform, so normalize them to system file + // paths. + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay2/printpath2.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func init() { + _, file, _, _ := runtime.Caller(0) + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay/dir2_i.go -- +package dir2 + +import "m/dir" + +func printMessage() { + dir.PrintMessage() +} +-- m/overlay/cgo_hello_quote.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_hello_angle.go -- +package main + +// #include <cgo_header.h> +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_head.h -- +void say_hello(); +-- m/overlay/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/overlay/asm_gc.s -- +// +build !gccgo + +TEXT ·foo(SB),0,$0 + RET + +-- m/overlay/asm_gccgo.s -- +// +build gccgo + +.globl main.foo +.text +main.foo: + ret + +-- m/overlay/test_cache.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("something") +} +-- m/overlay/test_cache_different.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("different") +} +-- m/cgo_hello_quote/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_angle/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } + +-- print_line_comments.go -- +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "strings" +) + +func main() { + compiledGoFilesArg := os.Args[1] + b, err := ioutil.ReadFile(compiledGoFilesArg) + if err != nil { + log.Fatal(err) + } + compiledGoFiles := strings.Split(strings.TrimSpace(string(b)), "\n") + for _, f := range compiledGoFiles { + b, err := ioutil.ReadFile(f) + if err != nil { + log.Fatal(err) + } + for _, line := range strings.Split(string(b), "\n") { + if strings.HasPrefix(line, "#line") || strings.HasPrefix(line, "//line") { + fmt.Println(line) + } + } + } +} diff --git a/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt index f36e90fea6..6a600cfb0a 100644 --- a/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt +++ b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt @@ -1,6 +1,9 @@ # Tests issue #18778 +[short] skip cd pkgs + +env GO111MODULE=off go build ./... ! stdout . go test ./... @@ -9,6 +12,10 @@ go list ./... stdout 'pkgs$' stdout 'pkgs/a' +-- pkgs/go.mod -- +module pkgs + +go 1.16 -- pkgs/a.go -- package x -- pkgs/a_test.go -- @@ -26,4 +33,4 @@ package a_test import "testing" func TestA(t *testing.T) { -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/build_plugin_non_main.txt b/src/cmd/go/testdata/script/build_plugin_non_main.txt index 996d87d961..e0bbbefb19 100644 --- a/src/cmd/go/testdata/script/build_plugin_non_main.txt +++ b/src/cmd/go/testdata/script/build_plugin_non_main.txt @@ -1,17 +1,13 @@ -# Plugins are only supported on linux,cgo and darwin,cgo. -[!linux] [!darwin] skip -[!cgo] skip +# Plugins are not supported on all platforms. +[!buildmode:plugin] skip -go build -n testdep/p2 -! go build -buildmode=plugin testdep/p2 +go build -n testdep +! go build -buildmode=plugin testdep stderr '-buildmode=plugin requires exactly one main package' --- testdep/p1/p1.go -- -package p1 --- testdep/p1/p1_test.go -- -package p1 - -import _ "testdep/p2" --- testdep/p2/p2.go -- -package p2 +-- go.mod -- +module testdep +go 1.16 +-- testdep.go -- +package p diff --git a/src/cmd/go/testdata/script/build_test_only.txt b/src/cmd/go/testdata/script/build_test_only.txt index 54dd59772a..8693a80a08 100644 --- a/src/cmd/go/testdata/script/build_test_only.txt +++ b/src/cmd/go/testdata/script/build_test_only.txt @@ -1,14 +1,18 @@ # Named explicitly, test-only packages should be reported as # unbuildable/uninstallable, even if there is a wildcard also matching. -! go build testonly testonly... +! go build m/testonly m/testonly... stderr 'no non-test Go files in' ! go install ./testonly stderr 'no non-test Go files in' # Named through a wildcard, the test-only packages should be silently ignored. -go build testonly... +go build m/testonly... go install ./testonly... +-- go.mod -- +module m + +go 1.16 -- testonly/t_test.go -- package testonly -- testonly2/t.go -- diff --git a/src/cmd/go/testdata/script/build_trimpath.txt b/src/cmd/go/testdata/script/build_trimpath.txt index ad78bcf2b2..e1ea0a48b2 100644 --- a/src/cmd/go/testdata/script/build_trimpath.txt +++ b/src/cmd/go/testdata/script/build_trimpath.txt @@ -9,6 +9,8 @@ env GO111MODULE=on mkdir $WORK/a/src/paths $WORK/b/src/paths cp paths.go $WORK/a/src/paths cp paths.go $WORK/b/src/paths +cp overlay.json $WORK/a/src/paths +cp overlay.json $WORK/b/src/paths cp go.mod $WORK/a/src/paths/ cp go.mod $WORK/b/src/paths/ @@ -43,6 +45,29 @@ go build -trimpath -o $WORK/paths-b.exe cmp -q $WORK/paths-a.exe $WORK/paths-b.exe +# Same sequence of tests but with overlays. +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -overlay overlay.json -o $WORK/paths-dbg.exe ./overlaydir +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -overlay overlay.json -trimpath -o $WORK/paths-a.exe ./overlaydir +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -overlay overlay.json -trimpath -o $WORK/paths-b.exe ./overlaydir +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + # Same sequence of tests but in GOPATH mode. # A binary built without -trimpath should contain GOPATH and GOROOT. env GO111MODULE=off @@ -96,7 +121,6 @@ package main import ( "bytes" "fmt" - "io/ioutil" "log" "os" "os/exec" @@ -106,7 +130,7 @@ import ( func main() { exe := os.Args[1] - data, err := ioutil.ReadFile(exe) + data, err := os.ReadFile(exe) if err != nil { log.Fatal(err) } @@ -129,7 +153,8 @@ func check(data []byte, desc, dir string) { containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir))) fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir) } - +-- overlay.json -- +{ "Replace": { "overlaydir/paths.go": "paths.go" } } -- go.mod -- module paths diff --git a/src/cmd/go/testdata/script/build_trimpath_cgo.txt b/src/cmd/go/testdata/script/build_trimpath_cgo.txt index 4608d9ac6b..3187b4d643 100644 --- a/src/cmd/go/testdata/script/build_trimpath_cgo.txt +++ b/src/cmd/go/testdata/script/build_trimpath_cgo.txt @@ -20,10 +20,38 @@ go build -trimpath -o hello.exe . go run ./list-dwarf hello.exe ! stdout gopath/src + +# Do the above, with the cgo (but not .c) sources in an overlay +# Check that the source path appears when -trimpath is not used. +mkdir $WORK/overlay +cp hello.go $WORK/overlay/hello.go +mkdir hello_overlay +cp hello.c hello_overlay/hello.c +go build -overlay overlay.json -o hello_overlay.exe ./hello_overlay +grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +stdout gopath[/\\]src +! stdout $WORK[/\\]overlay + +# Check that the source path does not appear when -trimpath is used. +go build -overlay overlay.json -trimpath -o hello_overlay.exe ./hello_overlay +! grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +! stdout gopath/src +! stdout $WORK[/\\]overlay + -- go.mod -- module m go 1.14 +-- overlay.json -- +{ + "Replace": { + "hello_overlay/hello.go": "../../overlay/hello.go" + } +} -- hello.c -- #include <stdio.h> diff --git a/src/cmd/go/testdata/script/build_vendor.txt b/src/cmd/go/testdata/script/build_vendor.txt index 726ecd75b9..f430ff2c3e 100644 --- a/src/cmd/go/testdata/script/build_vendor.txt +++ b/src/cmd/go/testdata/script/build_vendor.txt @@ -1,4 +1,5 @@ # Build +env GO111MODULE=off go build vend/x ! stdout . ! stderr . diff --git a/src/cmd/go/testdata/script/cgo_asm_error.txt b/src/cmd/go/testdata/script/cgo_asm_error.txt index e656106940..7aaa713e24 100644 --- a/src/cmd/go/testdata/script/cgo_asm_error.txt +++ b/src/cmd/go/testdata/script/cgo_asm_error.txt @@ -6,7 +6,11 @@ ! go build cgoasm stderr 'package using cgo has Go assembly file' --- cgoasm/p.go -- +-- go.mod -- +module cgoasm + +go 1.16 +-- p.go -- package p /* @@ -15,7 +19,7 @@ package p import "C" func F() {} --- cgoasm/p.s -- +-- p.s -- TEXT asm(SB),$0 RET diff --git a/src/cmd/go/testdata/script/cgo_bad_directives.txt b/src/cmd/go/testdata/script/cgo_bad_directives.txt index 358284ffec..6bf3beb8e4 100644 --- a/src/cmd/go/testdata/script/cgo_bad_directives.txt +++ b/src/cmd/go/testdata/script/cgo_bad_directives.txt @@ -1,58 +1,57 @@ [!cgo] skip [short] skip -mkdir x -cp x.go.txt x/x.go +cp x.go.txt x.go # Only allow //go:cgo_ldflag .* in cgo-generated code -[gc] cp x_gc.go.txt x/x.go +[gc] cp x_gc.go.txt x.go [gc] ! go build x [gc] stderr '//go:cgo_ldflag .* only allowed in cgo-generated code' # Ignore _* files -rm x/x.go -! go build x +rm x.go +! go build . stderr 'no Go files' -cp cgo_yy.go.txt x/_cgo_yy.go -! go build x +cp cgo_yy.go.txt _cgo_yy.go +! go build . stderr 'no Go files' #_* files are ignored... -[gc] ! go build x/_cgo_yy.go # ... but if forced, the comment is rejected +[gc] ! go build _cgo_yy.go # ... but if forced, the comment is rejected # Actually, today there is a separate issue that _ files named # on the command line are ignored. Once that is fixed, # we want to see the cgo_ldflag error. [gc] stderr '//go:cgo_ldflag only allowed in cgo-generated code|no Go files' -rm x/_cgo_yy.go +rm _cgo_yy.go # Reject #cgo CFLAGS: -fplugin=foo.so -cp x.go.txt x/x.go -cp y_fplugin.go.txt x/y.go +cp x.go.txt x.go +cp y_fplugin.go.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' # Reject #cgo CFLAGS: -lbar -fplugin=foo.so -cp y_lbar_fplugin.go.txt x/y.go +cp y_lbar_fplugin.go.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' # Reject #cgo pkg-config: -foo -cp y_pkgconfig_dash_foo.txt x/y.go +cp y_pkgconfig_dash_foo.txt y.go ! go build x stderr 'invalid pkg-config package name: -foo' # Reject #cgo pkg-config: @foo -cp y_pkgconfig_at_foo.txt x/y.go +cp y_pkgconfig_at_foo.txt y.go ! go build x stderr 'invalid pkg-config package name: @foo' # Reject #cgo CFLAGS: @foo -cp y_cflags_at_foo.txt x/y.go +cp y_cflags_at_foo.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: @foo' # Reject #cgo CFLAGS: -D -cp y_cflags_dash_d.txt x/y.go +cp y_cflags_dash_d.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: -D without argument' @@ -60,21 +59,25 @@ stderr 'invalid flag in #cgo CFLAGS: -D without argument' # before the check is applied. There's no such rewrite for -D. # Reject #cgo CFLAGS: -D @foo -cp y_cflags_dash_d_space_at_foo.txt x/y.go +cp y_cflags_dash_d_space_at_foo.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: -D @foo' # Reject #cgo CFLAGS -D@foo -cp y_cflags_dash_d_at_foo.txt x/y.go +cp y_cflags_dash_d_at_foo.txt y.go ! go build x stderr 'invalid flag in #cgo CFLAGS: -D@foo' # Check for CFLAGS in commands env CGO_CFLAGS=-D@foo -cp y_no_cflags.txt x/y.go +cp y_no_cflags.txt y.go go build -n x stderr '-D@foo' +-- go.mod -- +module x + +go 1.16 -- x_gc.go.txt -- package x @@ -123,4 +126,4 @@ package x import "C" -- y_no_cflags.txt -- package x -import "C"
\ No newline at end of file +import "C" diff --git a/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt index e5fa84fdbb..bd4777c821 100644 --- a/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt +++ b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt @@ -4,7 +4,11 @@ go list -race -deps foo stdout syscall --- foo/foo.go -- +-- go.mod -- +module foo + +go 1.16 +-- foo.go -- package foo // #include <stdio.h> diff --git a/src/cmd/go/testdata/script/clean_binary.txt b/src/cmd/go/testdata/script/clean_binary.txt new file mode 100644 index 0000000000..7335f8a4c7 --- /dev/null +++ b/src/cmd/go/testdata/script/clean_binary.txt @@ -0,0 +1,78 @@ +# Build something to create the executable, including several cases +[short] skip + +# --------------------- clean executables ------------------------- + +# case1: test file-named executable 'main' +env GO111MODULE=on + +! exists main$GOEXE +go build main.go +exists -exec main$GOEXE +go clean +! exists main$GOEXE + +# case2: test module-named executable 'a.b.c' +! exists a.b.c$GOEXE +go build +exists -exec a.b.c$GOEXE +go clean +! exists a.b.c$GOEXE + +# case3: directory-named executable 'src' +env GO111MODULE=off + +! exists src$GOEXE +go build +exists -exec src$GOEXE +go clean +! exists src$GOEXE + +# --------------------- clean test files ------------------------- + +# case1: test file-named test file +env GO111MODULE=on + +! exists main.test$GOEXE +go test -c main_test.go +exists -exec main.test$GOEXE +go clean +! exists main.test$GOEXE + +# case2: test module-named test file +! exists a.b.c.test$GOEXE +go test -c +exists -exec a.b.c.test$GOEXE +go clean +! exists a.b.c.test$GOEXE + +# case3: test directory-based test file +env GO111MODULE=off + +! exists src.test$GOEXE +go test -c +exists -exec src.test$GOEXE +go clean +! exists src.test$GOEXE + +-- main.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello!") +} + +-- main_test.go -- +package main + +import "testing" + +func TestSomething(t *testing.T) { +} + +-- go.mod -- +module example.com/a.b.c/v2 + +go 1.12
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/cover_asm.txt b/src/cmd/go/testdata/script/cover_asm.txt index 5241c7f0df..57f76d6c02 100644 --- a/src/cmd/go/testdata/script/cover_asm.txt +++ b/src/cmd/go/testdata/script/cover_asm.txt @@ -8,7 +8,11 @@ go tool cover -func=$WORK/cover.out stdout '\tg\t*100.0%' # Check g is 100% covered. ! stdout '\tf\t*[0-9]' # Check for no coverage on the assembly function --- coverasm/p.go -- +-- go.mod -- +module coverasm + +go 1.16 +-- p.go -- package p func f() @@ -16,10 +20,10 @@ func f() func g() { println("g") } --- coverasm/p.s -- +-- p.s -- // empty asm file, // so go test doesn't complain about declaration of f in p.go. --- coverasm/p_test.go -- +-- p_test.go -- package p import "testing" diff --git a/src/cmd/go/testdata/script/cover_blank_func_decl.txt b/src/cmd/go/testdata/script/cover_blank_func_decl.txt index 6fac4f87ea..e7d5250468 100644 --- a/src/cmd/go/testdata/script/cover_blank_func_decl.txt +++ b/src/cmd/go/testdata/script/cover_blank_func_decl.txt @@ -1,9 +1,13 @@ [short] skip -go test -cover ./coverblank +go test -cover coverblank stdout 'coverage: 100.0% of statements' --- coverblank/a.go -- +-- go.mod -- +module coverblank + +go 1.16 +-- a.go -- package coverblank func _() { @@ -20,7 +24,7 @@ func (x X) _() { println("unreachable") } --- coverblank/a_test.go -- +-- a_test.go -- package coverblank import "testing" diff --git a/src/cmd/go/testdata/script/cover_cgo.txt b/src/cmd/go/testdata/script/cover_cgo.txt index fdd0191ee0..9cf78f71e9 100644 --- a/src/cmd/go/testdata/script/cover_cgo.txt +++ b/src/cmd/go/testdata/script/cover_cgo.txt @@ -8,7 +8,11 @@ go test -short -cover cgocover stdout 'coverage:.*[1-9][0-9.]+%' ! stderr '[^0-9]0\.0%' --- cgocover/p.go -- +-- go.mod -- +module cgocover + +go 1.16 +-- p.go -- package p /* @@ -28,7 +32,7 @@ func F() { } C.f() } --- cgocover/p_test.go -- +-- p_test.go -- package p import "testing" diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt index 483813bd6a..c53b979f9f 100644 --- a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt +++ b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt @@ -9,9 +9,13 @@ go test -short -cover cgocover4 stdout 'coverage:.*[1-9][0-9.]+%' ! stderr '[^0-9]0\.0%' --- cgocover4/notcgo.go -- +-- go.mod -- +module cgocover4 + +go 1.16 +-- notcgo.go -- package p --- cgocover4/p.go -- +-- p.go -- package p /* @@ -31,7 +35,7 @@ func F() { } C.f() } --- cgocover4/x_test.go -- +-- x_test.go -- package p_test import ( @@ -41,4 +45,4 @@ import ( func TestF(t *testing.T) { F() -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt index 92fc1ebdda..b501ab02a5 100644 --- a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt +++ b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt @@ -10,7 +10,11 @@ go test -short -cover cgocover3 stdout 'coverage:.*[1-9][0-9.]+%' ! stderr '[^0-9]0\.0%' --- cgocover3/p.go -- +-- go.mod -- +module cgocover3 + +go 1.16 +-- p.go -- package p /* @@ -30,9 +34,9 @@ func F() { } C.f() } --- cgocover3/p_test.go -- +-- p_test.go -- package p --- cgocover3/x_test.go -- +-- x_test.go -- package p_test import ( @@ -42,4 +46,4 @@ import ( func TestF(t *testing.T) { F() -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/cover_cgo_xtest.txt b/src/cmd/go/testdata/script/cover_cgo_xtest.txt index edf8112728..79cc08c481 100644 --- a/src/cmd/go/testdata/script/cover_cgo_xtest.txt +++ b/src/cmd/go/testdata/script/cover_cgo_xtest.txt @@ -8,7 +8,11 @@ go test -short -cover cgocover2 stdout 'coverage:.*[1-9][0-9.]+%' ! stderr '[^0-9]0\.0%' --- cgocover2/p.go -- +-- go.mod -- +module cgocover2 + +go 1.16 +-- p.go -- package p /* @@ -28,7 +32,7 @@ func F() { } C.f() } --- cgocover2/x_test.go -- +-- x_test.go -- package p_test import ( @@ -38,4 +42,4 @@ import ( func TestF(t *testing.T) { F() -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/cover_dash_c.txt b/src/cmd/go/testdata/script/cover_dash_c.txt index 61793cec49..8950f8d088 100644 --- a/src/cmd/go/testdata/script/cover_dash_c.txt +++ b/src/cmd/go/testdata/script/cover_dash_c.txt @@ -6,18 +6,22 @@ go test -c -o $WORK/coverdep -coverprofile=$WORK/no/such/dir/cover.out coverdep exists -exec $WORK/coverdep --- coverdep/p.go -- +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- package p import _ "coverdep/p1" func F() { } --- coverdep/p1/p1.go -- +-- p1/p1.go -- package p1 import _ "errors" --- coverdep/p_test.go -- +-- p_test.go -- package p import "testing" diff --git a/src/cmd/go/testdata/script/cover_dep_loop.txt b/src/cmd/go/testdata/script/cover_dep_loop.txt index 20b0c15d18..36ea6e00b3 100644 --- a/src/cmd/go/testdata/script/cover_dep_loop.txt +++ b/src/cmd/go/testdata/script/cover_dep_loop.txt @@ -7,11 +7,15 @@ go test -short -cover coverdep2/p1 stdout 'coverage: 100.0% of statements' # expect 100.0% coverage --- coverdep2/p1/p.go -- +-- go.mod -- +module coverdep2 + +go 1.16 +-- p1/p.go -- package p1 func F() int { return 1 } --- coverdep2/p1/p_test.go -- +-- p1/p_test.go -- package p1_test import ( @@ -22,7 +26,7 @@ import ( func Test(t *testing.T) { p2.F() } --- coverdep2/p2/p2.go -- +-- p2/p2.go -- package p2 import "coverdep2/p1" diff --git a/src/cmd/go/testdata/script/cover_dot_import.txt b/src/cmd/go/testdata/script/cover_dot_import.txt index e07be22d6c..d492e42e2a 100644 --- a/src/cmd/go/testdata/script/cover_dot_import.txt +++ b/src/cmd/go/testdata/script/cover_dot_import.txt @@ -1,22 +1,26 @@ [short] skip [gccgo] skip # gccgo has no cover tool -go test -coverpkg=coverdot1,coverdot2 coverdot2 +go test -coverpkg=coverdot/a,coverdot/b coverdot/b ! stderr '[^0-9]0\.0%' ! stdout '[^0-9]0\.0%' --- coverdot1/p.go -- -package coverdot1 +-- go.mod -- +module coverdot + +go 1.16 +-- a/a.go -- +package a func F() {} --- coverdot2/p.go -- -package coverdot2 +-- b/b.go -- +package b -import . "coverdot1" +import . "coverdot/a" func G() { F() } --- coverdot2/p_test.go -- -package coverdot2 +-- b/b_test.go -- +package b import "testing" diff --git a/src/cmd/go/testdata/script/cover_error.txt b/src/cmd/go/testdata/script/cover_error.txt index 6ba0f08a2b..583a664237 100644 --- a/src/cmd/go/testdata/script/cover_error.txt +++ b/src/cmd/go/testdata/script/cover_error.txt @@ -5,8 +5,8 @@ # Get errors from a go test into stderr.txt ! go test coverbad -stderr 'coverbad[\\/]p\.go:4' # look for error at coverbad/p.go:4 -[cgo] stderr 'coverbad[\\/]p1\.go:6' # look for error at coverbad/p.go:6 +stderr 'p\.go:4' # look for error at coverbad/p.go:4 +[cgo] stderr 'p1\.go:6' # look for error at coverbad/p.go:6 ! stderr $WORK # make sure temporary directory isn't in error cp stderr $WORK/stderr.txt @@ -24,13 +24,17 @@ wait # for go run above cmp $WORK/stderr.txt $WORK/stderr2.txt --- coverbad/p.go -- +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- package p func f() { g() } --- coverbad/p1.go -- +-- p1.go -- package p import "C" @@ -38,17 +42,18 @@ import "C" func h() { j() } --- coverbad/p_test.go -- +-- p_test.go -- package p import "testing" func Test(t *testing.T) {} -- clean_charpos.go -- +// +build ignore + package main import ( - "io/ioutil" "log" "os" "strings" @@ -56,14 +61,14 @@ import ( func main() { log.SetFlags(0) - b, err := ioutil.ReadFile(os.Args[1]) + b, err := os.ReadFile(os.Args[1]) if err != nil { log.Fatal(err) } s := strings.ReplaceAll(string(b), "p.go:4:2:", "p.go:4:") s = strings.ReplaceAll(s, "p1.go:6:2:", "p1.go:6:") - ioutil.WriteFile(os.Args[1], []byte(s), 0644) + os.WriteFile(os.Args[1], []byte(s), 0644) if err != nil { log.Fatal(err) } -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/cover_import_main_loop.txt b/src/cmd/go/testdata/script/cover_import_main_loop.txt index 83eef0c8a8..eb6de6778a 100644 --- a/src/cmd/go/testdata/script/cover_import_main_loop.txt +++ b/src/cmd/go/testdata/script/cover_import_main_loop.txt @@ -5,15 +5,19 @@ stderr 'not an importable package' # check that import main was detected ! go test -n -cover importmain/test stderr 'not an importable package' # check that import main was detected --- importmain/ismain/main.go -- +-- go.mod -- +module importmain + +go 1.16 +-- ismain/main.go -- package main import _ "importmain/test" func main() {} --- importmain/test/test.go -- +-- test/test.go -- package test --- importmain/test/test_test.go -- +-- test/test_test.go -- package test_test import "testing" diff --git a/src/cmd/go/testdata/script/cover_pattern.txt b/src/cmd/go/testdata/script/cover_pattern.txt index 0b7f2d70a2..ec0850c003 100644 --- a/src/cmd/go/testdata/script/cover_pattern.txt +++ b/src/cmd/go/testdata/script/cover_pattern.txt @@ -1,12 +1,16 @@ [gccgo] skip -# If coverpkg=sleepy... expands by package loading +# If coverpkg=m/sleepy... expands by package loading # (as opposed to pattern matching on deps) # then it will try to load sleepybad, which does not compile, # and the test command will fail. -! go list sleepy... -go test -c -n -coverprofile=$TMPDIR/cover.out -coverpkg=sleepy... -run=^$ sleepy1 +! go list m/sleepy... +go test -c -n -coverprofile=$TMPDIR/cover.out -coverpkg=m/sleepy... -run=^$ m/sleepy1 +-- go.mod -- +module m + +go 1.16 -- sleepy1/p_test.go -- package p diff --git a/src/cmd/go/testdata/script/cover_statements.txt b/src/cmd/go/testdata/script/cover_statements.txt index 314ea6bead..4f3c9ca2f2 100644 --- a/src/cmd/go/testdata/script/cover_statements.txt +++ b/src/cmd/go/testdata/script/cover_statements.txt @@ -5,6 +5,10 @@ stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' stdout 'pkg3 \S+ coverage: 100.0% of statements' stdout 'pkg4 \S+ coverage: \[no statements\]' +-- go.mod -- +module m + +go 1.16 -- pkg1/a.go -- package pkg1 diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt index 769c03ea83..433af9ab73 100644 --- a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt +++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt @@ -3,22 +3,26 @@ go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep --- coverdep/p.go -- +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- package p import _ "coverdep/p1" func F() { } --- coverdep/p1/p1.go -- +-- p1/p1.go -- package p1 import _ "errors" --- coverdep/p_test.go -- +-- p_test.go -- package p import "testing" func Test(t *testing.T) { F() -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/embed.txt b/src/cmd/go/testdata/script/embed.txt new file mode 100644 index 0000000000..7e9a548661 --- /dev/null +++ b/src/cmd/go/testdata/script/embed.txt @@ -0,0 +1,72 @@ +# go list shows patterns and files +go list -f '{{.EmbedPatterns}}' +stdout '\[x\*t\*t\]' +go list -f '{{.EmbedFiles}}' +stdout '\[x.txt\]' + +# build embeds x.txt +go build -x +stderr 'x.txt' + +# build uses cache correctly +go build -x +! stderr 'x.txt' +cp x.txt2 x.txt +go build -x +stderr 'x.txt' + +# build rejects invalid names +cp x.go2 x.go +go build -x +cp x.txt .git +! go build -x +stderr 'pattern [*]t: cannot embed file [.]git' +rm .git + +# build rejects symlinks +[symlink] symlink x.tzt -> x.txt +[symlink] ! go build -x +[symlink] stderr 'pattern [*]t: cannot embed irregular file x.tzt' +[symlink] rm x.tzt + +# build rejects empty directories +mkdir t +! go build -x +stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files' + +# build ignores symlinks and invalid names in directories +cp x.txt t/.git +! go build -x +stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files' +[symlink] symlink t/x.link -> ../x.txt +[symlink] ! go build -x +[symlink] stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files' + +cp x.txt t/x.txt +go build -x + +-- x.go -- +package p + +import "embed" + +//go:embed x*t*t +var X embed.FS + +-- x.go2 -- +package p + +import "embed" + +//go:embed *t +var X embed.FS + +-- x.txt -- +hello + +-- x.txt2 -- +not hello + +-- go.mod -- +module m + diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt index 2366c3f580..bda1e57826 100644 --- a/src/cmd/go/testdata/script/env_write.txt +++ b/src/cmd/go/testdata/script/env_write.txt @@ -24,6 +24,16 @@ stdout GOARCH= stdout GOOS= stdout GOROOT= +# go env ignores invalid flag in GOFLAGS environment variable +env GOFLAGS='=true' +go env + +# checking errors +! go env -w +stderr 'go env -w: no KEY=VALUE arguments given' +! go env -u +stderr 'go env -u: no arguments given' + # go env -w changes default setting env root= [windows] env root=c: @@ -59,6 +69,8 @@ go env -u GOPATH stderr 'unknown go command variable GODEBUG' ! go env -w GOEXE=.bat stderr 'GOEXE cannot be modified' +! go env -w GOVERSION=customversion +stderr 'GOVERSION cannot be modified' ! go env -w GOENV=/env stderr 'GOENV can only be set using the OS environment' @@ -97,6 +109,50 @@ stderr 'GOPATH entry cannot start with shell metacharacter' ! go env -w GOPATH=./go stderr 'GOPATH entry is relative; must be absolute path' +# go env -w rejects invalid GOTMPDIR values +! go env -w GOTMPDIR=x +stderr 'go env -w: GOTMPDIR must be an absolute path' + +# go env -w should accept absolute GOTMPDIR value +# and should not create it +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +! exists $WORK/x/y/z +# we should be able to clear an env +go env -u GOTMPDIR +go env GOTMPDIR +stdout ^$ + +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +go env -w GOTMPDIR= +go env GOTMPDIR +stdout ^$ + +# go env -w rejects relative CC values +[!windows] go env -w CC=/usr/bin/clang +go env -w CC=clang +[!windows] ! go env -w CC=./clang +[!windows] ! go env -w CC=bin/clang +[!windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +[windows] go env -w CC=$WORK\bin\clang +[windows] ! go env -w CC=.\clang +[windows] ! go env -w CC=bin\clang +[windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +# go env -w rejects relative CXX values +[!windows] go env -w CC=/usr/bin/cpp +go env -w CXX=cpp +[!windows] ! go env -w CXX=./cpp +[!windows] ! go env -w CXX=bin/cpp +[!windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + +[windows] go env -w CXX=$WORK\bin\cpp +[windows] ! go env -w CXX=.\cpp +[windows] ! go env -w CXX=bin\cpp +[windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + # go env -w/-u checks validity of GOOS/ARCH combinations env GOOS= env GOARCH= diff --git a/src/cmd/go/testdata/script/gcflags_patterns.txt b/src/cmd/go/testdata/script/gcflags_patterns.txt index 5374493a43..f23cecefd3 100644 --- a/src/cmd/go/testdata/script/gcflags_patterns.txt +++ b/src/cmd/go/testdata/script/gcflags_patterns.txt @@ -63,6 +63,10 @@ stderr 'link.* -X=math.pi=3' go build -n -ldflags=-X=math.pi=3 stderr 'link.* -X=math.pi=3' +# cgo.a should not be a dependency of internally-linked go package +go build -ldflags='-linkmode=external -linkmode=internal' -n prog.go +! stderr 'packagefile .*runtime/cgo.a' + -- z1/z.go -- package z1 import _ "y" diff --git a/src/cmd/go/testdata/script/generate_bad_imports.txt b/src/cmd/go/testdata/script/generate_bad_imports.txt index 59a2f5786b..4d31573d56 100644 --- a/src/cmd/go/testdata/script/generate_bad_imports.txt +++ b/src/cmd/go/testdata/script/generate_bad_imports.txt @@ -3,7 +3,11 @@ go generate gencycle stdout 'hello world' # check go generate gencycle ran the generator --- gencycle/gencycle.go -- +-- go.mod -- +module gencycle + +go 1.16 +-- gencycle.go -- //go:generate echo hello world package gencycle diff --git a/src/cmd/go/testdata/script/generate_invalid.txt b/src/cmd/go/testdata/script/generate_invalid.txt index 62aa9dd9ba..e18e62ccf3 100644 --- a/src/cmd/go/testdata/script/generate_invalid.txt +++ b/src/cmd/go/testdata/script/generate_invalid.txt @@ -54,6 +54,10 @@ func main() { fmt.Println() } +-- go.mod -- +module m + +go 1.16 -- nogo/foo.txt -- Text file in a directory without go files. Go generate should ignore this directory. @@ -196,4 +200,4 @@ import "bar" package importerr import "moo" -//go:generate echo Success c
\ No newline at end of file +//go:generate echo Success c diff --git a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt index 743fbb3ea4..cda25e12b0 100644 --- a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt +++ b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off go get -u rsc.io/pdf/... -exists $GOPATH/bin/pdfpasswd$GOEXE
\ No newline at end of file +exists $GOPATH/bin/pdfpasswd$GOEXE diff --git a/src/cmd/go/testdata/script/get_dash_t.txt b/src/cmd/go/testdata/script/get_dash_t.txt index be5c8dd5ca..baac916868 100644 --- a/src/cmd/go/testdata/script/get_dash_t.txt +++ b/src/cmd/go/testdata/script/get_dash_t.txt @@ -2,7 +2,8 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off go get -v -t github.com/rsc/go-get-issue-8181/a github.com/rsc/go-get-issue-8181/b go list ... -stdout 'x/build/gerrit'
\ No newline at end of file +stdout 'x/build/gerrit' diff --git a/src/cmd/go/testdata/script/get_domain_root.txt b/src/cmd/go/testdata/script/get_domain_root.txt index c2e9db35ec..918784869b 100644 --- a/src/cmd/go/testdata/script/get_domain_root.txt +++ b/src/cmd/go/testdata/script/get_domain_root.txt @@ -3,6 +3,7 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # go-get-issue-9357.appspot.com is running # the code at github.com/rsc/go-get-issue-9357, @@ -16,4 +17,4 @@ rm $GOPATH/src/go-get-issue-9357.appspot.com go get go-get-issue-9357.appspot.com rm $GOPATH/src/go-get-issue-9357.appspot.com -go get -u go-get-issue-9357.appspot.com
\ No newline at end of file +go get -u go-get-issue-9357.appspot.com diff --git a/src/cmd/go/testdata/script/get_dot_slash_download.txt b/src/cmd/go/testdata/script/get_dot_slash_download.txt index 0396e1b278..dbaf46ced3 100644 --- a/src/cmd/go/testdata/script/get_dot_slash_download.txt +++ b/src/cmd/go/testdata/script/get_dot_slash_download.txt @@ -1,9 +1,10 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # Tests Issues #9797 and #19769 mkdir $WORK/tmp/src/rsc.io env GOPATH=$WORK/tmp cd $WORK/tmp/src/rsc.io -go get ./pprof_mac_fix
\ No newline at end of file +go get ./pprof_mac_fix diff --git a/src/cmd/go/testdata/script/get_go_file.txt b/src/cmd/go/testdata/script/get_go_file.txt index 97e0f1ac92..bed8720987 100644 --- a/src/cmd/go/testdata/script/get_go_file.txt +++ b/src/cmd/go/testdata/script/get_go_file.txt @@ -5,46 +5,46 @@ env GO111MODULE=off # argument doesn't have .go suffix -go get test +go get -d test # argument has .go suffix, is a file and exists -! go get test.go +! go get -d test.go stderr 'go get test.go: arguments must be package or module paths' # argument has .go suffix, doesn't exist and has no slashes -! go get test_missing.go +! go get -d test_missing.go stderr 'go get test_missing.go: arguments must be package or module paths' # argument has .go suffix, is a file and exists in sub-directory -! go get test/test.go +! go get -d test/test.go stderr 'go get: test/test.go exists as a file, but ''go get'' requires package arguments' # argument has .go suffix, doesn't exist and has slashes -! go get test/test_missing.go +! go get -d test/test_missing.go ! stderr 'arguments must be package or module paths' ! stderr 'exists as a file, but ''go get'' requires package arguments' # argument has .go suffix, is a symlink and exists [symlink] symlink test_sym.go -> test.go -[symlink] ! go get test_sym.go +[symlink] ! go get -d test_sym.go [symlink] stderr 'go get test_sym.go: arguments must be package or module paths' [symlink] rm test_sym.go # argument has .go suffix, is a symlink and exists in sub-directory [symlink] symlink test/test_sym.go -> test.go -[symlink] ! go get test/test_sym.go +[symlink] ! go get -d test/test_sym.go [symlink] stderr 'go get: test/test_sym.go exists as a file, but ''go get'' requires package arguments' [symlink] rm test_sym.go # argument has .go suffix, is a directory and exists mkdir test_dir.go -! go get test_dir.go +! go get -d test_dir.go stderr 'go get test_dir.go: arguments must be package or module paths' rm test_dir.go # argument has .go suffix, is a directory and exists in sub-directory mkdir test/test_dir.go -! go get test/test_dir.go +! go get -d test/test_dir.go ! stderr 'arguments must be package or module paths' ! stderr 'exists as a file, but ''go get'' requires package arguments' rm test/test_dir.go diff --git a/src/cmd/go/testdata/script/get_goroot.txt b/src/cmd/go/testdata/script/get_goroot.txt index 49f1a174d0..929435ad70 100644 --- a/src/cmd/go/testdata/script/get_goroot.txt +++ b/src/cmd/go/testdata/script/get_goroot.txt @@ -1,4 +1,5 @@ [!net] skip +env GO111MODULE=off # Issue 4186. go get cannot be used to download packages to $GOROOT. # Test that without GOPATH set, go get should fail. @@ -49,4 +50,4 @@ stderr '\$GOPATH not set' env GOPATH= env GOROOT=$WORK/home/go/ ! go get -d github.com/golang/example/hello -stderr '\$GOPATH not set'
\ No newline at end of file +stderr '\$GOPATH not set' diff --git a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt index c0439fb037..a4a6fd428f 100644 --- a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt +++ b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off ! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p -go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p
\ No newline at end of file +go get -d -insecure insecure.go-get-issue-15410.appspot.com/pkg/p diff --git a/src/cmd/go/testdata/script/get_insecure_deprecated.txt b/src/cmd/go/testdata/script/get_insecure_deprecated.txt new file mode 100644 index 0000000000..7f5f5c7877 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_deprecated.txt @@ -0,0 +1,21 @@ +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Fetch without insecure, no warning +! go get test +! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# GOPATH: Fetch with insecure, should warn +! go get -insecure test +stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# Modules: Set up +env GO111MODULE=on + +# Modules: Fetch without insecure, no warning +! go get test +! stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' + +# Modules: Fetch with insecure, should warn +! go get -insecure test +stderr 'go get: -insecure flag is deprecated; see ''go help get'' for details' diff --git a/src/cmd/go/testdata/script/get_insecure_update.txt b/src/cmd/go/testdata/script/get_insecure_update.txt index 792c868151..4511c98c56 100644 --- a/src/cmd/go/testdata/script/get_insecure_update.txt +++ b/src/cmd/go/testdata/script/get_insecure_update.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # Clone the repo via HTTP manually. exec git clone -q http://github.com/golang/example github.com/golang/example @@ -8,4 +9,4 @@ exec git clone -q http://github.com/golang/example github.com/golang/example # Update with -insecure should succeed. # We need -f to ignore import comments. ! go get -d -u -f github.com/golang/example/hello -go get -d -u -f -insecure github.com/golang/example/hello
\ No newline at end of file +go get -d -u -f -insecure github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_internal_wildcard.txt b/src/cmd/go/testdata/script/get_internal_wildcard.txt index 82bb0d5ba5..ff20d4ba04 100644 --- a/src/cmd/go/testdata/script/get_internal_wildcard.txt +++ b/src/cmd/go/testdata/script/get_internal_wildcard.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # This used to fail with errors about internal packages -go get github.com/rsc/go-get-issue-11960/...
\ No newline at end of file +go get github.com/rsc/go-get-issue-11960/... diff --git a/src/cmd/go/testdata/script/get_issue11307.txt b/src/cmd/go/testdata/script/get_issue11307.txt index da7704dee5..9d6b7dde01 100644 --- a/src/cmd/go/testdata/script/get_issue11307.txt +++ b/src/cmd/go/testdata/script/get_issue11307.txt @@ -2,7 +2,8 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off env GOPATH=$WORK/tmp/gopath go get github.com/rsc/go-get-issue-11307 -go get -u github.com/rsc/go-get-issue-11307 # was failing
\ No newline at end of file +go get -u github.com/rsc/go-get-issue-11307 # was failing diff --git a/src/cmd/go/testdata/script/mod_get_legacy.txt b/src/cmd/go/testdata/script/get_legacy.txt index 28a820e97b..938d42868a 100644 --- a/src/cmd/go/testdata/script/mod_get_legacy.txt +++ b/src/cmd/go/testdata/script/get_legacy.txt @@ -5,6 +5,7 @@ [short] skip [!exec:git] skip +env GO111MODULE=off env GOPATH=$WORK/tmp/d1 go get vcs-test.golang.org/git/modlegacy1-old.git/p1 @@ -54,4 +55,4 @@ rm $GOPATH go get github.com/rsc/vgotest5 github.com/myitcv/vgo_example_compat github.com/rsc/vgotest4 rm $GOPATH -go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat
\ No newline at end of file +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat diff --git a/src/cmd/go/testdata/script/get_race.txt b/src/cmd/go/testdata/script/get_race.txt index 8b34c9596c..16a560afca 100644 --- a/src/cmd/go/testdata/script/get_race.txt +++ b/src/cmd/go/testdata/script/get_race.txt @@ -3,5 +3,6 @@ [!net] skip [!exec:git] skip [!race] skip +env GO111MODULE=off -go get -race github.com/rsc/go-get-issue-9224-cmd
\ No newline at end of file +go get -race github.com/rsc/go-get-issue-9224-cmd diff --git a/src/cmd/go/testdata/script/get_test_only.txt b/src/cmd/go/testdata/script/get_test_only.txt index 7437c30e77..a3f38ddbab 100644 --- a/src/cmd/go/testdata/script/get_test_only.txt +++ b/src/cmd/go/testdata/script/get_test_only.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off go get golang.org/x/tour/content... -go get -t golang.org/x/tour/content...
\ No newline at end of file +go get -t golang.org/x/tour/content... diff --git a/src/cmd/go/testdata/script/get_update.txt b/src/cmd/go/testdata/script/get_update.txt index df889c49b0..9afce6a443 100644 --- a/src/cmd/go/testdata/script/get_update.txt +++ b/src/cmd/go/testdata/script/get_update.txt @@ -4,6 +4,7 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # Rewind go get github.com/rsc/go-get-issue-9224-cmd @@ -21,4 +22,4 @@ exec git reset --hard HEAD~ cd $GOPATH/src # (Again with -d -u) Run get -go get -d -u 'github.com/rsc/go-get-issue-9224-cmd'
\ No newline at end of file +go get -d -u 'github.com/rsc/go-get-issue-9224-cmd' diff --git a/src/cmd/go/testdata/script/get_update_all.txt b/src/cmd/go/testdata/script/get_update_all.txt index d0b9860ade..2b75849209 100644 --- a/src/cmd/go/testdata/script/get_update_all.txt +++ b/src/cmd/go/testdata/script/get_update_all.txt @@ -3,5 +3,7 @@ [!net] skip +env GO111MODULE=off + go get -u -n .../ ! stderr 'duplicate loads of' # make sure old packages are removed from cache diff --git a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt index 85c2e24bc8..b00adea70b 100644 --- a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt +++ b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off # Clone the repo via HTTPS manually. exec git clone -q https://github.com/golang/example github.com/golang/example @@ -10,4 +11,4 @@ cd github.com/golang/example exec git remote set-url origin xyz://github.com/golang/example exec git config --local url.https://github.com/.insteadOf xyz://github.com/ -go get -d -u -f github.com/golang/example/hello
\ No newline at end of file +go get -d -u -f github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_update_wildcard.txt b/src/cmd/go/testdata/script/get_update_wildcard.txt index bfa47a2a4c..4e66004014 100644 --- a/src/cmd/go/testdata/script/get_update_wildcard.txt +++ b/src/cmd/go/testdata/script/get_update_wildcard.txt @@ -2,6 +2,7 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off go get github.com/tmwh/go-get-issue-14450/a ! go get -u .../ @@ -12,4 +13,4 @@ exists github.com/tmwh/go-get-issue-14450/b exists github.com/tmwh/go-get-issue-14450-b-dependency/c exists github.com/tmwh/go-get-issue-14450-b-dependency/d -! exists github.com/tmwh/go-get-issue-14450-c-dependency/e
\ No newline at end of file +! exists github.com/tmwh/go-get-issue-14450-c-dependency/e diff --git a/src/cmd/go/testdata/script/get_vcs_error_message.txt b/src/cmd/go/testdata/script/get_vcs_error_message.txt index e2404cc8d9..8dc84fc727 100644 --- a/src/cmd/go/testdata/script/get_vcs_error_message.txt +++ b/src/cmd/go/testdata/script/get_vcs_error_message.txt @@ -1,4 +1,5 @@ # Test that the Version Control error message includes the correct directory +env GO111MODULE=off ! go get -u foo stderr gopath(\\\\|/)src(\\\\|/)foo diff --git a/src/cmd/go/testdata/script/get_vendor.txt b/src/cmd/go/testdata/script/get_vendor.txt index a6f0a70c48..4ebb8a26b6 100644 --- a/src/cmd/go/testdata/script/get_vendor.txt +++ b/src/cmd/go/testdata/script/get_vendor.txt @@ -1,4 +1,5 @@ [short] skip +env GO111MODULE=off cd $GOPATH/src/v go run m.go @@ -91,4 +92,4 @@ func TestNothing(t *testing.T) { } -- v/vendor/vendor.org/p/p.go -- package p -const C = 1
\ No newline at end of file +const C = 1 diff --git a/src/cmd/go/testdata/script/gopath_moved_repo.txt b/src/cmd/go/testdata/script/gopath_moved_repo.txt index 869980da7c..99d80bff5d 100644 --- a/src/cmd/go/testdata/script/gopath_moved_repo.txt +++ b/src/cmd/go/testdata/script/gopath_moved_repo.txt @@ -45,7 +45,6 @@ package main import ( "bytes" - "io/ioutil" "log" "os" ) @@ -57,11 +56,11 @@ func main() { base := []byte(os.Args[1]) path := os.Args[2] - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { log.Fatal(err) } - err = ioutil.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) + err = os.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) if err != nil { log.Fatal(err) } diff --git a/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt index 5096195c70..22e6048e96 100644 --- a/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt +++ b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt @@ -1,4 +1,5 @@ [!net] skip +env GO111MODULE=off # Issue 17119: Test more duplicate load errors. ! go build dupload diff --git a/src/cmd/go/testdata/script/govcs.txt b/src/cmd/go/testdata/script/govcs.txt new file mode 100644 index 0000000000..35f092ee49 --- /dev/null +++ b/src/cmd/go/testdata/script/govcs.txt @@ -0,0 +1,174 @@ +env GO111MODULE=on +env proxy=$GOPROXY +env GOPROXY=direct + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for private github.com/google/go-cmp' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for private github.com/google/go-cmp' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr 'go get github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr 'go get github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list +env GOPROXY=$proxy +go get -d rsc.io/quote # ok because used proxy +env GOPROXY=direct + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr 'go get rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr 'go get rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr 'go get rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr 'go get rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr 'go get rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg' + +# Repeat in GOPATH mode. Error texts slightly different. + +env GO111MODULE=off + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr 'package github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr 'package rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr 'package rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr 'package rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr 'package rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr 'package rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg' + +-- go.mod -- +module m + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/script/import_ignore.txt b/src/cmd/go/testdata/script/import_ignore.txt new file mode 100644 index 0000000000..83a39a0be3 --- /dev/null +++ b/src/cmd/go/testdata/script/import_ignore.txt @@ -0,0 +1,11 @@ +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +-- go.mod -- +module m.test + +go 1.16 +-- .ignore.go -- +package p +import _ "golang.org/x/mod/modfile"
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/install_cgo_excluded.txt b/src/cmd/go/testdata/script/install_cgo_excluded.txt index fa1fcd67a4..5a2b46030f 100644 --- a/src/cmd/go/testdata/script/install_cgo_excluded.txt +++ b/src/cmd/go/testdata/script/install_cgo_excluded.txt @@ -3,7 +3,11 @@ env CGO_ENABLED=0 ! go install cgotest stderr 'build constraints exclude all Go files' --- cgotest/m.go -- +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- package cgotest import "C" diff --git a/src/cmd/go/testdata/script/install_relative_gobin_fail.txt b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt index e1e9ec7bdf..aa145249c5 100644 --- a/src/cmd/go/testdata/script/install_relative_gobin_fail.txt +++ b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt @@ -2,7 +2,11 @@ env GOBIN=. ! go install stderr 'cannot install, GOBIN must be an absolute path' +-- go.mod -- +module triv + +go 1.16 -- triv.go -- package main -func main() {}
\ No newline at end of file +func main() {} diff --git a/src/cmd/go/testdata/script/install_shadow_gopath.txt b/src/cmd/go/testdata/script/install_shadow_gopath.txt index 995162172e..2039d9e7f2 100644 --- a/src/cmd/go/testdata/script/install_shadow_gopath.txt +++ b/src/cmd/go/testdata/script/install_shadow_gopath.txt @@ -3,6 +3,7 @@ [!net] skip +env GO111MODULE=off env GOPATH=$WORK/gopath1${:}$WORK/gopath2 mkdir $WORK/gopath1/src/test @@ -16,4 +17,4 @@ stderr 'no install location for.*gopath2.src.test: hidden by .*gopath1.src.test' -- main.go -- package main -func main() {}
\ No newline at end of file +func main() {} diff --git a/src/cmd/go/testdata/script/ldflag.txt b/src/cmd/go/testdata/script/ldflag.txt new file mode 100644 index 0000000000..6ceb33bb70 --- /dev/null +++ b/src/cmd/go/testdata/script/ldflag.txt @@ -0,0 +1,44 @@ +# Issue #42565 + +[!cgo] skip + +# We can't build package bad, which uses #cgo LDFLAGS. +cd bad +! go build +stderr no-such-warning + +# We can build package ok with the same flags in CGO_LDFLAGS. +env CGO_LDFLAGS=-Wno-such-warning -Wno-unknown-warning-option +cd ../ok +go build + +# Build a main program that actually uses LDFLAGS. +cd .. +go build -ldflags=-v + +# Because we passed -v the Go linker should print the external linker +# command which should include the flag we passed in CGO_LDFLAGS. +stderr no-such-warning + +-- go.mod -- +module ldflag + +-- bad/bad.go -- +package bad + +// #cgo LDFLAGS: -Wno-such-warning -Wno-unknown-warning +import "C" + +func F() {} +-- ok/ok.go -- +package ok + +import "C" + +func F() {} +-- main.go -- +package main + +import _ "ldflag/ok" + +func main() {} diff --git a/src/cmd/go/testdata/script/link_matching_actionid.txt b/src/cmd/go/testdata/script/link_matching_actionid.txt new file mode 100644 index 0000000000..b8d423d027 --- /dev/null +++ b/src/cmd/go/testdata/script/link_matching_actionid.txt @@ -0,0 +1,38 @@ +# Checks that an identical binary is built with -trimpath from the same +# source files, with GOROOT in two different locations. +# Verifies golang.org/issue/38989 + +[short] skip +[!symlink] skip + +# Symlink the compiler to a local path +env GOROOT=$WORK/goroot1 +symlink $GOROOT -> $TESTGO_GOROOT + +# Set up fresh GOCACHE +env GOCACHE=$WORK/gocache1 +mkdir $GOCACHE + +# Build a simple binary +go build -o binary1 -trimpath -x main.go + +# Now repeat the same process with the compiler at a different local path +env GOROOT=$WORK/goroot2 +symlink $GOROOT -> $TESTGO_GOROOT + +env GOCACHE=$WORK/gocache2 +mkdir $GOCACHE + +go build -o binary2 -trimpath -x main.go + +# Check that the binaries match exactly +go tool buildid binary1 +cp stdout buildid1 +go tool buildid binary2 +cp stdout buildid2 +cmp buildid1 buildid2 + + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt index 46b0ef4200..26034c9626 100644 --- a/src/cmd/go/testdata/script/link_syso_issue33139.txt +++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt @@ -8,13 +8,13 @@ # See: https://github.com/golang/go/issues/8912 [linux] [ppc64] skip -# External linking is not supported on linux/riscv64. -# See: https://github.com/golang/go/issues/36739 -[linux] [riscv64] skip - cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c go build -ldflags='-linkmode=external' ./cmd/main.go +-- go.mod -- +module m + +go 1.16 -- syso/objTest.s -- #include "textflag.h" @@ -36,7 +36,7 @@ void objTestImpl() { /* Empty */ } -- cmd/main.go -- package main -import "syso" +import "m/syso" func main() { syso.ObjTest() diff --git a/src/cmd/go/testdata/script/list_bad_import.txt b/src/cmd/go/testdata/script/list_bad_import.txt index b8f9d586f3..dbec35069c 100644 --- a/src/cmd/go/testdata/script/list_bad_import.txt +++ b/src/cmd/go/testdata/script/list_bad_import.txt @@ -15,10 +15,11 @@ stdout 'incomplete' stdout 'bad dep: .*example.com[/\\]notfound' # Listing with -deps should also fail. -# BUG: Today, it does not. -# ! go list -deps example.com/direct -# stderr example.com[/\\]notfound -go list -deps example.com/direct +! go list -deps example.com/direct +stderr example.com[/\\]notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct stdout example.com/notfound @@ -31,10 +32,11 @@ stdout incomplete stdout 'bad dep: .*example.com[/\\]notfound' # Again, -deps should fail. -# BUG: Again, it does not. -# ! go list -deps example.com/indirect -# stderr example.com[/\\]notfound -go list -deps example.com/indirect +! go list -deps example.com/indirect +stderr example.com[/\\]notfound + +# But -deps -e should succeed. +go list -e -deps example.com/indirect stdout example.com/notfound diff --git a/src/cmd/go/testdata/script/list_case_collision.txt b/src/cmd/go/testdata/script/list_case_collision.txt index 73f44b63a0..181a202989 100644 --- a/src/cmd/go/testdata/script/list_case_collision.txt +++ b/src/cmd/go/testdata/script/list_case_collision.txt @@ -8,30 +8,34 @@ stderr 'case-insensitive import collision' # List files explicitly on command line, to encounter case-checking # logic even on case-insensitive filesystems. -cp example/b/file.go example/b/FILE.go # no-op on case-insensitive filesystems -! go list example/b/file.go example/b/FILE.go +cp b/file.go b/FILE.go # no-op on case-insensitive filesystems +! go list b/file.go b/FILE.go stderr 'case-insensitive file name collision' -mkdir example/a/Pkg # no-op on case-insensitive filesystems -cp example/a/pkg/pkg.go example/a/Pkg/pkg.go # no-op on case-insensitive filesystems +mkdir a/Pkg # no-op on case-insensitive filesystems +cp a/pkg/pkg.go a/Pkg/pkg.go # no-op on case-insensitive filesystems ! go list example/a/pkg example/a/Pkg # Test that the path reported with an indirect import is correct. -cp example/b/file.go example/b/FILE.go +cp b/file.go b/FILE.go [case-sensitive] ! go build example/c [case-sensitive] stderr '^package example/c\n\timports example/b: case-insensitive file name collision: "FILE.go" and "file.go"$' --- example/a/a.go -- +-- go.mod -- +module example + +go 1.16 +-- a/a.go -- package p import ( _ "example/a/pkg" _ "example/a/Pkg" ) --- example/a/pkg/pkg.go -- +-- a/pkg/pkg.go -- package pkg --- example/b/file.go -- +-- b/file.go -- package b --- example/c/c.go -- +-- c/c.go -- package c import _ "example/b" diff --git a/src/cmd/go/testdata/script/list_dedup_packages.txt b/src/cmd/go/testdata/script/list_dedup_packages.txt index ebd497b7e5..30c68dd77f 100644 --- a/src/cmd/go/testdata/script/list_dedup_packages.txt +++ b/src/cmd/go/testdata/script/list_dedup_packages.txt @@ -1,4 +1,5 @@ # Setup +env GO111MODULE=off mkdir $WORK/tmp/testdata/src/xtestonly cp f.go $WORK/tmp/testdata/src/xtestonly/f.go cp f_test.go $WORK/tmp/testdata/src/xtestonly/f_test.go diff --git a/src/cmd/go/testdata/script/list_overlay.txt b/src/cmd/go/testdata/script/list_overlay.txt new file mode 100644 index 0000000000..1153975345 --- /dev/null +++ b/src/cmd/go/testdata/script/list_overlay.txt @@ -0,0 +1,63 @@ +# Test listing with overlays + +# Overlay in an existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' . +stdout '^\[f.go\]$' + +# Overlays in a non-existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir +stdout '^\[g.go\]$' + +# Overlays in an existing directory with already existing files +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir2 +stdout '^\[h.go i.go\]$' + +# Overlay that removes a file from a directory +! go list ./dir3 # contains a file without a package statement +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir3 # overlay removes that file + +# Walking through an overlay +go list -overlay overlay.json ./... +cmp stdout want-list.txt + +# TODO(#39958): assembly files, C files, files that require cgo preprocessing + +-- want-list.txt -- +m +m/dir +m/dir2 +m/dir3 +-- go.mod -- +// TODO(#39958): Support and test overlays including go.mod itself (especially if mod=readonly) +module m + +go 1.16 + +-- dir2/h.go -- +package dir2 + +-- dir3/good.go -- +package dir3 +-- dir3/bad.go -- +// no package statement +-- overlay.json -- +{ + "Replace": { + "f.go": "overlay/f_go", + "dir/g.go": "overlay/dir_g_go", + "dir2/i.go": "overlay/dir2_i_go", + "dir3/bad.go": "" + } +} +-- overlay/f_go -- +package m + +func f() { +} +-- overlay/dir_g_go -- +package m + +func g() { +} +-- overlay/dir2_i_go -- +package dir2 diff --git a/src/cmd/go/testdata/script/list_symlink.txt b/src/cmd/go/testdata/script/list_symlink.txt index 20c85b6453..f74ca86f37 100644 --- a/src/cmd/go/testdata/script/list_symlink.txt +++ b/src/cmd/go/testdata/script/list_symlink.txt @@ -1,4 +1,5 @@ [!symlink] skip +env GO111MODULE=off mkdir $WORK/tmp/src symlink $WORK/tmp/src/dir1 -> $WORK/tmp diff --git a/src/cmd/go/testdata/script/list_symlink_internal.txt b/src/cmd/go/testdata/script/list_symlink_internal.txt index e538072b33..f756a56a3f 100644 --- a/src/cmd/go/testdata/script/list_symlink_internal.txt +++ b/src/cmd/go/testdata/script/list_symlink_internal.txt @@ -1,4 +1,5 @@ [!symlink] skip +env GO111MODULE=off mkdir $WORK/tmp/gopath/src/dir1/internal/v cp p.go $WORK/tmp/gopath/src/dir1/p.go @@ -23,4 +24,4 @@ import _ `dir1/internal/v` func main() {} -- v.go -- -package v
\ No newline at end of file +package v diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt index 68b7fd948b..8e63a5a259 100644 --- a/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt @@ -1,4 +1,5 @@ [!symlink] skip +env GO111MODULE=off mkdir $WORK/tmp/gopath/src/dir1/vendor/v cp p.go $WORK/tmp/gopath/src/dir1/p.go @@ -24,4 +25,4 @@ import _ `v` func main () {} -- v.go -- -package v
\ No newline at end of file +package v diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt index 98921614a9..19f2138250 100644 --- a/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt @@ -1,4 +1,5 @@ [!symlink] skip +env GO111MODULE=off mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x symlink $WORK/tmp/gopath/src/x/y/_vendor/src/x/y -> ../../.. @@ -17,4 +18,4 @@ package w import "x/y/z" -- z.go -- -package z
\ No newline at end of file +package z diff --git a/src/cmd/go/testdata/script/list_test_err.txt b/src/cmd/go/testdata/script/list_test_err.txt index a174b5e9ad..c6f1ecf400 100644 --- a/src/cmd/go/testdata/script/list_test_err.txt +++ b/src/cmd/go/testdata/script/list_test_err.txt @@ -22,6 +22,9 @@ go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' syntaxerr stdout 'pkgdep <nil>' stdout 'testdep_a <nil>' stdout 'testdep_b <nil>' +stdout 'syntaxerr <nil>' +stdout 'syntaxerr \[syntaxerr.test\] <nil>' +stdout 'syntaxerr_test \[syntaxerr.test\] <nil>' stdout 'syntaxerr\.test "[^"]*expected declaration' ! stderr 'expected declaration' diff --git a/src/cmd/go/testdata/script/list_test_simple.txt b/src/cmd/go/testdata/script/list_test_simple.txt index 862b7a8fbb..954897c663 100644 --- a/src/cmd/go/testdata/script/list_test_simple.txt +++ b/src/cmd/go/testdata/script/list_test_simple.txt @@ -1,21 +1,23 @@ [short] skip -cd $WORK - # Test -go test './gopath/src/testlist/...' -list=Test +go test -list=Test stdout TestSimple # Benchmark -go test './gopath/src/testlist/...' -list=Benchmark +go test -list=Benchmark stdout BenchmarkSimple # Examples -go test './gopath/src/testlist/...' -list=Example +go test -list=Example stdout ExampleSimple stdout ExampleWithEmptyOutput --- testlist/bench_test.go -- +-- go.mod -- +module m + +go 1.16 +-- bench_test.go -- package testlist import ( @@ -30,7 +32,7 @@ func BenchmarkSimplefunc(b *testing.B) { _ = fmt.Sprint("Test for bench") } } --- testlist/example_test.go -- +-- example_test.go -- package testlist import ( @@ -52,7 +54,7 @@ func ExampleWithEmptyOutput() { func ExampleNoOutput() { _ = fmt.Sprint("Test with no output") } --- testlist/test_test.go -- +-- test_test.go -- package testlist import ( @@ -62,4 +64,4 @@ import ( func TestSimple(t *testing.T) { _ = fmt.Sprint("Test simple") -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt index 74ca315a72..02b1088297 100644 --- a/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt +++ b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt @@ -1,13 +1,17 @@ # Test that wildcards don't look in useless directories. # First make sure that badpkg fails the list of '...'. -! go list ... +! go list ./... stderr badpkg -# Check that the list of 'm...' succeeds. That implies badpkg was skipped. -go list m... +# Check that the list of './goodpkg...' succeeds. That implies badpkg was skipped. +go list ./goodpkg... --- m/x.go -- -package m +-- go.mod -- +module m + +go 1.16 +-- goodpkg/x.go -- +package goodpkg -- badpkg/x.go -- -pkg badpkg
\ No newline at end of file +pkg badpkg diff --git a/src/cmd/go/testdata/script/load_test_pkg_err.txt b/src/cmd/go/testdata/script/load_test_pkg_err.txt index b3065490de..d088ee40f3 100644 --- a/src/cmd/go/testdata/script/load_test_pkg_err.txt +++ b/src/cmd/go/testdata/script/load_test_pkg_err.txt @@ -10,17 +10,21 @@ stdout golang.org/fake/d d d.test d_test [d.test] --- d/d.go -- +-- go.mod -- +module d + +go 1.16 +-- d.go -- package d import "net/http" const d = http.MethodGet func Get() string { return d; } --- d/d2.go -- --- d/d_test.go -- +-- d2.go -- +-- d_test.go -- package d_test import "testing" import "golang.org/fake/d" -func TestD(t *testing.T) { d.Get(); }
\ No newline at end of file +func TestD(t *testing.T) { d.Get(); } diff --git a/src/cmd/go/testdata/script/mod_all.txt b/src/cmd/go/testdata/script/mod_all.txt index 9f4b0a4e4d..aac66292d6 100644 --- a/src/cmd/go/testdata/script/mod_all.txt +++ b/src/cmd/go/testdata/script/mod_all.txt @@ -187,16 +187,104 @@ stdout '^example.com/main_test \[example.com/main.test\]$' stdout '^example.com/main/testonly.test$' stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' -# TODO(#36460): +rm vendor + +# Convert all modules to go 1.16 to enable lazy loading. +go mod edit -go=1.16 a/go.mod +go mod edit -go=1.16 b/go.mod +go mod edit -go=1.16 c/go.mod +go mod edit -go=1.16 d/go.mod +go mod edit -go=1.16 q/go.mod +go mod edit -go=1.16 r/go.mod +go mod edit -go=1.16 s/go.mod +go mod edit -go=1.16 t/go.mod +go mod edit -go=1.16 u/go.mod +go mod edit -go=1.16 w/go.mod +go mod edit -go=1.16 x/go.mod +go mod edit -go=1.16 -# With lazy loading, 'go list all' without -mod=vendor should match -# 'go mod vendor'. +# With lazy loading, 'go list all' with neither -mod=vendor nor -test should +# match -mod=vendor without -test in 1.15. -# 'go list -test all' should expand that to cover test dependencies -# of packages imported by the main module. +go list -f $PKGFMT all +stdout -count=8 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' -# 'go list -m all' should cover the packages in 'go list -test all'. +# 'go list -test all' should expand that to include the test variants of the +# packages in 'all', but not the dependencies of outside tests. +go list -test -f $PKGFMT all +stdout -count=25 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + +# 'go list -test -deps all' should include the dependencies of those tests, +# but not the tests of the dependencies of outside tests. + +go list -test -deps -f $PKGFMT all +stdout -count=28 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + + +# TODO(#36460): +# 'go list -m all' should exactly cover the packages in 'go list -test all'. -- go.mod -- module example.com/main diff --git a/src/cmd/go/testdata/script/mod_auth.txt b/src/cmd/go/testdata/script/mod_auth.txt index 5bcbcd1a18..d8ea5867d6 100644 --- a/src/cmd/go/testdata/script/mod_auth.txt +++ b/src/cmd/go/testdata/script/mod_auth.txt @@ -3,11 +3,12 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOVCS='*:off' # Without credentials, downloading a module from a path that requires HTTPS # basic auth should fail. env NETRC=$WORK/empty -! go list all +! go mod tidy stderr '^\tserver response: ACCESS DENIED, buddy$' stderr '^\tserver response: File\? What file\?$' diff --git a/src/cmd/go/testdata/script/mod_bad_domain.txt b/src/cmd/go/testdata/script/mod_bad_domain.txt index ec0d474382..20199c1c2c 100644 --- a/src/cmd/go/testdata/script/mod_bad_domain.txt +++ b/src/cmd/go/testdata/script/mod_bad_domain.txt @@ -2,22 +2,34 @@ env GO111MODULE=on # explicit get should report errors about bad names ! go get appengine -stderr '^go get appengine: package appengine is not in GOROOT \(.*\)$' +stderr '^go get: malformed module path "appengine": missing dot in first path element$' ! go get x/y.z stderr 'malformed module path "x/y.z": missing dot in first path element' + # 'go list -m' should report errors about module names, never GOROOT. ! go list -m -versions appengine stderr 'malformed module path "appengine": missing dot in first path element' ! go list -m -versions x/y.z stderr 'malformed module path "x/y.z": missing dot in first path element' + # build should report all unsatisfied imports, # but should be more definitive about non-module import paths ! go build ./useappengine -stderr 'cannot find package' +stderr '^useappengine[/\\]x.go:2:8: cannot find package$' ! go build ./usenonexistent -stderr 'cannot find module providing package nonexistent.rsc.io' +stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; try ''go mod tidy'' to add it$' + + +# 'get -d' should be similarly definitive + +go get -d ./useappengine # TODO(#41315): This should fail. + # stderr '^useappengine[/\\]x.go:2:8: cannot find package$' + +! go get -d ./usenonexistent +stderr '^x/usenonexistent imports\n\tnonexistent.rsc.io: cannot find module providing package nonexistent.rsc.io$' + # go mod vendor and go mod tidy should ignore appengine imports. rm usenonexistent/x.go diff --git a/src/cmd/go/testdata/script/mod_build_info_err.txt b/src/cmd/go/testdata/script/mod_build_info_err.txt index 87a099b219..cee055eabe 100644 --- a/src/cmd/go/testdata/script/mod_build_info_err.txt +++ b/src/cmd/go/testdata/script/mod_build_info_err.txt @@ -1,8 +1,19 @@ # This test verifies that line numbers are included in module import errors. # Verifies golang.org/issue/34393. -go list -e -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main -stdout 'bad[/\\]bad.go:3:8: malformed module path "🐧.example.com/string": invalid char ''🐧''' +go list -e -mod=mod -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main +stdout '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#26909): This should include an import stack. +# (Today it includes only a file and line.) +! go build ./main +stderr '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#41688): This should include a file and line, and report the reason for the error.. +# (Today it includes only an import stack.) +! go get -d ./main +stderr '^m/main imports\n\tm/bad imports\n\t🐧.example.com/string: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + -- go.mod -- module m diff --git a/src/cmd/go/testdata/script/mod_case.txt b/src/cmd/go/testdata/script/mod_case.txt index ee818c2c07..4a4698600f 100644 --- a/src/cmd/go/testdata/script/mod_case.txt +++ b/src/cmd/go/testdata/script/mod_case.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -go get rsc.io/QUOTE +go get -d go list -m all stdout '^rsc.io/quote v1.5.2' stdout '^rsc.io/QUOTE v1.5.2' @@ -9,7 +9,7 @@ go list -f 'DIR {{.Dir}} DEPS {{.Deps}}' rsc.io/QUOTE/QUOTE stdout 'DEPS.*rsc.io/quote' stdout 'DIR.*!q!u!o!t!e' -go get rsc.io/QUOTE@v1.5.3-PRE +go get -d rsc.io/QUOTE@v1.5.3-PRE go list -m all stdout '^rsc.io/QUOTE v1.5.3-PRE' @@ -18,3 +18,8 @@ stdout '!q!u!o!t!e@v1.5.3-!p!r!e' -- go.mod -- module x + +-- use.go -- +package use + +import _ "rsc.io/QUOTE/QUOTE" diff --git a/src/cmd/go/testdata/script/mod_case_cgo.txt b/src/cmd/go/testdata/script/mod_case_cgo.txt index 917bce92d8..f3d6aaa5ab 100644 --- a/src/cmd/go/testdata/script/mod_case_cgo.txt +++ b/src/cmd/go/testdata/script/mod_case_cgo.txt @@ -2,7 +2,9 @@ env GO111MODULE=on -go get rsc.io/CGO +go get -d rsc.io/CGO +[short] stop + go build rsc.io/CGO -- go.mod -- diff --git a/src/cmd/go/testdata/script/mod_concurrent.txt b/src/cmd/go/testdata/script/mod_concurrent.txt index e03e5e5edb..8c21525158 100644 --- a/src/cmd/go/testdata/script/mod_concurrent.txt +++ b/src/cmd/go/testdata/script/mod_concurrent.txt @@ -1,6 +1,7 @@ env GO111MODULE=on # Concurrent builds should succeed, even if they need to download modules. +go get -d ./x ./y go build ./x & go build ./y wait diff --git a/src/cmd/go/testdata/script/mod_concurrent_unzipinplace.txt b/src/cmd/go/testdata/script/mod_concurrent_unzipinplace.txt deleted file mode 100644 index 473be71c9c..0000000000 --- a/src/cmd/go/testdata/script/mod_concurrent_unzipinplace.txt +++ /dev/null @@ -1,17 +0,0 @@ -# This tests checks the GODEBUG=modcacheunzipinplace=1 flag, used as part of -# a migration in golang.org/issue/36568. -# -# Concurrent downloads with and without GODEBUG=modcacheunzipinplace=1 should -# not conflict. This is meant to simulate an old version and a new version -# of Go accessing the cache concurrently. -go mod download & -env GODEBUG=modcacheunzipinplace=1 -go mod download -wait - --- go.mod -- -module golang.org/issue/36568 - -go 1.14 - -require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_doc.txt b/src/cmd/go/testdata/script/mod_doc.txt index aac3db00be..595ad679fc 100644 --- a/src/cmd/go/testdata/script/mod_doc.txt +++ b/src/cmd/go/testdata/script/mod_doc.txt @@ -1,6 +1,7 @@ # go doc should find module documentation env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # Check when module x is inside GOPATH/src. @@ -48,6 +49,7 @@ stderr '^doc: cannot find module providing package example.com/hello: module loo # path used in source code, not to the absolute path relative to GOROOT. cd $GOROOT/src +env GOFLAGS= go doc cryptobyte stdout '// import "golang.org/x/crypto/cryptobyte"' diff --git a/src/cmd/go/testdata/script/mod_domain_root.txt b/src/cmd/go/testdata/script/mod_domain_root.txt index e34cc29fa6..14745b5812 100644 --- a/src/cmd/go/testdata/script/mod_domain_root.txt +++ b/src/cmd/go/testdata/script/mod_domain_root.txt @@ -2,7 +2,7 @@ # (example.com not example.com/something) env GO111MODULE=on -go build +go get -d -- go.mod -- module x diff --git a/src/cmd/go/testdata/script/mod_dot.txt b/src/cmd/go/testdata/script/mod_dot.txt index 1f7643e1de..ca8d5c6cc2 100644 --- a/src/cmd/go/testdata/script/mod_dot.txt +++ b/src/cmd/go/testdata/script/mod_dot.txt @@ -4,8 +4,12 @@ env GO111MODULE=on # in an empty directory should refer to the path '.' and should not attempt # to resolve an external module. cd dir +! go get +stderr '^go get: no package in current directory$' ! go get . -stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$' +stderr '^go get \.: no package in current directory$' +! go get ./subdir +stderr '^go get: \.[/\\]subdir \('$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir\) is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src[/\\]dir$' ! go list ! stderr 'cannot find module providing package' stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' diff --git a/src/cmd/go/testdata/script/mod_download.txt b/src/cmd/go/testdata/script/mod_download.txt index 5acb83266b..8a9faffe4e 100644 --- a/src/cmd/go/testdata/script/mod_download.txt +++ b/src/cmd/go/testdata/script/mod_download.txt @@ -46,7 +46,7 @@ go mod edit -require rsc.io/quote@v1.5.3-pre1 ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip # module loading will page in the info and mod files -go list -m all +go list -m -mod=mod all exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip @@ -93,19 +93,27 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip # download reports errors encountered when locating modules ! go mod download bad/path -stderr '^module bad/path: not a known dependency$' +stderr '^go mod download: module bad/path: not a known dependency$' ! go mod download bad/path@latest -stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$' +stderr '^go mod download: bad/path@latest: malformed module path "bad/path": missing dot in first path element$' ! go mod download rsc.io/quote@v1.999.999 -stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' +stderr '^go mod download: rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' ! go mod download -json bad/path stdout '^\t"Error": "module bad/path: not a known dependency"' -# download main module returns an error +# download main module produces a warning or error go mod download m stderr '^go mod download: skipping argument m that resolves to the main module\n' -go mod download m@latest -stderr '^go mod download: skipping argument m@latest that resolves to the main module\n' +! go mod download m@latest +stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$' + +# download updates go.mod and populates go.sum +cd update +! exists go.sum +go mod download +grep '^rsc.io/sampler v1.3.0 ' go.sum +go list -m rsc.io/sampler +stdout '^rsc.io/sampler v1.3.0$' # allow go mod download without go.mod env GO111MODULE=auto @@ -122,3 +130,13 @@ stderr 'get '$GOPROXY -- go.mod -- module m + +-- update/go.mod -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.2.1 // older version than in build list +) diff --git a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt index bb9c588896..231babd0c0 100644 --- a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt +++ b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt @@ -1,27 +1,18 @@ # This test simulates a process watching for changes and reading files in # module cache as a module is extracted. # -# By default, we unzip a downloaded module into a temporary directory with a -# random name, then rename the directory into place. On Windows, this fails -# with ERROR_ACCESS_DENIED if another process (e.g., antivirus) opens files -# in the directory. +# Before Go 1.16, we extracted each module zip to a temporary directory with +# a random name, then renamed that into place with os.Rename. On Windows, +# this failed with ERROR_ACCESS_DENIED when another process (usually an +# anti-virus scanner) opened files in the temporary directory. This test +# simulates that behavior, verifying golang.org/issue/36568. # -# Setting GODEBUG=modcacheunzipinplace=1 opts into new behavior: a downloaded -# module is unzipped in place. A .partial file is created elsewhere to indicate -# that the extraction is incomplete. -# -# Verifies golang.org/issue/36568. +# Since 1.16, we extract to the final directory, but we create a .partial file +# so that if we crash, other processes know the directory is incomplete. [!windows] skip [short] skip -# Control case: check that the default behavior fails. -# This is commented out to avoid flakiness. We can't reproduce the failure -# 100% of the time. -# ! go run downloader.go - -# Experiment: check that the new behavior does not fail. -env GODEBUG=modcacheunzipinplace=1 go run downloader.go -- go.mod -- @@ -34,7 +25,6 @@ package main import ( "fmt" - "io/ioutil" "log" "os" "os/exec" @@ -54,7 +44,7 @@ func main() { // don't need to clean the cache or synchronize closing files after each // iteration. func run() (err error) { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") if err != nil { return err } diff --git a/src/cmd/go/testdata/script/mod_download_partial.txt b/src/cmd/go/testdata/script/mod_download_partial.txt index 4978982dab..0aab60ddaf 100644 --- a/src/cmd/go/testdata/script/mod_download_partial.txt +++ b/src/cmd/go/testdata/script/mod_download_partial.txt @@ -1,5 +1,5 @@ -# Download a module -go mod download -modcacherw rsc.io/quote +# Download modules and populate go.sum. +go get -d -modcacherw exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod # 'go mod verify' should fail if we delete a file. @@ -46,7 +46,6 @@ rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod # 'go mod download' should not leave behind a directory or a .partial file # if there is an error extracting the zip file. -env GODEBUG=modcacheunzipinplace=1 rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 cp empty $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip ! go mod download @@ -61,4 +60,9 @@ go 1.14 require rsc.io/quote v1.5.2 +-- use.go -- +package use + +import _ "rsc.io/quote" + -- empty -- diff --git a/src/cmd/go/testdata/script/mod_e.txt b/src/cmd/go/testdata/script/mod_e.txt new file mode 100644 index 0000000000..3a0d18dabc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_e.txt @@ -0,0 +1,89 @@ +cp go.mod go.mod.orig + + +# If a dependency cannot be resolved, 'go mod tidy' fails with an error message +# explaining the problem and does not update the go.mod file. +# TODO(bcmills): Ideally, with less redundancy than these error messages! + +! go mod tidy + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m tested by\n\texample.net/m.test imports\n\texample.net/indirecttestnotfound: cannot find module providing package example.net/indirecttestnotfound: module example.net/indirecttestnotfound: reading http://.*: 404 Not Found$' + +cmp go.mod.orig go.mod + + +# If a dependency cannot be resolved, 'go mod vendor' fails with an error message +# explaining the problem, does not update the go.mod file, and does not create +# the vendor directory. + +! go mod vendor + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$' + +! stderr 'indirecttestnotfound' # Vendor prunes test dependencies. + +cmp go.mod.orig go.mod +! exists vendor + + +# 'go mod tidy' still logs the errors, but succeeds and updates go.mod. + +go mod tidy -e +stderr -count=4 'cannot find module providing package' +cmp go.mod.final go.mod + + +# 'go mod vendor -e' still logs the errors, but succeeds and updates go.mod. + +cp go.mod.orig go.mod +go mod vendor -e +stderr -count=3 'cannot find module providing package' +cmp go.mod.final go.mod +exists vendor/modules.txt +exists vendor/example.net/m/m.go + + +-- go.mod -- +module example.com/untidy +go 1.16 +replace example.net/m v0.1.0 => ./m +-- go.mod.final -- +module example.com/untidy + +go 1.16 + +replace example.net/m v0.1.0 => ./m + +require example.net/m v0.1.0 +-- untidy.go -- +package untidy + +import ( + _ "example.net/m" + _ "example.net/directnotfound" +) +-- untidy_test.go -- +package untidy_test + +import _ "example.net/directtestnotfound" +-- m/go.mod -- +module example.net/m +go 1.16 +-- m/m.go -- +package m + +import _ "example.net/indirectnotfound" +-- m/m_test.go -- +package m_test + +import _ "example.net/indirecttestnotfound" diff --git a/src/cmd/go/testdata/script/mod_enabled.txt b/src/cmd/go/testdata/script/mod_enabled.txt index 10fa103fad..39f1ece8cb 100644 --- a/src/cmd/go/testdata/script/mod_enabled.txt +++ b/src/cmd/go/testdata/script/mod_enabled.txt @@ -25,7 +25,7 @@ cd $GOPATH/foo/bar/baz go env GOMOD stdout foo[/\\]go.mod -# GO111MODULE unset should be equivalent to auto. +# GO111MODULE unset should be equivalent to on. env GO111MODULE= cd $GOPATH/src/x/y/z @@ -34,7 +34,7 @@ stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod cd $GOPATH/src/x/y go env GOMOD -! stdout . +stdout 'NUL|/dev/null' # GO111MODULE=on should trigger everywhere env GO111MODULE=on diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt new file mode 100644 index 0000000000..daed03b02c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt @@ -0,0 +1,107 @@ +go mod tidy +cp go.mod go.mod.orig + +# If there is no sensible *package* meaning for 'm/p', it should refer +# to *module* m/p. + +go get -d m/p # @latest +go list -m all +stdout '^m/p v0.3.0 ' +! stdout '^m ' + +cp go.mod.orig go.mod + +go get -d m/p@v0.1.0 +go list -m all +stdout '^m/p v0.1.0 ' +! stdout '^m ' + +# When feasible, the argument 'm/p' in 'go get m/p' refers to *package* m/p, +# which is in module m. +# +# (It only refers to *module* m/p if there is no such package at the +# requested version.) + +go get -d m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' # unchanged from the previous case + +# Repeating the above with module m/p already in the module graph does not +# change its meaning. + +go get -d m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' + +-- go.mod -- +module example.com + +go 1.16 + +replace ( + m v0.1.0 => ./m01 + m v0.2.0 => ./m02 + m v0.3.0 => ./m03 + m/p v0.1.0 => ./mp01 + m/p v0.2.0 => ./mp02 + m/p v0.3.0 => ./mp03 +) +-- m01/go.mod -- +module m + +go 1.16 +-- m01/README.txt -- +Module m at v0.1.0 does not yet contain package p. + +-- m02/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m02/p/p.go -- +// Package p is present in module m, but not module m/p. +package p + +-- m03/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m03/README.txt -- +Module m at v0.3.0 no longer contains package p. + +-- mv2/go.mod -- +module m/v2 + +go 1.16 +-- mv2/README.txt -- +This module is m/v2. It doesn't actually need to exist, +but it explains how module m could plausibly exist +and still contain package p at 'latest' even when module +m/p also exists. + +-- mp01/go.mod -- +module m/p + +go 1.16 +-- mp01/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp02/go.mod -- +module m/p + +go 1.16 +-- mp02/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp03/go.mod -- +module m/p + +go 1.16 +-- mp03/README.txt -- +This module is m/p. +Package m/p does not exist in this module. diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt new file mode 100644 index 0000000000..33605f51a5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt @@ -0,0 +1,60 @@ +go list -m all +stdout '^example.net/m v0.1.0 ' +! stdout '^example.net/m/p ' +cp go.mod go.mod.orig + +# Upgrading example.net/m/p without also upgrading example.net/m +# causes the import of package example.net/m/p to be ambiguous. +# +# TODO(#27899): Should we automatically upgrade example.net/m to v0.2.0 +# to resolve the conflict? +! go get -d example.net/m/p@v1.0.0 +stderr '^example.net/m/p: ambiguous import: found package example.net/m/p in multiple modules:\n\texample.net/m v0.1.0 \(.*[/\\]m1[/\\]p\)\n\texample.net/m/p v1.0.0 \(.*[/\\]p0\)\n\z' +cmp go.mod go.mod.orig + +# Upgrading both modules simultaneously resolves the ambiguous upgrade. +# Note that this command line mixes a module path (example.net/m) +# and a package path (example.net/m/p) in the same command. +go get -d example.net/m@v0.2.0 example.net/m/p@v1.0.0 + +go list -m all +stdout '^example.net/m v0.2.0 ' +stdout '^example.net/m/p v1.0.0 ' + +-- go.mod -- +module example.net/importer + +go 1.16 + +require ( + example.net/m v0.1.0 +) + +replace ( + example.net/m v0.1.0 => ./m1 + example.net/m v0.2.0 => ./m2 + example.net/m/p v1.0.0 => ./p0 +) +-- importer.go -- +package importer +import _ "example.net/m/p" +-- m1/go.mod -- +module example.net/m + +go 1.16 +-- m1/p/p.go -- +package p +-- m2/go.mod -- +module example.net/m + +go 1.16 +-- m2/README.txt -- +Package p has been moved to module …/m/p. +Module …/m/p does not require any version of module …/m. + +-- p0/go.mod -- +module example.net/m/p + +go 1.16 +-- p0/p.go -- +package p diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt new file mode 100644 index 0000000000..0e7f93bccb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt @@ -0,0 +1,87 @@ +# Both example.net/ambiguous v0.1.0 and example.net/ambiguous/pkg v0.1.0 exist. +# 'go mod tidy' would arbitrarily choose the one with the longer path, +# but 'go mod tidy' also arbitrarily chooses the latest version. + +cp go.mod go.mod.orig + + +# From a clean slate, 'go get' currently does the same thing as 'go mod tidy': +# it resolves the package from the module with the longest matching prefix. + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# From an initial state that already depends on the shorter path, +# the same 'go get' command should (somewhat arbitrarily) keep the +# existing path, since it is a valid interpretation of the command. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous v0.1.0$' +! stdout '^example.net/ambiguous/nested ' + + +# The user should be able to make the command unambiguous by explicitly +# upgrading the conflicting module... + +go get -d example.net/ambiguous@v0.2.0 example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +stdout '^example.net/ambiguous v0.2.0$' + + +# ...or by explicitly NOT adding the conflicting module. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg@v0.1.0 example.net/ambiguous/nested@none +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +# The user should also be able to fix it by *downgrading* the conflicting module +# away. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous@none example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# In contrast, if we do the same thing tacking a wildcard pattern ('/...') on +# the end of the package path, we get different behaviors depending on the +# initial state, and no error. (This seems to contradict the “same meaning +# regardless of the initial state” point above, but maybe that's ok?) + +cp go.mod.orig go.mod + +go get -d example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get -d example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +-- go.mod -- +module test + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_get_changes.txt b/src/cmd/go/testdata/script/mod_get_changes.txt new file mode 100644 index 0000000000..3287b2a609 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_changes.txt @@ -0,0 +1,70 @@ +# When adding a requirement, 'go get' prints a message for the requirement +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go list -m all +! stdout golang.org/x/text +go get -d rsc.io/quote@v1.5.2 +stderr '^go get: added rsc.io/quote v1.5.2$' +stderr '^go get: upgraded rsc.io/sampler v1.0.0 => v1.3.0$' +! stderr '^go get.*golang.org/x/text' +go list -m all +stdout golang.org/x/text +cmp go.mod go.mod.upgrade + +# When removing a requirement, 'go get' prints a message for the requiremnent +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go get -d rsc.io/sampler@none +stderr '^go get: downgraded rsc.io/quote v1.5.2 => v1.3.0$' +stderr '^go get: removed rsc.io/sampler v1.3.0$' +! stderr '^go get.*golang.org/x/text' +cmp go.mod go.mod.downgrade + +# When removing or downgrading a requirement, 'go get' also prints a message +# for explicit dependencies removed as a consequence. +cp go.mod.usequote go.mod +go get -d rsc.io/quote@v1.5.1 +stderr '^go get: downgraded rsc.io/quote v1.5.2 => v1.5.1$' +stderr '^go get: removed usequote v0.0.0$' + +-- go.mod -- +module m + +go 1.16 + +require rsc.io/sampler v1.0.0 +-- go.sum -- +rsc.io/sampler v1.0.0 h1:SRJnjyQ07sAtq6G4RcfJEmz8JxqLyj3PoGXG2VhbDWo= +rsc.io/sampler v1.0.0/go.mod h1:cqxpM3ZVz9VtirqxZPmrWzkQ+UkiNiGtkrN+B+i8kx8= +-- go.mod.upgrade -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 +) +-- go.mod.downgrade -- +module m + +go 1.16 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/quote v1.3.0 // indirect +) +-- go.mod.usequote -- +module m + +go 1.16 + +require usequote v0.0.0 + +replace usequote => ./usequote +-- usequote/go.mod -- +module usequote + +go 1.16 + +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_get_commit.txt b/src/cmd/go/testdata/script/mod_get_commit.txt index 857740ae6c..4649491a53 100644 --- a/src/cmd/go/testdata/script/mod_get_commit.txt +++ b/src/cmd/go/testdata/script/mod_get_commit.txt @@ -32,11 +32,11 @@ go install -x golang.org/x/text/language ! go get -d -x golang.org/x/text/foo@14c0d48 # get pseudo-version should record that version -go get rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 +go get -d rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 grep 'rsc.io/quote v0.0.0-20180214005840-23179ee8a569' go.mod # but as commit should record as v1.5.1 -go get rsc.io/quote@23179ee8 +go get -d rsc.io/quote@23179ee8 grep 'rsc.io/quote v1.5.1' go.mod # go mod edit -require does not interpret commits diff --git a/src/cmd/go/testdata/script/mod_get_downgrade.txt b/src/cmd/go/testdata/script/mod_get_downgrade.txt index ee9ac96475..a954c10344 100644 --- a/src/cmd/go/testdata/script/mod_get_downgrade.txt +++ b/src/cmd/go/testdata/script/mod_get_downgrade.txt @@ -3,30 +3,33 @@ env GO111MODULE=on # downgrade sampler should downgrade quote cp go.mod.orig go.mod -go get rsc.io/sampler@v1.0.0 +go get -d rsc.io/sampler@v1.0.0 go list -m all stdout 'rsc.io/quote v1.4.0' stdout 'rsc.io/sampler v1.0.0' # downgrade sampler away should downgrade quote further -go get rsc.io/sampler@none +go get -d rsc.io/sampler@none go list -m all stdout 'rsc.io/quote v1.3.0' # downgrade should report inconsistencies and not change go.mod -go get rsc.io/quote@v1.5.1 +go get -d rsc.io/quote@v1.5.1 go list -m all stdout 'rsc.io/quote v1.5.1' stdout 'rsc.io/sampler v1.3.0' -! go get rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none -stderr 'go get: inconsistent versions:\n\trsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c \(not golang.org/x/text@none\), rsc.io/sampler@v1.3.0 \(not rsc.io/sampler@v1.0.0\)' + +! go get -d rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none +stderr '^go get: rsc.io/quote@v1.5.2 requires rsc.io/sampler@v1.3.0, not rsc.io/sampler@v1.0.0$' +stderr '^go get: rsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c, not golang.org/x/text@none$' + go list -m all stdout 'rsc.io/quote v1.5.1' stdout 'rsc.io/sampler v1.3.0' # go get -u args should limit upgrades cp go.mod.empty go.mod -go get -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 +go get -d -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 go list -m all stdout 'rsc.io/quote v1.4.0' stdout 'rsc.io/sampler v1.0.0' @@ -37,7 +40,7 @@ stdout 'rsc.io/sampler v1.0.0' cp go.mod.orig go.mod go list -m -versions example.com/latemigrate/v2 stdout v2.0.0 # proxy may serve incompatible versions -go get rsc.io/quote@none +go get -d rsc.io/quote@none go list -m all ! stdout 'example.com/latemigrate/v2' diff --git a/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt new file mode 100644 index 0000000000..5b768faeb1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt @@ -0,0 +1,43 @@ +cp go.mod go.mod.orig + +# getting a specific version of a module along with a pattern +# not yet present in that module should report the version mismatch +# rather than a "matched no packages" warning. + +! go get -d example.net/pkgadded@v1.1.0 example.net/pkgadded/subpkg/... +stderr '^go get: example.net/pkgadded@v1.1.0 conflicts with example.net/pkgadded/subpkg/...@upgrade \(v1.2.0\)$' +! stderr 'matched no packages' +cmp go.mod.orig go.mod + + +# A wildcard pattern should match the pattern with that path. + +go get -d example.net/pkgadded/...@v1.0.0 +go list -m all +stdout '^example.net/pkgadded v1.0.0' +cp go.mod.orig go.mod + + +# If we need to resolve a transitive dependency of a package, +# and another argument constrains away the version that provides that +# package, then 'go get' should fail with a useful error message. + +! go get -d example.net/pkgadded@v1.0.0 . +stderr '^example.com/m imports\n\texample.net/pkgadded/subpkg: cannot find module providing package example.net/pkgadded/subpkg$' +! stderr 'example.net/pkgadded v1\.2\.0' +cmp go.mod.orig go.mod + +go get -d example.net/pkgadded@v1.0.0 +! go list -deps -mod=readonly . +stderr '^m.go:3:8: cannot find module providing package example\.net/pkgadded/subpkg: ' + +-- go.mod -- +module example.com/m + +go 1.16 + +require example.net/pkgadded v1.2.0 +-- m.go -- +package m + +import _ "example.net/pkgadded/subpkg" diff --git a/src/cmd/go/testdata/script/mod_get_errors.txt b/src/cmd/go/testdata/script/mod_get_errors.txt new file mode 100644 index 0000000000..5c37058d1c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_errors.txt @@ -0,0 +1,69 @@ +cp go.mod go.mod.orig + + +# Both 'go get' and 'go get -d' should fail, without updating go.mod, +# if the transitive dependencies of the requested package (by default, +# the package in the current directory) cannot be resolved. + +! go get +stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$' +cmp go.mod.orig go.mod + +! go get -d +stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$' +cmp go.mod.orig go.mod + +cd importsyntax + + +# If 'go get' fails due to a compile error (such as a syntax error), +# it should not update the go.mod file. + +! go get +stderr '^..[/\\]badimport[/\\]syntaxerror[/\\]syntaxerror.go:1:1: expected ''package'', found pack$' # TODO: An import stack would be nice. +cmp ../go.mod.orig ../go.mod + + +# A syntax error in a dependency prevents the compiler from needing that +# dependency's imports, so 'go get -d' should not report an error when those +# imports cannot be resolved: it has all of the dependencies that the compiler +# needs, and the user did not request to run the compiler. + +go get -d +cmp ../go.mod.syntax-d ../go.mod + + +-- go.mod -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport +-- go.mod.syntax-d -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport + +require example.com/badimport v0.1.0 +-- m.go -- +package m + +import _ "example.com/badimport" +-- importsyntax/importsyntax.go -- +package importsyntax + +import _ "example.com/badimport/syntaxerror" +-- badimport/go.mod -- +module example.com/badimport + +go 1.16 +-- badimport/badimport.go -- +package badimport + +import "example.net/oops" +-- badimport/syntaxerror/syntaxerror.go -- +pack-age syntaxerror // sic + +import "example.net/oops" diff --git a/src/cmd/go/testdata/script/mod_get_extra.txt b/src/cmd/go/testdata/script/mod_get_extra.txt new file mode 100644 index 0000000000..7efa24e87b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_extra.txt @@ -0,0 +1,69 @@ +cp go.mod go.mod.orig + +# The -u flag should not (even temporarily) upgrade modules whose versions are +# determined by explicit queries to any version other than the explicit one. +# Otherwise, 'go get -u' could introduce spurious dependencies. + +go get -d -u example.net/a@v0.1.0 example.net/b@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +! stdout '^example.net/c ' + + +# TODO(bcmills): This property does not yet hold for modules added for +# missing packages when the newly-added module matches a wildcard. + +cp go.mod.orig go.mod + +go get -d -u example.net/a@v0.1.0 example.net/b/...@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +stdout '^example.net/c ' # BUG, but a minor and rare one + + +-- go.mod -- +module example + +go 1.15 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/b v0.1.0 => ./b1 + example.net/b v0.2.0 => ./b2 + example.net/c v0.1.0 => ./c1 + example.net/c v0.2.0 => ./c1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 + +// example.net/a needs a dependency on example.net/b, but lacks a requirement +// on it (perhaps due to a missed file in a VCS commit). +-- a1/a.go -- +package a +import _ "example.net/b" + +-- b1/go.mod -- +module example.net/b + +go 1.15 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.15 + +require example.net/c v0.1.0 +-- b2/b.go -- +package b + +-- c1/go.mod -- +module example.net/c + +go 1.15 diff --git a/src/cmd/go/testdata/script/mod_get_fossil.txt b/src/cmd/go/testdata/script/mod_get_fossil.txt new file mode 100644 index 0000000000..baad544557 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_fossil.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:fossil] skip + +# Regression test for 'go get' to ensure repositories +# provided by fossil v2.12 and up are able to be fetched +# and parsed correctly. +# Verifies golang.org/issue/42323. + + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get' for the fossil repo will fail if fossil +# is unable to determine your fossil user. Easiest +# way to set it for use by 'go get' is specifying +# a any non-empty $USER; the value doesn't otherwise matter. +env USER=fossiluser +env FOSSIL_HOME=$WORK/home + +# Attempting to get the latest version of a fossil repo. +go get vcs-test.golang.org/fossil/hello.fossil +! stderr 'unexpected response from fossil info' +grep 'vcs-test.golang.org/fossil/hello.fossil' go.mod +exists $GOPATH/bin/hello.fossil$GOEXE + +-- go.mod -- +module x +-- $WORK/home/.fossil -- diff --git a/src/cmd/go/testdata/script/mod_get_incompatible.txt b/src/cmd/go/testdata/script/mod_get_incompatible.txt index b210715a5d..8000ee6148 100644 --- a/src/cmd/go/testdata/script/mod_get_incompatible.txt +++ b/src/cmd/go/testdata/script/mod_get_incompatible.txt @@ -1,15 +1,15 @@ env GO111MODULE=on -go list x +go get -d x go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' cp go.mod2 go.mod -go get rsc.io/breaker@7307b30 +go get -d rsc.io/breaker@7307b30 go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' -go get rsc.io/breaker@v2.0.0 +go get -d rsc.io/breaker@v2.0.0 go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' diff --git a/src/cmd/go/testdata/script/mod_get_indirect.txt b/src/cmd/go/testdata/script/mod_get_indirect.txt index f25e170a49..e1cc1ab411 100644 --- a/src/cmd/go/testdata/script/mod_get_indirect.txt +++ b/src/cmd/go/testdata/script/mod_get_indirect.txt @@ -27,7 +27,7 @@ grep 'golang.org/x/text v0.3.0 // indirect$' go.mod # indirect tag should be removed upon seeing direct import. cp $WORK/tmp/uselang.go x.go -go list +go get -d grep 'rsc.io/quote v1.5.2$' go.mod grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod diff --git a/src/cmd/go/testdata/script/mod_get_issue37438.txt b/src/cmd/go/testdata/script/mod_get_issue37438.txt new file mode 100644 index 0000000000..38b2031d3a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_issue37438.txt @@ -0,0 +1,37 @@ +# Regression test for https://golang.org/issue/37438. +# +# If a path exists at the requested version, but does not exist at the +# version of the module that is already required and does not exist at +# the version that would be selected by 'go mod tidy', then +# 'go get foo@requested' should resolve the requested version, +# not error out on the (unrelated) latest one. + +go get -d example.net/a/p@v0.2.0 + +-- go.mod -- +module example + +go 1.15 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/a v0.2.0 => ./a2 + example.net/a v0.3.0 => ./a1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 +-- a1/README -- +package example.net/a/p does not exist at this version. + +-- a2/go.mod -- +module example.net/a + +go 1.15 +-- a2/p/p.go -- +// Package p exists only at v0.2.0. +package p diff --git a/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt index 825ee8cf89..241a0c2f0d 100644 --- a/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt +++ b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt @@ -5,6 +5,6 @@ env GO111MODULE=on go mod init m -go list example.com/notags +go get -d example.com/notags go list -m all stdout '^example.com/notags v0.0.0-20190507143103-cc8cbe209b64$' diff --git a/src/cmd/go/testdata/script/mod_get_main.txt b/src/cmd/go/testdata/script/mod_get_main.txt index 408a5b51c8..50b2fee9ae 100644 --- a/src/cmd/go/testdata/script/mod_get_main.txt +++ b/src/cmd/go/testdata/script/mod_get_main.txt @@ -3,13 +3,13 @@ cp go.mod.orig go.mod # relative and absolute paths must be within the main module. ! go get -d .. -stderr '^go get \.\.: path '$WORK'[/\\]gopath is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +stderr '^go get: \.\. \('$WORK'[/\\]gopath\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d $WORK -stderr '^go get '$WORK': path '$WORK' is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +stderr '^go get: '$WORK' is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d ../... -stderr '^go get: pattern \.\./\.\.\.: directory prefix \.\. outside available modules$' +stderr '^go get: \.\./\.\.\. \('$WORK'[/\\]gopath([/\\]...)?\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d $WORK/... -stderr '^go get: pattern '$WORK'[/\\]\.\.\.: directory prefix \.\.[/\\]\.\. outside available modules$' +stderr '^go get: '$WORK'[/\\]\.\.\. is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' # @patch and @latest within the main module refer to the current version. # The main module won't be upgraded, but missing dependencies will be added. @@ -22,21 +22,25 @@ go get -d rsc.io/x@patch grep 'rsc.io/quote v1.5.2' go.mod cp go.mod.orig go.mod -# The main module cannot be updated to @latest, which is a specific version. -! go get -d rsc.io/x@latest -stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$' - -# The main module cannot be updated to a specific version. -! go get -d rsc.io/x@v0.1.0 -stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' -! go get -d rsc.io/x@v0.1.0 -stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' # Upgrading a package pattern not contained in the main module should not # attempt to upgrade the main module. go get -d rsc.io/quote/...@v1.5.1 grep 'rsc.io/quote v1.5.1' go.mod + +# The main module cannot be updated to a specific version. +! go get -d rsc.io@v0.1.0 +stderr '^go get: can''t request version "v0.1.0" of the main module \(rsc.io\)$' + +# A package in the main module can't be upgraded either. +! go get -d rsc.io/x@v0.1.0 +stderr '^go get: package rsc.io/x is in the main module, so can''t request version v0.1.0$' + +# Nor can a pattern matching packages in the main module. +! go get -d rsc.io/x/...@latest +stderr '^go get: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$' + -- go.mod.orig -- module rsc.io diff --git a/src/cmd/go/testdata/script/mod_get_moved.txt b/src/cmd/go/testdata/script/mod_get_moved.txt index b46ec8e8b6..8430a737c4 100644 --- a/src/cmd/go/testdata/script/mod_get_moved.txt +++ b/src/cmd/go/testdata/script/mod_get_moved.txt @@ -9,7 +9,7 @@ go list -m all stdout 'example.com/split v1.0.0' # A 'go get' that simultaneously upgrades away conflicting package defitions is not ambiguous. -go get example.com/split/subpkg@v1.1.0 +go get -d example.com/split/subpkg@v1.1.0 # A 'go get' without an upgrade should find the package. rm go.mod @@ -28,7 +28,9 @@ go list -m all stdout 'example.com/join/subpkg v1.0.0' # A 'go get' that simultaneously upgrades away conflicting package definitions is not ambiguous. -go get example.com/join/subpkg@v1.1.0 +# (A wildcard pattern applies to both packages and modules, +# because we define wildcard matching to apply after version resolution.) +go get -d example.com/join/subpkg/...@v1.1.0 # A 'go get' without an upgrade should find the package. rm go.mod diff --git a/src/cmd/go/testdata/script/mod_get_newcycle.txt b/src/cmd/go/testdata/script/mod_get_newcycle.txt index 5c197bb0b8..f71620c1bc 100644 --- a/src/cmd/go/testdata/script/mod_get_newcycle.txt +++ b/src/cmd/go/testdata/script/mod_get_newcycle.txt @@ -11,5 +11,4 @@ go mod init m cmp stderr stderr-expected -- stderr-expected -- -go get: inconsistent versions: - example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1 (not example.com/newcycle/a@v1.0.0) +go get: example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1, not example.com/newcycle/a@v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_get_none.txt b/src/cmd/go/testdata/script/mod_get_none.txt index 5aec209f59..b358f05af3 100644 --- a/src/cmd/go/testdata/script/mod_get_none.txt +++ b/src/cmd/go/testdata/script/mod_get_none.txt @@ -3,10 +3,10 @@ env GO111MODULE=on go mod init example.com/foo # 'go get bar@none' should be a no-op if module bar is not active. -go get example.com/bar@none +go get -d example.com/bar@none go list -m all ! stdout example.com/bar -go get example.com/bar@none +go get -d example.com/bar@none go list -m all ! stdout example.com/bar diff --git a/src/cmd/go/testdata/script/mod_get_nopkgs.txt b/src/cmd/go/testdata/script/mod_get_nopkgs.txt new file mode 100644 index 0000000000..078e71a041 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_nopkgs.txt @@ -0,0 +1,40 @@ +cd subdir + +# 'go get' on empty patterns that are necessarily local to the module +# should warn that the patterns are empty, exactly once. + +go get ./... +stderr -count=1 'matched no packages' + +go get -d ./... +stderr -count=1 'matched no packages' + +# 'go get' on patterns that could conceivably match nested modules +# should report a module resolution error. + +go get -d example.net/emptysubdir/... # control case + +! go get -d example.net/emptysubdir/subdir/... +! stderr 'matched no packages' +stderr '^go get example\.net/emptysubdir/subdir/\.\.\.: module example\.net/emptysubdir/subdir: reading http://.*: 404 Not Found\n\tserver response: 404 page not found\n\z' + +# It doesn't make sense to 'go get' a path in the standard library, +# since the standard library necessarily can't have unresolved imports. +# +# TODO(#30241): Maybe that won't always be the case? +# +# For that case, we emit a "malformed module path" error message, +# which isn't ideal either. + +! go get -d builtin/... # in GOROOT/src, but contains no packages +stderr '^go get builtin/...: malformed module path "builtin": missing dot in first path element$' + +-- go.mod -- +module example.net/emptysubdir + +go 1.16 +-- emptysubdir.go -- +// Package emptysubdir has a subdirectory containing no packages. +package emptysubdir +-- subdir/README.txt -- +This module intentionally does not contain any p diff --git a/src/cmd/go/testdata/script/mod_get_patch.txt b/src/cmd/go/testdata/script/mod_get_patch.txt new file mode 100644 index 0000000000..053ef62147 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patch.txt @@ -0,0 +1,130 @@ +# This test examines the behavior of 'go get …@patch' +# See also mod_upgrade_patch.txt (focused on "-u=patch" specifically) +# and mod_get_patchmod.txt (focused on module/package ambiguities). + +cp go.mod go.mod.orig + +# example.net/b@patch refers to the patch for the version of b that was selected +# at the start of 'go get', not the version after applying other changes. + +! go get -d example.net/a@v0.2.0 example.net/b@patch +stderr '^go get: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch changes the default version for other arguments to '@patch', +# but they continue to be resolved against the originally-selected version, +# not the updated one. +# +# TODO(#42360): Reconsider the change in defaults. + +! go get -d -u=patch example.net/a@v0.2.0 example.net/b +stderr '^go get: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch refers to the patches for the selected versions of dependencies *after* +# applying other version changes, not the versions that were selected at the start. +# However, it should not patch versions determined by explicit arguments. + +go get -d -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.2.1 ' + + +# "-u=patch all" should be equivalent to "all@patch", and should fail if the +# patched versions result in a higher-than-patch upgrade. + +cp go.mod.orig go.mod +! go get -u=patch all +stderr '^go get: example.net/a@v0.1.1 \(matching all@patch\) requires example.net/b@v0.2.0, not example.net/b@v0.1.1 \(matching all@patch\)$' +cmp go.mod go.mod.orig + + +# On the other hand, "-u=patch ./..." should patch-upgrade dependencies until +# they reach a fixed point, even if that results in higher-than-patch upgrades. + +go get -u=patch ./... +go list -m all +stdout '^example.net/a v0.1.1 ' +stdout '^example.net/b v0.2.1 ' + + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a21 + example.net/b v0.1.0 => ./b + example.net/b v0.1.1 => ./b + example.net/b v0.2.0 => ./b + example.net/b v0.2.1 => ./b + example.net/b v0.3.0 => ./b + example.net/b v0.3.1 => ./b +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a10/a.go -- +package a + +import _ "example.net/b" + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // upgraded +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 +-- a20/a.go -- +package a + +import _ "example.net/b" + +-- a21/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // not upgraded +-- a21/a.go -- +package a + +import _ "example.net/b" + +-- b/go.mod -- +module example.net/b + +go 1.16 +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/script/mod_get_patchbound.txt b/src/cmd/go/testdata/script/mod_get_patchbound.txt new file mode 100644 index 0000000000..4fd1ec53e1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchbound.txt @@ -0,0 +1,84 @@ +# -u=patch will patch dependencies as far as possible, but not so far that they +# conflict with other command-line arguments. + +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' + +go get -d -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.1.1 ' # not v0.1.2, which requires …/a v0.3.0. + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/a v0.3.0 => ./a + example.net/b v0.1.0 => ./b10 + example.net/b v0.1.1 => ./b11 + example.net/b v0.1.2 => ./b12 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a/a.go -- +package a + +import _ "example.net/b" + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.1.0 +-- b10/b.go -- +package b +-- b10/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b11/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b11/b.go -- +package b +-- b11/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b12/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.3.0 +-- b12/b.go -- +package b +-- b12/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchcycle.txt b/src/cmd/go/testdata/script/mod_get_patchcycle.txt new file mode 100644 index 0000000000..d1db56f935 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchcycle.txt @@ -0,0 +1,64 @@ +# If a patch of a module requires a higher version of itself, +# it should be reported as its own conflict. +# +# This case is weird and unlikely to occur often at all, but it should not +# spuriously succeed. +# (It used to print v0.1.1 but then silently upgrade to v0.2.0.) + +! go get example.net/a@patch +stderr '^go get: example.net/a@patch \(v0.1.1\) requires example.net/a@v0.2.0, not example.net/a@patch \(v0.1.1\)$' # TODO: A mention of b v0.1.0 would be nice. + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/b v0.1.0 => ./b10 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b10/b.go -- +package b + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchmod.txt b/src/cmd/go/testdata/script/mod_get_patchmod.txt new file mode 100644 index 0000000000..e39d13a0f4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchmod.txt @@ -0,0 +1,82 @@ +# example.net/pkgremoved@v0.1.0 refers to a package. +go get -d example.net/pkgremoved@v0.1.0 + +go list example.net/pkgremoved +stdout '^example.net/pkgremoved' + +cp go.mod go.mod.orig + + +# When we resolve a new dependency on example.net/other, +# it will change the meaning of the path "example.net/pkgremoved" +# from a package (at v0.1.0) to only a module (at v0.2.0). +# +# If we simultaneously 'get' that module at the query "patch", the module should +# be constrained to the latest patch of its originally-selected version (v0.1.0), +# not upgraded to the latest patch of the new transitive dependency. + +! go get -d example.net/pkgremoved@patch example.net/other@v0.1.0 +stderr '^go get: example.net/other@v0.1.0 requires example.net/pkgremoved@v0.2.0, not example.net/pkgremoved@patch \(v0.1.1\)$' +cmp go.mod.orig go.mod + + +# However, we should be able to patch from a package to a module and vice-versa. + +# Package to module ... + +go get -d example.net/pkgremoved@v0.3.0 +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + +go get -d example.net/pkgremoved@patch +! go list example.net/pkgremoved + +# ... and module to package. + +go get -d example.net/pkgremoved@v0.4.0 +! go list example.net/pkgremoved + +go get -d example.net/pkgremoved@patch +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + + +-- go.mod -- +module example + +go 1.16 + +replace ( + example.net/other v0.1.0 => ./other + + example.net/pkgremoved v0.1.0 => ./prpkg + example.net/pkgremoved v0.1.1 => ./prpkg + + example.net/pkgremoved v0.2.0 => ./prmod + example.net/pkgremoved v0.2.1 => ./prmod + + example.net/pkgremoved v0.3.0 => ./prpkg + example.net/pkgremoved v0.3.1 => ./prmod + + example.net/pkgremoved v0.4.0 => ./prmod + example.net/pkgremoved v0.4.1 => ./prpkg +) +-- other/go.mod -- +module example.net/other + +go 1.16 + +require example.net/pkgremoved v0.2.0 +-- other/other.go -- +package other +-- prpkg/go.mod -- +module example.net/pkgremoved + +go 1.16 +-- prpkg/pkgremoved.go -- +package pkgremoved +-- prmod/go.mod -- +module example.net/pkgremoved +-- prmod/README.txt -- +Package pkgremoved was removed in v0.2.0 and v0.3.1, +and added in v0.1.0 and v0.4.1. diff --git a/src/cmd/go/testdata/script/mod_get_patterns.txt b/src/cmd/go/testdata/script/mod_get_patterns.txt index 8adc4b0c06..aee4374dc8 100644 --- a/src/cmd/go/testdata/script/mod_get_patterns.txt +++ b/src/cmd/go/testdata/script/mod_get_patterns.txt @@ -10,21 +10,27 @@ grep 'require rsc.io/quote' go.mod cp go.mod.orig go.mod ! go get -d rsc.io/quote/x... -stderr 'go get rsc.io/quote/x...: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' +stderr 'go get: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' ! grep 'require rsc.io/quote' go.mod ! go get -d rsc.io/quote/x/... -stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' +stderr 'go get: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' ! grep 'require rsc.io/quote' go.mod # If a pattern matches no packages within a module, the module should not -# be upgraded, even if the module path matches the pattern. +# be upgraded, even if the module path is a prefix of the pattern. cp go.mod.orig go.mod go mod edit -require example.com/nest@v1.0.0 go get -d example.com/nest/sub/y... grep 'example.com/nest/sub v1.0.0' go.mod grep 'example.com/nest v1.0.0' go.mod +# However, if the pattern matches the module path itself, the module +# should be upgraded even if it contains no matching packages. +go get -d example.com/n...t +grep 'example.com/nest v1.1.0' go.mod +grep 'example.com/nest/sub v1.0.0' go.mod + -- go.mod.orig -- module m diff --git a/src/cmd/go/testdata/script/mod_get_replaced.txt b/src/cmd/go/testdata/script/mod_get_replaced.txt new file mode 100644 index 0000000000..76d0793ffe --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_replaced.txt @@ -0,0 +1,111 @@ +cp go.mod go.mod.orig + +env oldGOPROXY=$GOPROXY + +# If a wildcard replacement exists for an otherwise-nonexistent module, +# 'go get' should resolve it to the minimum valid pseudo-version. + +go mod edit -replace=example.com/x=./x +go get -d example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get -d example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get -d example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# The same should work with GOPROXY=off. + +env GOPROXY=off +cp go.mod.orig go.mod + +go mod edit -replace=example.com/x=./x +go get -d example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get -d example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get -d example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# Replacements should also be listed as known versions, and 'go get' should sort +# them in with ordinary versions. + +env GOPROXY=$oldGOPROXY + +cp go.mod.orig go.mod +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.4.0' + +go get -d rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.0' + +go mod edit -replace rsc.io/quote@v1.3.1=rsc.io/quote@v1.4.0 + +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.3.1 v1.4.0' + +go get -d rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.1 ' + +go get -d rsc.io/quote@>v1.3.1 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.4.0' + + +# Replacements should allow 'go get' to work even with dotless module paths. + +cp go.mod.orig go.mod + +! go list example +stderr '^package example is not in GOROOT \(.*\)$' +! go get -d example +stderr '^go get: malformed module path "example": missing dot in first path element$' + +go mod edit -replace example@v0.1.0=./example + +! go list example +stderr '^module example provides package example and is replaced but not required; try ''go get -d example@v0.1.0'' to add it$' + +go get -d example +go list -m example +stdout '^example v0.1.0 ' + + +-- go.mod -- +module example.com + +go 1.16 +-- x/go.mod -- +module example.com/x + +go 1.16 +-- x/x.go -- +package x +-- example/go.mod -- +module example +go 1.16 +-- example/example.go -- +package example diff --git a/src/cmd/go/testdata/script/mod_get_retract.txt b/src/cmd/go/testdata/script/mod_get_retract.txt index da6c25523f..6e328eb592 100644 --- a/src/cmd/go/testdata/script/mod_get_retract.txt +++ b/src/cmd/go/testdata/script/mod_get_retract.txt @@ -10,7 +10,8 @@ stdout '^example.com/retract/self/prev v1.1.0$' cp go.mod.orig go.mod go mod edit -require example.com/retract/self/prev@v1.9.0 go get -d example.com/retract/self/prev -stderr '^go: warning: example.com/retract/self/prev@v1.9.0 is retracted: self$' +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' +stderr '^go: run ''go get example.com/retract/self/prev@latest'' to switch to the latest unretracted version$' go list -m example.com/retract/self/prev stdout '^example.com/retract/self/prev v1.9.0$' @@ -25,7 +26,7 @@ stdout '^example.com/retract/self/prev v1.1.0$' # version is retracted. cp go.mod.orig go.mod go get -d example.com/retract@v1.0.0-bad -stderr '^go: warning: example.com/retract@v1.0.0-bad is retracted: bad$' +stderr '^go: warning: example.com/retract@v1.0.0-bad: retracted by module author: bad$' go list -m example.com/retract stdout '^example.com/retract v1.0.0-bad$' @@ -33,17 +34,26 @@ stdout '^example.com/retract v1.0.0-bad$' # version is available. cp go.mod.orig go.mod go mod edit -require example.com/retract/self/prev@v1.9.0 -go get -d -u . -stderr '^go: warning: example.com/retract/self/prev@v1.9.0 is retracted: self$' +go get -d -u ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' go list -m example.com/retract/self/prev stdout '^example.com/retract/self/prev v1.9.0$' +# 'go get' should warn if a module needed to build named packages is retracted. +# 'go get' should not warn about unrelated modules. +go get -d ./empty +! stderr retracted +go get -d ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' + -- go.mod.orig -- module example.com/use go 1.15 --- use.go -- +-- use/use.go -- package use import _ "example.com/retract/self/prev" +-- empty/empty.go -- +package empty diff --git a/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt new file mode 100644 index 0000000000..b49ba54982 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt @@ -0,0 +1,10 @@ +! go get -d example.com/retract/ambiguous/other +stderr 'ambiguous import: found package example.com/retract/ambiguous/nested in multiple modules:' +stderr '^go: warning: example.com/retract/ambiguous/nested@v1.9.0-bad: retracted by module author: nested modules are bad$' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/ambiguous/nested v1.9.0-bad diff --git a/src/cmd/go/testdata/script/mod_get_split.txt b/src/cmd/go/testdata/script/mod_get_split.txt new file mode 100644 index 0000000000..f4e7661f9b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_split.txt @@ -0,0 +1,157 @@ +cp go.mod go.mod.orig + + +# 'go get' on a package already provided by the build list should update +# the module already in the build list, not fail with an ambiguous import error. + +go get -d example.net/split/nested@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + +# We should get the same behavior if we use a pattern that matches only that package. + +cp go.mod.orig go.mod + +go get -d example.net/split/nested/...@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + + +# If we request a version for which the package only exists in one particular module, +# we should add that one particular module but not resolve import ambiguities. +# +# In particular, if the module that previously provided the package has a +# matching version, but does not itself match the pattern and contains no +# matching packages, we should not change its version. (We should *not* downgrade +# module example.net/split to v0.1.0, despite the fact that +# example.net/split v0.2.0 currently provides the package with the requested path.) +# +# TODO(#27899): Maybe we should resolve the ambiguities by upgrading. + +cp go.mod.orig go.mod + +! go get -d example.net/split/nested@v0.1.0 +stderr '^example.net/split/nested: ambiguous import: found package example.net/split/nested in multiple modules:\n\texample.net/split v0.2.0 \(.*split.2[/\\]nested\)\n\texample.net/split/nested v0.1.0 \(.*nested.1\)$' + +# A wildcard that matches packages in some module at its selected version +# but not at the requested version should fail. +# +# We can't set the module to the selected version, because that version doesn't +# even match the query: if we ran the same query twice, we wouldn't consider the +# module to match the wildcard during the second call, so why should we consider +# it to match during the first one? ('go get' should be idempotent, and if we +# did that then it would not be.) +# +# But we also can't leave it where it is: the user requested that we set everything +# matching the pattern to the given version, and right now we have packages +# that match the pattern but *not* the version. +# +# That only leaves two options: we can set the module to an arbitrary version +# (perhaps 'latest' or 'none'), or we can report an error and the let the user +# disambiguate. We would rather not choose arbitrarily, so we do the latter. +# +# TODO(#27899): Should we instead upgrade or downgrade to an arbirary version? + +! go get -d example.net/split/nested/...@v0.1.0 +stderr '^go get: example.net/split/nested/\.\.\.@v0.1.0 matches packages in example.net/split@v0.2.0 but not example.net/split@v0.1.0: specify a different version for module example.net/split$' + +cmp go.mod go.mod.orig + + +# If another argument resolves the ambiguity, we should be ok again. + +go get -d example.net/split@none example.net/split/nested@v0.1.0 +go list -m all +! stdout '^example.net/split ' +stdout '^example.net/split/nested v0.1.0 ' + +cp go.mod.orig go.mod + +go get -d example.net/split@v0.3.0 example.net/split/nested@v0.1.0 +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.1.0 ' + + +# If a pattern applies to modules and to packages, we should set all matching +# modules to the version indicated by the pattern, and also resolve packages +# to match the pattern if possible. + +cp go.mod.orig go.mod +go get -d example.net/split/nested@v0.0.0 + +go get -d example.net/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' +stdout '^example.net/split/nested v0.1.0 ' + +go get -d example.net/... +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.2.0 ' + + +# @none applies to all matching module paths, +# regardless of whether they contain any packages. + +go get -d example.net/...@none +go list -m all +! stdout '^example.net' + +# Starting from no dependencies, a wildcard can resolve to an empty module with +# the same prefix even if it contains no packages. + +go get -d example.net/...@none +go get -d example.net/split/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' + + +-- go.mod -- +module m + +go 1.16 + +require example.net/split v0.2.0 + +replace ( + example.net/split v0.1.0 => ./split.1 + example.net/split v0.2.0 => ./split.2 + example.net/split v0.2.1 => ./split.2 + example.net/split v0.3.0 => ./split.3 + example.net/split/nested v0.0.0 => ./nested.0 + example.net/split/nested v0.1.0 => ./nested.1 + example.net/split/nested v0.2.0 => ./nested.2 +) +-- split.1/go.mod -- +module example.net/split + +go 1.16 +-- split.2/go.mod -- +module example.net/split + +go 1.16 +-- split.2/nested/nested.go -- +package nested +-- split.3/go.mod -- +module example.net/split + +go 1.16 +-- nested.0/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/nested.go -- +package nested +-- nested.2/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.2/nested.go -- +package nested diff --git a/src/cmd/go/testdata/script/mod_get_sum_noroot.txt b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt new file mode 100644 index 0000000000..4f1cf03277 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt @@ -0,0 +1,11 @@ +# When 'go get' is invoked on a module without a package in the root directory, +# it should add sums for the module's go.mod file and its content to go.sum. +# Verifies golang.org/issue/41103. +go mod init m +go get -d rsc.io/QUOTE +grep '^rsc.io/QUOTE v1.5.2/go.mod ' go.sum +grep '^rsc.io/QUOTE v1.5.2 ' go.sum + +# Double-check rsc.io/QUOTE does not have a root package. +! go list -mod=readonly rsc.io/QUOTE +stderr '^cannot find module providing package rsc.io/QUOTE: import lookup disabled by -mod=readonly$' diff --git a/src/cmd/go/testdata/script/mod_get_test.txt b/src/cmd/go/testdata/script/mod_get_test.txt index 3680ca273d..23722bd4e4 100644 --- a/src/cmd/go/testdata/script/mod_get_test.txt +++ b/src/cmd/go/testdata/script/mod_get_test.txt @@ -2,7 +2,7 @@ env GO111MODULE=on # By default, 'go get' should ignore tests cp go.mod.empty go.mod -go get m/a +go get -d m/a ! grep rsc.io/quote go.mod # 'go get -t' should consider test dependencies of the named package. diff --git a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt index 7b5d90c50b..3b38d8ba7d 100644 --- a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt +++ b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -1,3 +1,6 @@ +# Populate go.sum +go mod download + # go list should succeed to load a package ending with ".go" if the path does # not correspond to an existing local file. Listing a pattern ending with # ".go/" should try to list a package regardless of whether a file exists at the diff --git a/src/cmd/go/testdata/script/mod_get_upgrade.txt b/src/cmd/go/testdata/script/mod_get_upgrade.txt index 6a14dfdc45..eeb6d6f6af 100644 --- a/src/cmd/go/testdata/script/mod_get_upgrade.txt +++ b/src/cmd/go/testdata/script/mod_get_upgrade.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -go get rsc.io/quote@v1.5.1 +go get -d rsc.io/quote@v1.5.1 go list -m all stdout 'rsc.io/quote v1.5.1' grep 'rsc.io/quote v1.5.1$' go.mod diff --git a/src/cmd/go/testdata/script/mod_get_wild.txt b/src/cmd/go/testdata/script/mod_get_wild.txt new file mode 100644 index 0000000000..78c645c6b9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_wild.txt @@ -0,0 +1,95 @@ +# This test covers a crazy edge-case involving wildcards and multiple passes of +# patch-upgrades, but if we get it right we probably get many other edge-cases +# right too. + +go list -m all +stdout '^example.net/a v0.1.0 ' +! stdout '^example.net/b ' + + +# Requesting pattern example.../b by itself fails: there is no such module +# already in the build list, and the wildcard in the first element prevents us +# from attempting to resolve a new module whose path is a prefix of the pattern. + +! go get -d -u=patch example.../b@upgrade +stderr '^go get: no modules to query for example\.\.\./b@upgrade because first path element contains a wildcard$' + + +# Patching . causes a patch to example.net/a, which introduces a new match +# for example.net/b/..., which is itself patched and causes another upgrade to +# example.net/a, which is then patched again. + +go get -d -u=patch . example.../b@upgrade +go list -m all +stdout '^example.net/a v0.2.1 ' # upgraded by dependency of b and -u=patch +stdout '^example.net/b v0.2.0 ' # introduced by patch of a and upgraded by wildcard + + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a20 + example.net/b v0.1.0 => ./b1 + example.net/b v0.1.1 => ./b1 + example.net/b v0.2.0 => ./b2 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a +-- a11/unimported/unimported.go -- +package unimported + +import _ "example.net/b" + + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + +-- b1/go.mod -- +module example.net/b + +go 1.16 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b2/b.go -- +package b +-- b2/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_go_version.txt b/src/cmd/go/testdata/script/mod_go_version.txt index 37f173531b..97d9975e68 100644 --- a/src/cmd/go/testdata/script/mod_go_version.txt +++ b/src/cmd/go/testdata/script/mod_go_version.txt @@ -8,12 +8,19 @@ go build sub.1 go build subver.1 ! stderr 'module requires' ! go build badsub.1 -stderr 'module requires Go 1.11111' +stderr '^note: module requires Go 1.11111$' go build versioned.1 go mod edit -require versioned.1@v1.1.0 ! go build versioned.1 -stderr 'module requires Go 1.99999' +stderr '^note: module requires Go 1.99999$' + +[short] stop + +# The message should be printed even if the compiler emits no output. +go build -o $WORK/nooutput.exe nooutput.go +! go build -toolexec=$WORK/nooutput.exe versioned.1 +stderr '^# versioned.1\nnote: module requires Go 1.99999$' -- go.mod -- module m @@ -71,3 +78,33 @@ go 1.99999 -- versioned2/x.go -- package x invalid syntax + +-- nooutput.go -- +// +build ignore + +package main + +import ( + "bytes" + "os" + "os/exec" + "strings" +) + +func main() { + stderr := new(bytes.Buffer) + stdout := new(bytes.Buffer) + + cmd := exec.Command(os.Args[1], os.Args[2:]...) + cmd.Stderr = stderr + cmd.Stdout = stdout + + err := cmd.Run() + if strings.HasPrefix(os.Args[2], "-V") { + os.Stderr.Write(stderr.Bytes()) + os.Stdout.Write(stdout.Bytes()) + } + if err != nil { + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt index 948496241e..3a133663ec 100644 --- a/src/cmd/go/testdata/script/mod_gobuild_import.txt +++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt @@ -19,7 +19,7 @@ exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go ! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . -stderr 'cannot find module providing package gobuild.example.com/x/y/z/w' +stderr 'no required module provides package gobuild.example.com/x/y/z/w; try ''go get -d gobuild.example.com/x/y/z/w'' to add it' cd z exec $WORK/testimport$GOEXE other/x/y/z/w . diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt index a9e0ca4010..204786969f 100644 --- a/src/cmd/go/testdata/script/mod_gonoproxy.txt +++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt @@ -7,26 +7,32 @@ env dbname=localhost.localdev/sumdb # disagree with sumdb fails cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong -! go get rsc.io/quote +! go get -d rsc.io/quote stderr 'SECURITY ERROR' # GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text env GONOSUMDB='*/quote,*/*mple*,golang.org/x' -go get rsc.io/quote +go get -d rsc.io/quote rm go.sum env GOPRIVATE='*/quote,*/*mple*,golang.org/x' env GONOPROXY=none # that is, proxy all despite GOPRIVATE -go get rsc.io/quote +go get -d rsc.io/quote + +# Download .info files needed for 'go list -m all' later. +# TODO(#42723): either 'go list -m' should not read these files, +# or 'go get' and 'go mod tidy' should download them. +go list -m all +stdout '^golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c$' # When GOPROXY is not empty but contains no entries, an error should be reported. env GOPROXY=',' -! go get golang.org/x/text +! go get -d golang.org/x/text stderr '^go get golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$' # When GOPROXY=off, fetching modules not matched by GONOPROXY fails. env GONOPROXY=*/fortune env GOPROXY=off -! go get golang.org/x/text +! go get -d golang.org/x/text stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' # GONOPROXY bypasses proxy @@ -34,13 +40,13 @@ stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' [!exec:git] skip env GOPRIVATE=none env GONOPROXY='*/fortune' -! go get rsc.io/fortune # does not exist in real world, only on test proxy +! go get -d rsc.io/fortune # does not exist in real world, only on test proxy stderr 'git ls-remote' env GOSUMDB= env GONOPROXY= env GOPRIVATE='*/x' -go get golang.org/x/text +go get -d golang.org/x/text go list -m all ! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy diff --git a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt index 9d288a64d4..5ad9106378 100644 --- a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt +++ b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt @@ -12,7 +12,7 @@ go list env GOPROXY=direct env GOSUMDB=off -go get gopkg.in/macaroon-bakery.v2-unstable/bakery +go get -d gopkg.in/macaroon-bakery.v2-unstable/bakery go list -m all stdout 'gopkg.in/macaroon-bakery.v2-unstable v2.0.0-[0-9]+-[0-9a-f]+$' diff --git a/src/cmd/go/testdata/script/mod_import.txt b/src/cmd/go/testdata/script/mod_import.txt index 3985b43144..28358b5b0c 100644 --- a/src/cmd/go/testdata/script/mod_import.txt +++ b/src/cmd/go/testdata/script/mod_import.txt @@ -1,7 +1,7 @@ env GO111MODULE=on # latest rsc.io/quote should be v1.5.2 not v1.5.3-pre1 -go list +go get -d go list -m all stdout 'rsc.io/quote v1.5.2' diff --git a/src/cmd/go/testdata/script/mod_import_issue41113.txt b/src/cmd/go/testdata/script/mod_import_issue41113.txt new file mode 100644 index 0000000000..fed2510f57 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue41113.txt @@ -0,0 +1,28 @@ +# Regression test for https://golang.org/issue/41113. +# +# When resolving a missing import path, the inability to add the package from +# one module path should not interfere with adding a nested path. + +# Initially, our module depends on split-incompatible v2.1.0-pre+incompatible, +# from which an imported package has been removed (and relocated to the nested +# split-incompatible/subpkg module). modload.QueryPattern will suggest +# split-incompatible v2.0.0+incompatible, which we cannot use (because it would +# be an implicit downgrade), and split-incompatible/subpkg v0.1.0, which we +# *should* use. + +go mod tidy + +go list -m all +stdout '^example.com/split-incompatible/subpkg v0\.1\.0$' +! stdout '^example.com/split-incompatible .*' + +-- go.mod -- +module golang.org/issue/41113 + +go 1.16 + +require example.com/split-incompatible v2.1.0-pre+incompatible +-- x.go -- +package issue41113 + +import _ "example.com/split-incompatible/subpkg" diff --git a/src/cmd/go/testdata/script/mod_import_issue42891.txt b/src/cmd/go/testdata/script/mod_import_issue42891.txt new file mode 100644 index 0000000000..a78cab29ba --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue42891.txt @@ -0,0 +1,14 @@ +# If an import declaration is an absolute path, most commands should report +# an error instead of going into an infinite loop. +# Verifies golang.org/issue/42891. +go list . +stdout '^m$' + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m + +import "/" diff --git a/src/cmd/go/testdata/script/mod_import_meta.txt b/src/cmd/go/testdata/script/mod_import_meta.txt new file mode 100644 index 0000000000..0e469d09d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_meta.txt @@ -0,0 +1,45 @@ +# The loader should not attempt to resolve imports of the "all", "std", and "cmd" meta-packages. + +! go list -deps ./importall +! stderr 'internal error' +stderr '^importall[/\\]x.go:3:8: "all" is not an importable package; see ''go help packages''$' + +! go list -deps ./importcmd +! stderr 'internal error' +stderr '^importcmd[/\\]x.go:3:8: "cmd" is not an importable package; see ''go help packages''$' + +! go list -deps ./importstd +! stderr 'internal error' +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +# Not even if such a path is theoretically provided by a (necessarily replaced) module. + +go mod edit -replace std@v0.1.0=./modstd +go mod edit -require std@v0.1.0 + +! go list -deps ./importstd +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +-- go.mod -- +module example.com +go 1.16 +-- importall/x.go -- +package importall + +import _ "all" +-- importcmd/x.go -- +package importcmd + +import _ "cmd" +-- importstd/x.go -- +package importstd + +import _ "std" +-- modstd/go.mod -- +module std +go 1.16 +-- modstd/std.go -- +// Package std is an incredibly confusingly-named package. +package std diff --git a/src/cmd/go/testdata/script/mod_in_testdata_dir.txt b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt index f582569798..66f79faa6d 100644 --- a/src/cmd/go/testdata/script/mod_in_testdata_dir.txt +++ b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt @@ -8,8 +8,8 @@ env GO111MODULE=on cd $WORK/testdata go mod init testdata.tld/foo -# Building a package within that module should resolve its dependencies. -go build +# Getting a package within that module should resolve its dependencies. +go get -d grep 'rsc.io/quote' go.mod # Tidying the module should preserve those dependencies. @@ -26,7 +26,7 @@ exists vendor/rsc.io/quote cd $WORK/_ignored go mod init testdata.tld/foo -go build +go get grep 'rsc.io/quote' go.mod go mod tidy diff --git a/src/cmd/go/testdata/script/mod_indirect.txt b/src/cmd/go/testdata/script/mod_indirect.txt index 87a3f0b10f..6ea1cae98b 100644 --- a/src/cmd/go/testdata/script/mod_indirect.txt +++ b/src/cmd/go/testdata/script/mod_indirect.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -# golang.org/issue/31248: module requirements imposed by dependency versions +# golang.org/issue/31248: required modules imposed by dependency versions # older than the selected version must still be taken into account. env GOFLAGS=-mod=readonly diff --git a/src/cmd/go/testdata/script/mod_init_dep.txt b/src/cmd/go/testdata/script/mod_init_dep.txt index 755076eae8..f8cf1d563a 100644 --- a/src/cmd/go/testdata/script/mod_init_dep.txt +++ b/src/cmd/go/testdata/script/mod_init_dep.txt @@ -1,24 +1,14 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod # modconv uses git directly to examine what old 'go get' would [!net] skip [!exec:git] skip -# go build should populate go.mod from Gopkg.lock -cp go.mod1 go.mod -go build +# go mod init should populate go.mod from Gopkg.lock +go mod init x stderr 'copying requirements from Gopkg.lock' go list -m all -! stderr 'copying requirements from Gopkg.lock' -stdout 'rsc.io/sampler v1.0.0' - -# go list should populate go.mod from Gopkg.lock -cp go.mod1 go.mod -go list -stderr 'copying requirements from Gopkg.lock' -go list -! stderr 'copying requirements from Gopkg.lock' -go list -m all stdout 'rsc.io/sampler v1.0.0' # test dep replacement @@ -26,9 +16,6 @@ cd y go mod init cmpenv go.mod go.mod.replace --- go.mod1 -- -module x - -- x.go -- package x @@ -54,4 +41,4 @@ go $goversion replace z v1.0.0 => rsc.io/quote v1.0.0 -require rsc.io/quote v1.0.0
\ No newline at end of file +require rsc.io/quote v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_init_path.txt b/src/cmd/go/testdata/script/mod_init_path.txt index 637c29f4bc..ccdfc92317 100644 --- a/src/cmd/go/testdata/script/mod_init_path.txt +++ b/src/cmd/go/testdata/script/mod_init_path.txt @@ -1,7 +1,7 @@ env GO111MODULE=on ! go mod init . -stderr 'malformed import path' +stderr '^go: invalid module path "\.": is a local import path$' cd x go mod init example.com/x diff --git a/src/cmd/go/testdata/script/mod_init_tidy.txt b/src/cmd/go/testdata/script/mod_init_tidy.txt new file mode 100644 index 0000000000..6a37edd960 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_tidy.txt @@ -0,0 +1,30 @@ +# 'go mod init' should not recommend 'go mod tidy' in an empty directory +# (one that contains no non-hidden .go files or subdirectories). +cd empty +go mod init m +! stderr tidy +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a .go file. +cd pkginroot +go mod init m +stderr '^go: run ''go mod tidy'' to add module requirements and sums$' +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a +# subdirectory. We don't walk the tree to see if it has .go files. +cd subdir +go mod init m +stderr '^go: run ''go mod tidy'' to add module requirements and sums$' +cd .. + +-- empty/empty.txt -- +Not a .go file. Still counts as an empty project. +-- empty/.hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- empty/_hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- pkginroot/hello.go -- +package vendorimport +-- subdir/sub/empty.txt -- +Subdirectory doesn't need to contain a package. diff --git a/src/cmd/go/testdata/script/mod_install_pkg_version.txt b/src/cmd/go/testdata/script/mod_install_pkg_version.txt new file mode 100644 index 0000000000..e4a7668351 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_pkg_version.txt @@ -0,0 +1,198 @@ +# 'go install pkg@version' works outside a module. +env GO111MODULE=auto +go install example.com/cmd/a@v1.0.0 +exists $GOPATH/bin/a$GOEXE +rm $GOPATH/bin + + +# 'go install pkg@version' reports an error if modules are disabled. +env GO111MODULE=off +! go install example.com/cmd/a@v1.0.0 +stderr '^go: modules disabled by GO111MODULE=off; see ''go help modules''$' +env GO111MODULE=auto + + +# 'go install pkg@version' ignores go.mod in current directory. +cd m +cp go.mod go.mod.orig +! go list -m all +stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; try ''go mod download example.com/cmd'' to add it$' +go install example.com/cmd/a@latest +cmp go.mod go.mod.orig +exists $GOPATH/bin/a$GOEXE +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' # "latest", not from go.mod +rm $GOPATH/bin/a +cd .. + + +# 'go install -modfile=x.mod pkg@version' reports an error, but only if +# -modfile is specified explicitly on the command line. +cd m +env GOFLAGS=-modfile=go.mod +go install example.com/cmd/a@latest # same as above +env GOFLAGS= +! go install -modfile=go.mod example.com/cmd/a@latest +stderr '^go: -modfile cannot be used with commands that ignore the current module$' +cd .. + + +# Every test case requires linking, so we only cover the most important cases +# when -short is set. +[short] stop + + +# 'go install pkg@version' works on a module that doesn't have a go.mod file +# and with a module whose go.mod file has missing requirements. +# With a proxy, the two cases are indistinguishable. +go install rsc.io/fortune@v1.0.0 +stderr '^go: found rsc.io/quote in rsc.io/quote v1.5.2$' +exists $GOPATH/bin/fortune$GOEXE +! exists $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0/go.mod # no go.mod file +go version -m $GOPATH/bin/fortune$GOEXE +stdout '^\tdep\trsc.io/quote\tv1.5.2\t' # latest version of fortune's dependency +rm $GOPATH/bin + + +# 'go install dir@version' works like a normal 'go install' command if +# dir is a relative or absolute path. +env GO111MODULE=on +go mod download rsc.io/fortune@v1.0.0 +! go install $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: cannot find main module; see ''go help modules''$' +! go install ../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: cannot find main module; see ''go help modules''$' +mkdir tmp +cd tmp +go mod init tmp +go mod edit -require=rsc.io/fortune@v1.0.0 +! go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; try ''go mod download rsc.io/fortune'' to add it$' +! go install -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; try ''go mod download rsc.io/fortune'' to add it$' +go get -d rsc.io/fortune@v1.0.0 +go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +exists $GOPATH/bin/fortune$GOEXE +cd .. +rm tmp +rm $GOPATH/bin +env GO111MODULE=auto + +# 'go install pkg@version' reports errors for meta packages, std packages, +# and directories. +! go install std@v1.0.0 +stderr '^go install std@v1.0.0: argument must be a package path, not a meta-package$' +! go install fmt@v1.0.0 +stderr '^go install fmt@v1.0.0: argument must not be a package in the standard library$' +! go install example.com//cmd/a@v1.0.0 +stderr '^go install example.com//cmd/a@v1.0.0: argument must be a clean package path$' +! go install example.com/cmd/a@v1.0.0 ./x@v1.0.0 +stderr '^go install ./x@v1.0.0: argument must be a package path, not a relative path$' +! go install example.com/cmd/a@v1.0.0 $GOPATH/src/x@v1.0.0 +stderr '^go install '$WORK'[/\\]gopath/src/x@v1.0.0: argument must be a package path, not an absolute path$' +! go install example.com/cmd/a@v1.0.0 cmd/...@v1.0.0 +stderr '^go install: package cmd/go not provided by module example.com/cmd@v1.0.0$' + +# 'go install pkg@version' should accept multiple arguments but report an error +# if the version suffixes are different, even if they refer to the same version. +go install example.com/cmd/a@v1.0.0 example.com/cmd/b@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +env GO111MODULE=on +go list -m example.com/cmd@latest +stdout '^example.com/cmd v1.0.0$' +env GO111MODULE=auto + +! go install example.com/cmd/a@v1.0.0 example.com/cmd/b@latest +stderr '^go install example.com/cmd/b@latest: all arguments must have the same version \(@v1.0.0\)$' + + +# 'go install pkg@version' should report an error if the arguments are in +# different modules. +! go install example.com/cmd/a@v1.0.0 rsc.io/fortune@v1.0.0 +stderr '^go install: package rsc.io/fortune provided by module rsc.io/fortune@v1.0.0\n\tAll packages must be provided by the same module \(example.com/cmd@v1.0.0\).$' + + +# 'go install pkg@version' should report an error if an argument is not +# a main package. +! go install example.com/cmd/a@v1.0.0 example.com/cmd/err@v1.0.0 +stderr '^go install: package example.com/cmd/err is not a main package$' + +# Wildcards should match only main packages. This module has a non-main package +# with an error, so we'll know if that gets built. +mkdir tmp +cd tmp +go mod init m +go get -d example.com/cmd@v1.0.0 +! go build example.com/cmd/... +stderr 'err[/\\]err.go:3:9: undefined: DoesNotCompile$' +cd .. + +go install example.com/cmd/...@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +# If a wildcard matches no packages, we should see a warning. +! go install example.com/cmd/nomatch...@v1.0.0 +stderr '^go install example.com/cmd/nomatch\.\.\.@v1.0.0: module example.com/cmd@v1.0.0 found, but does not contain packages matching example.com/cmd/nomatch\.\.\.$' +go install example.com/cmd/a@v1.0.0 example.com/cmd/nomatch...@v1.0.0 +stderr '^go: warning: "example.com/cmd/nomatch\.\.\." matched no packages$' + +# If a wildcard matches only non-main packges, we should see a different warning. +go install example.com/cmd/err...@v1.0.0 +stderr '^go: warning: "example.com/cmd/err\.\.\." matched no main packages$' + + +# 'go install pkg@version' should report errors if the module contains +# replace or exclude directives. +go mod download example.com/cmd@v1.0.0-replace +! go install example.com/cmd/a@v1.0.0-replace +cmp stderr replace-err + +go mod download example.com/cmd@v1.0.0-exclude +! go install example.com/cmd/a@v1.0.0-exclude +cmp stderr exclude-err + +# 'go install pkg@version' should report an error if the module requires a +# higher version of itself. +! go install example.com/cmd/a@v1.0.0-newerself +stderr '^go install example.com/cmd/a@v1.0.0-newerself: version constraints conflict:\n\texample.com/cmd@v1.0.0-newerself requires example.com/cmd@v1.0.0, but example.com/cmd@v1.0.0-newerself is requested$' + + +# 'go install pkg@version' will only match a retracted version if it's +# explicitly requested. +env GO111MODULE=on +go list -m -versions example.com/cmd +! stdout v1.9.0 +go list -m -versions -retracted example.com/cmd +stdout v1.9.0 +go install example.com/cmd/a@latest +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' +go install example.com/cmd/a@v1.9.0 +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.9.0\t' + +-- m/go.mod -- +module m + +go 1.16 + +require example.com/cmd v1.1.0-doesnotexist +-- x/x.go -- +package main + +func main() {} +-- replace-err -- +go install example.com/cmd/a@v1.0.0-replace: example.com/cmd@v1.0.0-replace + The go.mod file for the module providing named packages contains one or + more replace directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. +-- exclude-err -- +go install example.com/cmd/a@v1.0.0-exclude: example.com/cmd@v1.0.0-exclude + The go.mod file for the module providing named packages contains one or + more exclude directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. diff --git a/src/cmd/go/testdata/script/mod_install_versioned.txt b/src/cmd/go/testdata/script/mod_install_versioned.txt index 03986d06a0..c6bce418b4 100644 --- a/src/cmd/go/testdata/script/mod_install_versioned.txt +++ b/src/cmd/go/testdata/script/mod_install_versioned.txt @@ -1,9 +1,11 @@ env GO111MODULE=on +go get -d rsc.io/fortune go list -f '{{.Target}}' rsc.io/fortune ! stdout fortune@v1 stdout 'fortune(\.exe)?$' +go get -d rsc.io/fortune/v2 go list -f '{{.Target}}' rsc.io/fortune/v2 ! stdout v2 stdout 'fortune(\.exe)?$' diff --git a/src/cmd/go/testdata/script/mod_internal.txt b/src/cmd/go/testdata/script/mod_internal.txt index 1193d528ec..687269d18f 100644 --- a/src/cmd/go/testdata/script/mod_internal.txt +++ b/src/cmd/go/testdata/script/mod_internal.txt @@ -3,30 +3,34 @@ env GO111MODULE=on # golang.org/x/internal should be importable from other golang.org/x modules. go mod edit -module=golang.org/x/anything -go build . +go get -d . # ...and their tests... go test stdout PASS # ...but that should not leak into other modules. +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' # Internal packages in the standard library should not leak into modules. +go get -d ./fromstd ! go build ./fromstd stderr 'use of internal package internal/testenv not allowed' # Dependencies should be able to use their own internal modules... go mod edit -module=golang.org/notx -go build ./throughdep +go get -d ./throughdep # ... but other modules should not, even if they have transitive dependencies. +go get -d . ! go build . stderr 'use of internal package golang.org/x/.* not allowed' # And transitive dependencies still should not leak. +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' @@ -34,15 +38,17 @@ stderr 'use of internal package golang.org/x/.* not allowed' # Replacing an internal module should keep it internal to the same paths. go mod edit -module=golang.org/notx go mod edit -replace golang.org/x/internal=./replace/golang.org/notx/internal -go build ./throughdep +go get -d ./throughdep +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' go mod edit -replace golang.org/x/internal=./vendor/golang.org/x/internal -go build ./throughdep +go get -d ./throughdep +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt index 6dddd4b036..43b9564356 100644 --- a/src/cmd/go/testdata/script/mod_invalid_version.txt +++ b/src/cmd/go/testdata/script/mod_invalid_version.txt @@ -4,6 +4,7 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOFLAGS=-mod=mod # Regression test for golang.org/issue/27173: if the user (or go.mod file) # requests a pseudo-version that does not match both the module path and commit @@ -221,7 +222,7 @@ stdout 'github.com/pierrec/lz4 v2.0.5\+incompatible' # not resolve to a pseudo-version with a different major version. cp go.mod.orig go.mod ! go get -d github.com/pierrec/lz4@v2.0.8 -stderr 'go get github.com/pierrec/lz4@v2.0.8: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2' +stderr 'go get: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2' # An invalid +incompatible suffix for a canonical version should error out, # not resolve to a pseudo-version. diff --git a/src/cmd/go/testdata/script/mod_issue35317.txt b/src/cmd/go/testdata/script/mod_issue35317.txt index 92416a54e4..b1852ab031 100644 --- a/src/cmd/go/testdata/script/mod_issue35317.txt +++ b/src/cmd/go/testdata/script/mod_issue35317.txt @@ -5,4 +5,4 @@ env GO111MODULE=on [short] skip go mod init example.com -go get golang.org/x/text@v0.3.0 golang.org/x/internal@v0.1.0 golang.org/x/exp@none +go get -d golang.org/x/text@v0.3.0 golang.org/x/internal@v0.1.0 golang.org/x/exp@none diff --git a/src/cmd/go/testdata/script/mod_lazy_downgrade.txt b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt new file mode 100644 index 0000000000..1e84820f81 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt @@ -0,0 +1,145 @@ +# This test illustrates the interaction between lazy loading and downgrading in +# 'go get. + +# The package import graph used in this test looks like: +# +# lazy ---- a +# | +# a_test ---- b +# b_test ---- c +# +# The module dependency graph initially looks like: +# +# lazy ---- a.1 ---- b.1 ---- c.1 +# \ / +# b.3 ---- c.2 b.2 +# +# (Note that lazy loading will prune out the dependency from b.1 on c.1.) + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +# Downgrading c should also downgrade the b that requires it. + +go get -d example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +# Removing c entirely should also remove the a and b that require it. + +go get -d example.com/c@none +go list -m all +! stdout '^example.com/a ' +! stdout '^example.com/b ' +! stdout '^example.com/c ' + + +# With lazy loading, downgrading c should work the same way, but dependencies +# outside of the deepening scan should not affect the downgrade. + +cp go.mod.orig go.mod +go mod edit -go=1.16 + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +go get -d example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +go get -d example.com/c@none +go list -m all +! stdout '^example.com/a ' # TODO(#36460): example.com/a v0.1.0 +! stdout '^example.com/b ' # TODO(#36460): example.com/b v0.1.0 +! stdout '^example.com/c ' + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require ( + example.com/a v0.1.0 + example.com/b v0.3.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/b v0.3.0 => ./b3 + example.com/c v0.1.0 => ./c + example.com/c v0.2.0 => ./c +) +-- lazy.go -- +package lazy + +import _ "example.com/a" + +-- a/go.mod -- +module example.com/a + +go 1.15 + +require example.com/b v0.1.0 +-- a/a.go -- +package a +-- a/a_test.go -- +package a_test + +import _ "example.com/b" + +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b_test +import _ "example.com/c" + +-- b2/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b2/b.go -- +package b +-- b2/b_test.go -- +package b_test +import _ "example.com/c" + +-- b3/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.2.0 +-- b3/b.go -- +package b +-- b3/b_test.go -- +package b_test +import _ "example.com/c" + +-- c/go.mod -- +module example.com/c + +go 1.15 +-- c/c.go -- +package c diff --git a/src/cmd/go/testdata/script/mod_list.txt b/src/cmd/go/testdata/script/mod_list.txt index 17b33fcc7b..1ba6d7c910 100644 --- a/src/cmd/go/testdata/script/mod_list.txt +++ b/src/cmd/go/testdata/script/mod_list.txt @@ -2,12 +2,12 @@ env GO111MODULE=on [short] skip # list {{.Dir}} shows main module and go.mod but not not-yet-downloaded dependency dir. -go list -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all +go list -mod=mod -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all stdout '^x true .*[\\/]src[\\/]go.mod .*[\\/]src$' stdout '^rsc.io/quote false .*[\\/]v1.5.2.mod $' # list {{.Dir}} shows dependency after download (and go list without -m downloads it) -go list -f '{{.Dir}}' rsc.io/quote +go list -mod=mod -f '{{.Dir}}' rsc.io/quote stdout '.*mod[\\/]rsc.io[\\/]quote@v1.5.2$' # downloaded dependencies are read-only @@ -20,7 +20,7 @@ go clean -modcache # list {{.Dir}} shows replaced directories cp go.mod2 go.mod -go list -f {{.Dir}} rsc.io/quote +go list -mod=mod -f {{.Dir}} rsc.io/quote go list -m -f '{{.Path}} {{.Version}} {{.Dir}}{{with .Replace}} {{.GoMod}} => {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' all stdout 'mod[\\/]rsc.io[\\/]quote@v1.5.1' stdout 'v1.3.0.*mod[\\/]rsc.io[\\/]sampler@v1.3.1 .*[\\/]v1.3.1.mod => v1.3.1.*sampler@v1.3.1 .*[\\/]v1.3.1.mod' @@ -30,7 +30,7 @@ go list std stdout ^math/big # rsc.io/quote/buggy should be listable as a package -go list rsc.io/quote/buggy +go list -mod=mod rsc.io/quote/buggy # rsc.io/quote/buggy should not be listable as a module go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy diff --git a/src/cmd/go/testdata/script/mod_list_bad_import.txt b/src/cmd/go/testdata/script/mod_list_bad_import.txt index 8a66e0b72a..3cd50b0de2 100644 --- a/src/cmd/go/testdata/script/mod_list_bad_import.txt +++ b/src/cmd/go/testdata/script/mod_list_bad_import.txt @@ -12,10 +12,11 @@ stdout 'incomplete' stdout 'bad dep: .*example.com/notfound' # Listing with -deps should also fail. -# BUG: Today, it does not. -# ! go list -deps example.com/direct -# stderr example.com/notfound -go list -deps example.com/direct +! go list -deps example.com/direct +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct stdout example.com/notfound @@ -28,16 +29,17 @@ stdout incomplete stdout 'bad dep: .*example.com/notfound' # Again, -deps should fail. -# BUG: Again, it does not. -# ! go list -deps example.com/indirect -# stderr example.com/notfound -go list -deps example.com/indirect +! go list -deps example.com/indirect +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/indirect stdout example.com/notfound # Listing the missing dependency directly should fail outright... ! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound -stderr 'cannot find module providing package example.com/notfound' +stderr 'no required module provides package example.com/notfound; try ''go get -d example.com/notfound'' to add it' ! stdout error ! stdout incomplete diff --git a/src/cmd/go/testdata/script/mod_list_dir.txt b/src/cmd/go/testdata/script/mod_list_dir.txt index 6653435a06..1adab8f027 100644 --- a/src/cmd/go/testdata/script/mod_list_dir.txt +++ b/src/cmd/go/testdata/script/mod_list_dir.txt @@ -2,6 +2,9 @@ # go list with path to directory should work +# populate go.sum +go get -d + env GO111MODULE=off go list -f '{{.ImportPath}}' $GOROOT/src/math stdout ^math$ @@ -29,3 +32,5 @@ require rsc.io/quote v1.5.2 -- x.go -- package x + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_direct.txt b/src/cmd/go/testdata/script/mod_list_direct.txt index 8f85871189..62a472f475 100644 --- a/src/cmd/go/testdata/script/mod_list_direct.txt +++ b/src/cmd/go/testdata/script/mod_list_direct.txt @@ -10,7 +10,7 @@ env GOSUMDB=off # For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file, # which would produce a hard error at the subsequent call to GoMod. -go list all +go get -d -- go.mod -- module example.com diff --git a/src/cmd/go/testdata/script/mod_list_replace_dir.txt b/src/cmd/go/testdata/script/mod_list_replace_dir.txt index cad7fe2528..f2f2d2b2bb 100644 --- a/src/cmd/go/testdata/script/mod_list_replace_dir.txt +++ b/src/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -2,8 +2,11 @@ # module within the module cache. # Verifies golang.org/issue/29548 -env GO111MODULE=on -go mod download rsc.io/quote@v1.5.1 rsc.io/quote@v1.5.2 +# Populate go.sum and download dependencies. +go get -d + +# Ensure v1.5.2 is also in the cache so we can list it. +go mod download rsc.io/quote@v1.5.2 ! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside available modules$' @@ -17,3 +20,8 @@ module example.com/quoter require rsc.io/quote v1.5.2 replace rsc.io/quote => rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_retract.txt b/src/cmd/go/testdata/script/mod_list_retract.txt index 4e177b3f54..3ba53bc596 100644 --- a/src/cmd/go/testdata/script/mod_list_retract.txt +++ b/src/cmd/go/testdata/script/mod_list_retract.txt @@ -32,9 +32,9 @@ go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-u # 'go list -m -retracted mod@version' shows an error if the go.mod that should # contain the retractions is not available. ! go list -m -retracted example.com/retract/missingmod@v1.0.0 -stderr '^go list -m: loading module retractions: example.com/retract/missingmod@v1.9.0:.*404 Not Found$' +stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' go list -e -m -retracted -f '{{.Error.Err}}' example.com/retract/missingmod@v1.0.0 -stdout '^loading module retractions: example.com/retract/missingmod@v1.9.0:.*404 Not Found$' +stdout '^loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' # 'go list -m -retracted mod@version' shows retractions. go list -m -retracted example.com/retract@v1.0.0-unused diff --git a/src/cmd/go/testdata/script/mod_list_std.txt b/src/cmd/go/testdata/script/mod_list_std.txt index 76a3b00d1c..baf7908ab9 100644 --- a/src/cmd/go/testdata/script/mod_list_std.txt +++ b/src/cmd/go/testdata/script/mod_list_std.txt @@ -6,8 +6,13 @@ env GOPROXY=off # Outside of GOROOT, our vendored packages should be reported as part of the standard library. go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd -stdout ^vendor/golang.org/x/net/http2/hpack +stdout ^vendor/golang\.org/x/net/http2/hpack stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm +! stdout ^golang\.org/x/ + +# The dependencies of those packages should also be vendored. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang\.org/x/crypto/internal/subtle # cmd/... should match the same packages it used to match in GOPATH mode. go list cmd/... @@ -23,40 +28,57 @@ stdout ^bytes$ ! stdout ^builtin$ ! stdout ^cmd/ ! stdout ^vendor/ +! stdout ^golang\.org/x/ + +# Vendored dependencies should appear with their 'vendor/' paths in std (they're +# in GOROOT/src, but not in the 'std' module following the usual module-boundary +# rules). -# Within the std module, listing ./... should omit the 'std' prefix: -# the package paths should be the same via ./... or the 'std' meta-pattern. -# TODO(golang.org/issue/30241): Make that work. -# Today, they are listed in 'std' but not './...'. cd $GOROOT/src -go list ./... -! stdout ^vendor/golang.org/x # TODO: should be included, or should be omitted from 'std'. -cp stdout $WORK/listdot.txt go list std -stdout ^vendor/golang.org/x # TODO: remove vendor/ prefix -# TODO: cmp stdout $WORK/listdot.txt +stdout ^vendor/golang.org/x/net/http2/hpack +! stdout ^golang\.org/x + +# The dependencies of packages with an explicit 'vendor/' prefix should +# still themselves resolve to vendored packages. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang.org/x/crypto/internal/subtle +! stdout ^golang\.org/x + +# Within the std module, the dependencies of the non-vendored packages within +# std should appear to come from modules, but they should be loaded from the +# vendor directory (just like ordinary vendored module dependencies). go list all -stdout ^vendor/golang.org/x # TODO: remove vendor/ prefix. +stdout ^golang.org/x/ ! stdout ^std/ +! stdout ^cmd/ +! stdout ^vendor/ +go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std +! stdout ^vendor/golang.org/x/net/http2/hpack +stdout ^golang.org/x/net/http2/hpack -# Within the std module, the vendored dependencies of std should appear -# to come from the actual modules. -# TODO(golang.org/issue/30241): Make that work. -# Today, they still have the vendor/ prefix. -go list std -stdout ^vendor/golang.org/x/net/http2/hpack # TODO -! stdout ^golang.org/x/net/http2/hpack # TODO +go list -f '{{.Dir}}' golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor -go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std -# ! stdout ^vendor/golang.org/x/net/http2/hpack # TODO -! stdout ^golang.org/x/net/http2/hpack # TODO +# Within the std module, the packages within the module should omit the 'std/' +# prefix (they retain their own identities), but should respect normal module +# boundaries (vendored packages are not included in the module, even though they +# are included in the 'std' pattern). + +go list ./... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ # Within std, the vendored dependencies of cmd should still appear to be part of cmd. + go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' cmd stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm diff --git a/src/cmd/go/testdata/script/mod_list_upgrade.txt b/src/cmd/go/testdata/script/mod_list_upgrade.txt index 474df0dc26..0cef04b89a 100644 --- a/src/cmd/go/testdata/script/mod_list_upgrade.txt +++ b/src/cmd/go/testdata/script/mod_list_upgrade.txt @@ -1,5 +1,9 @@ env GO111MODULE=on +# Populate go.sum +go list -m -mod=mod all + +# Check for upgrades. go list -m -u all stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' diff --git a/src/cmd/go/testdata/script/mod_load_badchain.txt b/src/cmd/go/testdata/script/mod_load_badchain.txt index 67d9a1584f..c0c382bfa6 100644 --- a/src/cmd/go/testdata/script/mod_load_badchain.txt +++ b/src/cmd/go/testdata/script/mod_load_badchain.txt @@ -28,10 +28,10 @@ cmp stderr list-expected # Try listing a package that imports a package # in a module without a requirement. go mod edit -droprequire example.com/badchain/a -! go list m/use +! go list -mod=mod m/use cmp stderr list-missing-expected -! go list -test m/testuse +! go list -mod=mod -test m/testuse cmp stderr list-missing-test-expected -- go.mod.orig -- @@ -40,6 +40,19 @@ module m go 1.13 require example.com/badchain/a v1.0.0 +-- go.sum -- +example.com/badchain/a v1.0.0 h1:iJDLiHLmpQgr9Zrv+44UqywAE2IG6WkHnH4uG08vf+s= +example.com/badchain/a v1.0.0/go.mod h1:6/gnCYHdVrs6mUgatUYUSbuHxEY+/yWedmTggLz23EI= +example.com/badchain/a v1.1.0 h1:cPxQpsOjaIrn05yDfl4dFFgGSbjYmytLqtIIBfTsEqA= +example.com/badchain/a v1.1.0/go.mod h1:T15b2BEK+RY7h7Lr2dgS38p1pgH5/t7Kf5nQXBlcW/A= +example.com/badchain/b v1.0.0 h1:kjDVlBxpjQavYxHE7ECCyyXhfwsfhWIqvghfRgPktSA= +example.com/badchain/b v1.0.0/go.mod h1:sYsH934pMc3/A2vQZh019qrWmp4+k87l3O0VFUYqL+I= +example.com/badchain/b v1.1.0 h1:iEALV+DRN62FArnYylBR4YwCALn/hCdITvhdagHa0L4= +example.com/badchain/b v1.1.0/go.mod h1:mlCgKO7lRZ+ijwMFIBFRPCGt5r5oqCcHdhSSE0VL4uY= +example.com/badchain/c v1.0.0 h1:lOeUHQKR7SboSH7Bj6eIDWoNHaDQXI0T2GfaH2x9fNA= +example.com/badchain/c v1.0.0/go.mod h1:4U3gzno17SaQ2koSVNxITu9r60CeLSgye9y4/5LnfOE= +example.com/badchain/c v1.1.0 h1:VtTg1g7fOutWKHQf+ag04KLRpdMGSfQ9s9tagVtGW14= +example.com/badchain/c v1.1.0/go.mod h1:tyoJj5qh+qtb48sflwdVvk4R+OjPQEY2UJOoibsVLPk= -- use/use.go -- package use @@ -56,14 +69,13 @@ import ( func Test(t *testing.T) {} -- update-main-expected -- -go: example.com/badchain/c upgrade => v1.1.0 go get: example.com/badchain/c@v1.0.0 updating to example.com/badchain/c@v1.1.0: parsing go.mod: module declares its path as: badchain.example.com/c but was required as: example.com/badchain/c -- update-a-expected -- -go: example.com/badchain/a upgrade => v1.1.0 -go get: example.com/badchain/a@v1.1.0 requires +go get: example.com/badchain/a@v1.0.0 updating to + example.com/badchain/a@v1.1.0 requires example.com/badchain/b@v1.1.0 requires example.com/badchain/c@v1.1.0: parsing go.mod: module declares its path as: badchain.example.com/c diff --git a/src/cmd/go/testdata/script/mod_load_badmod.txt b/src/cmd/go/testdata/script/mod_load_badmod.txt index 68c8b3792b..fa22e1808b 100644 --- a/src/cmd/go/testdata/script/mod_load_badmod.txt +++ b/src/cmd/go/testdata/script/mod_load_badmod.txt @@ -1,14 +1,13 @@ # Unknown lines should be ignored in dependency go.mod files. -env GO111MODULE=on -go list -m all +go list -m -mod=mod all # ... and in replaced dependency go.mod files. cp go.mod go.mod.usesub -go list -m all +go list -m -mod=mod all # ... but not in the main module. cp go.mod.bad go.mod -! go list -m all +! go list -m -mod=mod all stderr 'unknown directive: hello' -- go.mod -- diff --git a/src/cmd/go/testdata/script/mod_load_badzip.txt b/src/cmd/go/testdata/script/mod_load_badzip.txt index c5ba18e9f0..65374d2a6d 100644 --- a/src/cmd/go/testdata/script/mod_load_badzip.txt +++ b/src/cmd/go/testdata/script/mod_load_badzip.txt @@ -5,10 +5,8 @@ env GO111MODULE=on stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' ! grep rsc.io/badzip go.mod -# TODO(golang.org/issue/31730): 'go build' should print the error below if the -# requirement is not present. go mod edit -require rsc.io/badzip@v1.0.0 -! go build rsc.io/badzip +! go build -mod=mod rsc.io/badzip stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' -- go.mod -- diff --git a/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt index 067e209b01..2ca8b3cace 100644 --- a/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt +++ b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt @@ -2,7 +2,7 @@ # the original module and its location, report an error with all three paths. # In particular, the "required as" path should be the original. # Verifies golang.org/issue/38220. -! go list . +! go mod download cmp stderr want -- go.mod -- diff --git a/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt index 319ff85587..9c250e7d1c 100644 --- a/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt +++ b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt @@ -1,7 +1,7 @@ env GO111MODULE=on -! go list use.go -stderr 'example.com/missingpkg/deprecated: package provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta' +! go list -mod=mod -deps use.go +stderr '^use.go:4:2: package example.com/missingpkg/deprecated provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta$' -- go.mod -- module m diff --git a/src/cmd/go/testdata/script/mod_modinfo.txt b/src/cmd/go/testdata/script/mod_modinfo.txt index fb31f9e43b..8d77e224a5 100644 --- a/src/cmd/go/testdata/script/mod_modinfo.txt +++ b/src/cmd/go/testdata/script/mod_modinfo.txt @@ -6,6 +6,7 @@ env GO111MODULE=on cd x go mod edit -require=rsc.io/quote@v1.5.2 go mod edit -replace=rsc.io/quote@v1.5.2=rsc.io/quote@v1.0.0 +go mod tidy # populate go.sum # Build a binary and ensure that it can output its own debug info. # The debug info should be accessible before main starts (golang.org/issue/29628). @@ -68,7 +69,6 @@ package main import ( "bytes" "encoding/hex" - "io/ioutil" "log" "os" @@ -76,7 +76,7 @@ import ( ) func main() { - b, err := ioutil.ReadFile(os.Args[0]) + b, err := os.ReadFile(os.Args[0]) if err != nil { log.Fatal(err) } diff --git a/src/cmd/go/testdata/script/mod_multirepo.txt b/src/cmd/go/testdata/script/mod_multirepo.txt index 7f977e80f6..0f335a11f0 100644 --- a/src/cmd/go/testdata/script/mod_multirepo.txt +++ b/src/cmd/go/testdata/script/mod_multirepo.txt @@ -7,6 +7,7 @@ go list -deps -f {{.Dir}} # v2 import should use a downloaded module # both without an explicit go.mod entry ... cp tmp/use_v2.go x.go +go get -d . go list -deps -f {{.Dir}} stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' diff --git a/src/cmd/go/testdata/script/mod_notall.txt b/src/cmd/go/testdata/script/mod_notall.txt index 72a02485a4..1657c8d2d0 100644 --- a/src/cmd/go/testdata/script/mod_notall.txt +++ b/src/cmd/go/testdata/script/mod_notall.txt @@ -5,6 +5,7 @@ # module, but not should not include test dependencies of packages imported only # by other root patterns. +env GOFLAGS=-mod=mod cp go.mod go.mod.orig go list -deps all x/otherroot @@ -18,7 +19,7 @@ stdout '^x/otherdep$' ! stdout '^x/fromotherroottest$' ! stdout '^y/fromotherdeptest$' -# TODO(#40799): cmp go.mod go.mod.orig +cmp go.mod go.mod.orig # With -deps -test, test dependencies of other roots should be included, # but test dependencies of non-roots should not. @@ -33,7 +34,7 @@ stdout '^x/otherdep$' stdout '^x/fromotherroottest$' ! stdout '^y/fromotherdeptest$' -# TODO(#40799): cmp go.mod go.mod.orig +cmp go.mod go.mod.orig -- m.go -- package m diff --git a/src/cmd/go/testdata/script/mod_off.txt b/src/cmd/go/testdata/script/mod_off.txt index cada6deb1d..a73a58d4d0 100644 --- a/src/cmd/go/testdata/script/mod_off.txt +++ b/src/cmd/go/testdata/script/mod_off.txt @@ -4,7 +4,7 @@ env GO111MODULE=off # GO111MODULE=off when outside of GOPATH will fatal # with an error message, even with some source code in the directory and a go.mod. ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod graph stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod verify @@ -16,7 +16,7 @@ stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' mkdir z cd z ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod graph stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod verify diff --git a/src/cmd/go/testdata/script/mod_off_init.txt b/src/cmd/go/testdata/script/mod_off_init.txt index 1339c8aef9..2aec0b3ed5 100644 --- a/src/cmd/go/testdata/script/mod_off_init.txt +++ b/src/cmd/go/testdata/script/mod_off_init.txt @@ -2,4 +2,4 @@ # ignored anyway due to GO111MODULE=off. env GO111MODULE=off ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt index 03ef576168..28379ab40d 100644 --- a/src/cmd/go/testdata/script/mod_outside.txt +++ b/src/cmd/go/testdata/script/mod_outside.txt @@ -39,6 +39,11 @@ stdout '^fmt$' go list ./needmod/needmod.go stdout 'command-line-arguments' +# 'go list' on a package from a module should fail. +! go list example.com/printversion +stderr '^no required module provides package example.com/printversion: working directory is not part of a module$' + + # 'go list -m' with an explicit version should resolve that version. go list -m example.com/version@latest stdout 'example.com/version v1.1.0' @@ -69,10 +74,9 @@ go clean -n ! stdout . ! stderr . -# 'go mod graph' should not display anything, since there are no active modules. -go mod graph -! stdout . -! stderr . +# 'go mod graph' should fail, since there's no module graph. +! go mod graph +stderr 'cannot find main module' # 'go mod why' should fail, since there is no main module to depend on anything. ! go mod why -m example.com/version @@ -126,12 +130,12 @@ stderr 'cannot find main module' # 'go get -u all' upgrades the transitive import graph of the main module, # which is empty. ! go get -u all -stderr 'go get all: cannot match "all": working directory is not part of a module' +stderr 'go get: cannot match "all": working directory is not part of a module' # 'go get' should check the proposed module graph for consistency, # even though we won't write it anywhere. ! go get -d example.com/printversion@v1.0.0 example.com/version@none -stderr 'inconsistent versions' +stderr '^go get: example.com/printversion@v1.0.0 requires example.com/version@v1.0.0, not example.com/version@none$' # 'go get -d' should download and extract the source code needed to build the requested version. rm -r $GOPATH/pkg/mod/example.com @@ -152,7 +156,7 @@ stderr 'cannot find main module' # 'go build' of source files should fail if they import anything outside std. ! go build -n ./needmod/needmod.go -stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module$' # 'go build' of source files should succeed if they do not import anything outside std. go build -n -o ignore ./stdonly/stdonly.go @@ -175,20 +179,22 @@ go doc fmt # 'go doc' should fail for a package path outside a module. ! go doc example.com/version -stderr 'doc: cannot find module providing package example.com/version: working directory is not part of a module' +stderr 'doc: no required module provides package example.com/version: working directory is not part of a module' -# 'go install' with a version should fail due to syntax. -! go install example.com/printversion@v1.0.0 -stderr 'can only use path@version syntax with' +# 'go install' with a version should succeed if all constraints are met. +# See mod_install_pkg_version. +rm $GOPATH/bin +go install example.com/printversion@v0.1.0 +exists $GOPATH/bin/printversion$GOEXE # 'go install' should fail if a package argument must be resolved to a module. ! go install example.com/printversion -stderr 'cannot find module providing package example.com/printversion: working directory is not part of a module' +stderr 'no required module provides package example.com/printversion: working directory is not part of a module' # 'go install' should fail if a source file imports a package that must be # resolved to a module. ! go install ./needmod/needmod.go -stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' +stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module' # 'go run' with a verison should fail due to syntax. @@ -197,12 +203,12 @@ stderr 'can only use path@version syntax with' # 'go run' should fail if a package argument must be resolved to a module. ! go run example.com/printversion -stderr 'cannot find module providing package example.com/printversion: working directory is not part of a module' +stderr '^no required module provides package example.com/printversion: working directory is not part of a module$' # 'go run' should fail if a source file imports a package that must be # resolved to a module. ! go run ./needmod/needmod.go -stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module$' # 'go fmt' should be able to format files outside of a module. @@ -220,7 +226,7 @@ stdout 'main is example.com/printversion v0.1.0' stdout 'using example.com/version v1.1.0' # 'go get' of a versioned binary should build and install the latest version -# using its minimal module requirements, ignoring replacements and exclusions. +# using its minimal required modules, ignoring replacements and exclusions. go get example.com/printversion exec ../bin/printversion stdout 'path is example.com/printversion' diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt new file mode 100644 index 0000000000..92e79c725a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_overlay.txt @@ -0,0 +1,254 @@ +# Test overlays that affect go.mod files + +# The go.mod file can exist only in the overlay. +cd $WORK/gopath/src/no-go-mod +go list -overlay overlay.json . +stdout example.com/simple + +# Check content of overlaid go.mod is used. +cd $WORK/gopath/src/overlay-go-mod +go list -overlay overlay.json . +stdout use.this/module/name + +# Check content of overlaid go.mod in a replacement module is used. +# The go.mod in the replacement module is missing a requirement +# that the overlay has, so it will fail to list without the overlay. +cd $WORK/gopath/src/overlay-replaced-go-mod +! go list -deps . +go list -deps -overlay overlay.json . + +# Overlaid go.mod is not rewritten by 'go get'. +cd $WORK/gopath/src/get-doesnt-add-dep +cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod +! go get -d -overlay overlay.json . +stderr 'overlaid files can''t be opened for write' +cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod + +# Content of overlaid go.sum is used. +# The go.sum in the module directory has garbage values for its +# hashes, but the overlaid file has the correct values. If +# the correct go.sum is used with the overlay, 'go get .' should +# not report a security error. +cd $WORK/gopath/src/overlay-sum-used +! go get -d . +stderr 'SECURITY ERROR' +! go mod verify +stderr 'SECURITY ERROR' +go get -d -overlay overlay.json . +go mod verify -overlay overlay.json +# Overlaid go.sum is not rewritten. +# Copy an incomplete file to the overlay file, and expect an error +# attempting to update the file +cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go get -d -overlay overlay.json . +stderr 'overlaid files can''t be opened for write' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go mod tidy -overlay overlay.json +stderr 'overlaid files can''t be opened for write' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums + +# -overlay works with -modfile. +# There's an empty go.mod file in the directory, and the file alternate.mod is +# overlaid to the true go.mod file, so the -modfile flag and the overlay +# mechanism need to work together to determine the name of the module. +cd $WORK/gopath/src/overlay-and-dash-modfile +go list -modfile=alternate.mod -overlay overlay.json . +stdout 'found.the/module' +# Even with -modfile, overlaid files can't be opened for write. +! go get -modfile=alternate.mod -overlay overlay.json -d rsc.io/quote +stderr 'overlaid files can''t be opened for write' + +# Carving out a module by adding an overlaid go.mod file +cd $WORK/gopath/src/carve +go list ./... # without an overlay, hasmod is carved out and nomod isn't +stdout carve/nomod +! stdout carve/hasmod +go list -overlay overlay_carve_module.json ./... # The overlay carves out nomod, leaving nothing +! stdout . +stderr 'matched no packages' +go list -overlay overlay_uncarve_module.json ./... # The overlay uncarves out hasmod +stdout carve/nomod +stdout carve/hasmod + +# Carving out a module by adding an overlaid go.mod file and using +# -modfile to write to that file. +cd $WORK/gopath/src/carve2/nomod +go list -overlay overlay.json all +! stdout ^carve2$ +stdout ^carve2/nomod$ +# Editing go.mod file fails because overlay is read only +! go get -overlay overlay.json -d rsc.io/quote +stderr 'overlaid files can''t be opened for write' +! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod +# Editing go.mod file succeeds because we use -modfile to redirect to same file +go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod -d rsc.io/quote +grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod + +-- no-go-mod/file.go -- +package simple +-- no-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/simple_go_mod" + } +} +-- $WORK/overlay/simple_go_mod -- +module example.com/simple +-- overlay-go-mod/file.go -- +package name +-- overlay-go-mod/go.mod -- +module dont.use/this/module/name +-- overlay-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/use_this_go_mod" + } +} +-- $WORK/overlay/use_this_go_mod -- +module use.this/module/name +-- overlay-replaced-go-mod/go.mod -- +module m + +go 1.15 + +require replaced/mod v1.0.0 +replace replaced/mod v1.0.0 => ../replaced-mod +replace dep/mod v1.0.0 => ../dep-mod +-- overlay-replaced-go-mod/source.go -- +package m + +import "replaced/mod/foo" + +func main() { + foo.f() +} +-- overlay-replaced-go-mod/overlay.json -- +{ + "Replace": { + "../replaced-mod/go.mod": "../../../overlay/replacement_module_go_mod" + } +} +-- replaced-mod/go.mod -- +module replaced/mod +-- replaced-mod/foo/foo.go -- +package foo + +import "dep/mod/foo" + +func f() { foo.g() } +-- dep-mod/go.mod -- +invalid +-- dep-mod/foo/foo.go -- +package foo + +func g() { fmt.Println("hello") } +-- $WORK/overlay/replacement_module_go_mod -- +module replaced/mod + +require dep/mod v1.0.0 + +-- get-doesnt-add-dep/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/get_doesnt_add_dep_go_mod" + } +} +-- get-doesnt-add-dep/p.go -- +package p + +import "dependency/mod" + +func f() { mod.G() } +-- get-doesnt-add-dep-dependency/go.mod -- +module dependency/mod +-- get-doesnt-add-dep-dependency/mod.go -- +package mod + +func G() {} +-- $WORK/overlay/get_doesnt_add_dep_go_mod -- +module get.doesnt/add/dep + +replace dependency/mod v1.0.0 => ../get-doesnt-add-dep-dependency +-- overlay-sum-used/go.mod -- +module overlay.sum/used + +require rsc.io/quote v1.5.0 +-- overlay-sum-used/p.go -- +package p + +import "rsc.io/quote" + +func f() string { + return quote.Hello() +} +-- overlay-sum-used/incomplete-sum-file -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +-- overlay-sum-used/overlay.json -- +{ + "Replace": { + "go.sum": "../../../overlay/overlay-sum-used-correct-sums" + } +} +-- overlay-sum-used/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:garbage+hash +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:garbage+hash +rsc.io/quote v1.5.0 h1:garbage+hash +rsc.io/quote v1.5.0/go.mod h1:garbage+hash +rsc.io/sampler v1.3.0 h1:garbage+hash +rsc.io/sampler v1.3.0/go.mod h1:garbage+hash +-- $WORK/overlay/overlay-sum-used-correct-sums -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/quote v1.5.0/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- overlay-and-dash-modfile/p.go -- +package module +-- overlay-and-dash-modfile/go.mod -- +-- overlay-and-dash-modfile/overlay.json -- +{ + "Replace": { + "alternate.mod": "../../../overlay/overlay-and-dash-modfile-alternate-mod" + } +} +-- $WORK/overlay/overlay-and-dash-modfile-alternate-mod -- +module found.the/module +-- carve/go.mod -- +module carve +-- carve/overlay_carve_module.json -- +{ + "Replace": { + "nomod/go.mod": "../../../overlay/carve-nomod-go-mod" + } +} +-- carve/overlay_uncarve_module.json -- +{ + "Replace": { + "hasmod/go.mod": "" + } +} +-- carve/hasmod/a.go -- +package hasmod +-- carve/hasmod/go.mod -- +module carve/hasmod +-- carve/nomod/b.go -- +package nomod +-- $WORK/overlay/carve-nomod-go-mod -- +module carve/nomod +-- carve2/go.mod -- +module carve2 +-- carve2/p.go -- +package p +-- carve2/nomod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../../overlay/carve2-nomod-go.mod" + } +} +-- carve2/nomod/b.go -- +package nomod +-- $WORK/overlay/carve2-nomod-go.mod -- +module carve2/nomod diff --git a/src/cmd/go/testdata/script/mod_permissions.txt b/src/cmd/go/testdata/script/mod_permissions.txt index 11fb4754f8..2d32dcd10f 100644 --- a/src/cmd/go/testdata/script/mod_permissions.txt +++ b/src/cmd/go/testdata/script/mod_permissions.txt @@ -12,7 +12,7 @@ chmod 0640 go.mod chmod 0604 go.sum go mod edit -module=golang.org/issue/34634 -go build . +go get -d cmp go.mod go.mod.want cmp go.sum go.sum.want diff --git a/src/cmd/go/testdata/script/mod_proxy_list.txt b/src/cmd/go/testdata/script/mod_proxy_list.txt index 849cf2c476..89129f4fe2 100644 --- a/src/cmd/go/testdata/script/mod_proxy_list.txt +++ b/src/cmd/go/testdata/script/mod_proxy_list.txt @@ -3,34 +3,34 @@ env proxy=$GOPROXY # Proxy that can't serve should fail. env GOPROXY=$proxy/404 -! go get rsc.io/quote@v1.0.0 +! go get -d rsc.io/quote@v1.0.0 stderr '404 Not Found' # get should walk down the proxy list past 404 and 410 responses. env GOPROXY=$proxy/404,$proxy/410,$proxy -go get rsc.io/quote@v1.1.0 +go get -d rsc.io/quote@v1.1.0 # get should not walk past other 4xx errors if proxies are separated with ','. env GOPROXY=$proxy/403,$proxy -! go get rsc.io/quote@v1.2.0 +! go get -d rsc.io/quote@v1.2.0 stderr 'reading.*/403/rsc.io/.*: 403 Forbidden' # get should not walk past non-4xx errors if proxies are separated with ','. env GOPROXY=$proxy/500,$proxy -! go get rsc.io/quote@v1.3.0 +! go get -d rsc.io/quote@v1.3.0 stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error' # get should walk past other 4xx errors if proxies are separated with '|'. env GOPROXY=$proxy/403|https://0.0.0.0|$proxy -go get rsc.io/quote@v1.2.0 +go get -d rsc.io/quote@v1.2.0 # get should walk past non-4xx errors if proxies are separated with '|'. env GOPROXY=$proxy/500|https://0.0.0.0|$proxy -go get rsc.io/quote@v1.3.0 +go get -d rsc.io/quote@v1.3.0 # get should return the final error if that's all we have. env GOPROXY=$proxy/404,$proxy/410 -! go get rsc.io/quote@v1.4.0 +! go get -d rsc.io/quote@v1.4.0 stderr 'reading.*/410/rsc.io/.*: 410 Gone' -- go.mod -- diff --git a/src/cmd/go/testdata/script/mod_query.txt b/src/cmd/go/testdata/script/mod_query.txt index e87ca302f0..e10185709d 100644 --- a/src/cmd/go/testdata/script/mod_query.txt +++ b/src/cmd/go/testdata/script/mod_query.txt @@ -1,5 +1,10 @@ env GO111MODULE=on +# Populate go.sum. +# TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands +# below depend on the build list. +go mod download + go list -m -versions rsc.io/quote stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' @@ -30,3 +35,8 @@ stdout 'no matching versions for query ">v1.5.3"' -- go.mod -- module x require rsc.io/quote v1.0.0 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_query_empty.txt b/src/cmd/go/testdata/script/mod_query_empty.txt index b3ea3e3de0..f8b6e3e97e 100644 --- a/src/cmd/go/testdata/script/mod_query_empty.txt +++ b/src/cmd/go/testdata/script/mod_query_empty.txt @@ -8,7 +8,7 @@ go mod download example.com/join@v1.1.0 env GOPROXY=file:///$WORK/badproxy cp go.mod.orig go.mod ! go get -d example.com/join/subpkg -stderr 'go get example.com/join/subpkg: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' +stderr 'go get: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' # If @v/list is empty, the 'go' command should still try to resolve # other module paths. @@ -40,7 +40,7 @@ env GOPROXY=file:///$WORK/gatekeeper chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest cp go.mod.orig go.mod ! go get -d example.com/join/subpkg -stderr 'go get example.com/join/subpkg: module example.com/join/subpkg: (invalid response from proxy ".+": invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' +stderr 'go get: module example.com/join/subpkg: (invalid response from proxy ".+": invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' -- go.mod.orig -- module example.com/othermodule diff --git a/src/cmd/go/testdata/script/mod_query_exclude.txt b/src/cmd/go/testdata/script/mod_query_exclude.txt index 742c6f17e3..b001969411 100644 --- a/src/cmd/go/testdata/script/mod_query_exclude.txt +++ b/src/cmd/go/testdata/script/mod_query_exclude.txt @@ -19,7 +19,7 @@ stdout '^rsc.io/quote v1.5.1$' # get excluded version cp go.exclude.mod go.exclude.mod.orig ! go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.0 -stderr '^go get rsc.io/quote@v1.5.0: rsc.io/quote@v1.5.0: excluded by go.mod$' +stderr '^go get: rsc.io/quote@v1.5.0: excluded by go.mod$' # get non-excluded version cp go.exclude.mod.orig go.exclude.mod diff --git a/src/cmd/go/testdata/script/mod_query_main.txt b/src/cmd/go/testdata/script/mod_query_main.txt new file mode 100644 index 0000000000..39e5841a9c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_main.txt @@ -0,0 +1,43 @@ +# 'go mod download' can download specific versions of the main module. +go mod download rsc.io/quote@5d9f230b +go mod download rsc.io/quote@v1.5.2 +go mod download rsc.io/quote@latest + +# 'go mod download' will not download @upgrade or @patch, since they always +# resolve to the main module. +go mod download rsc.io/quote@upgrade +stderr '^go mod download: skipping argument rsc.io/quote@upgrade that resolves to the main module$' +go mod download rsc.io/quote@patch +stderr '^go mod download: skipping argument rsc.io/quote@patch that resolves to the main module$' + +# 'go list -m' can show a version of the main module. +go list -m rsc.io/quote@5d9f230b +stdout '^rsc.io/quote v0.0.0-20180710144737-5d9f230bcfba$' +go list -m rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote v1.5.2$' +go list -m rsc.io/quote@latest +stdout '^rsc.io/quote v1.5.2$' + +# 'go list -m -versions' shows available versions. +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote.*v1.5.2' + +# 'go list -m' resolves @upgrade and @patch to the main module. +go list -m rsc.io/quote@upgrade +stdout '^rsc.io/quote$' +go list -m rsc.io/quote@patch +stdout '^rsc.io/quote$' + +# 'go get' will not attempt to upgrade the main module to any specific version. +# See also: mod_get_main.txt. +! go get rsc.io/quote@5d9f230b +stderr '^go get: can''t request version "5d9f230b" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@v1.5.2 +stderr '^go get: can''t request version "v1.5.2" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@latest +stderr '^go get: can''t request version "latest" of the main module \(rsc.io/quote\)$' + +-- go.mod -- +module rsc.io/quote + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt index ac581264f1..ca8cd6e068 100644 --- a/src/cmd/go/testdata/script/mod_readonly.txt +++ b/src/cmd/go/testdata/script/mod_readonly.txt @@ -10,17 +10,16 @@ stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lo ! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one. cmp go.mod go.mod.empty -# -mod=readonly should be set implicitly if the go.mod file is read-only -chmod 0400 go.mod +# -mod=readonly should be set by default. env GOFLAGS= ! go list all -stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$' +stderr '^x.go:2:8: no required module provides package rsc\.io/quote; try ''go mod tidy'' to add it$' +cmp go.mod go.mod.empty -chmod 0600 go.mod env GOFLAGS=-mod=readonly # update go.mod - go get allowed -go get rsc.io/quote +go get -d rsc.io/quote grep rsc.io/quote go.mod # update go.mod - go mod tidy allowed @@ -42,24 +41,50 @@ go list -m all # -mod=readonly should reject inconsistent go.mod files # (ones that would be rewritten). -go mod edit -require rsc.io/sampler@v1.2.0 +go get -d rsc.io/sampler@v1.2.0 +go mod edit -require rsc.io/quote@v1.5.2 cp go.mod go.mod.inconsistent ! go list stderr 'go: updates to go.mod needed, disabled by -mod=readonly' cmp go.mod go.mod.inconsistent +# We get a different message when -mod=readonly is used by default. +env GOFLAGS= +! go list +stderr '^go: updates to go.mod needed; try ''go mod tidy'' first$' + # However, it should not reject files missing a 'go' directive, # since that was not always required. cp go.mod.nogo go.mod go list all +cmp go.mod go.mod.nogo # Nor should it reject files with redundant (not incorrect) # requirements. cp go.mod.redundant go.mod go list all +cmp go.mod go.mod.redundant cp go.mod.indirect go.mod go list all +cmp go.mod go.mod.indirect + + +# If we identify a missing package as a dependency of some other package in the +# main module, we should suggest 'go mod tidy' instead of resolving it. + +cp go.mod.untidy go.mod +! go list all +stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$' + +! go list -deps . +stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$' + +# However, if we didn't see an import from the main module, we should suggest +# 'go get -d' instead, because we don't know whether 'go mod tidy' would add it. +! go list rsc.io/quote +stderr '^no required module provides package rsc.io/quote; try ''go get -d rsc.io/quote'' to add it$' + -- go.mod -- module m @@ -96,3 +121,11 @@ require ( rsc.io/sampler v1.3.0 // indirect rsc.io/testonly v1.0.0 // indirect ) +-- go.mod.untidy -- +module m + +go 1.20 + +require ( + rsc.io/sampler v1.3.0 // indirect +) diff --git a/src/cmd/go/testdata/script/mod_replace.txt b/src/cmd/go/testdata/script/mod_replace.txt index c21f172002..dc9667f1d0 100644 --- a/src/cmd/go/testdata/script/mod_replace.txt +++ b/src/cmd/go/testdata/script/mod_replace.txt @@ -4,7 +4,7 @@ env GO111MODULE=on cp go.mod go.mod.orig # Make sure the test builds without replacement. -go build -o a1.exe . +go build -mod=mod -o a1.exe . exec ./a1.exe stdout 'Don''t communicate by sharing memory' @@ -32,7 +32,7 @@ stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/ # Modules that do not (yet) exist upstream can be replaced too. cp go.mod.orig go.mod go mod edit -replace=not-rsc.io/quote/v3@v3.1.0=./local/rsc.io/quote/v3 -go build -o a5.exe ./usenewmodule +go build -mod=mod -o a5.exe ./usenewmodule ! stderr 'finding not-rsc.io/quote/v3' grep 'not-rsc.io/quote/v3 v3.1.0' go.mod exec ./a5.exe diff --git a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt index 674c99cb0c..df752d9716 100644 --- a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt +++ b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt @@ -11,6 +11,7 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOFLAGS=-mod=mod # Replacing gopkg.in/[…].vN with a repository with a root go.mod file # specifying […].vN and a compatible version should succeed, even if diff --git a/src/cmd/go/testdata/script/mod_replace_import.txt b/src/cmd/go/testdata/script/mod_replace_import.txt index 54b1a12448..2add31f71c 100644 --- a/src/cmd/go/testdata/script/mod_replace_import.txt +++ b/src/cmd/go/testdata/script/mod_replace_import.txt @@ -1,12 +1,12 @@ env GO111MODULE=on -# 'go list -mod=readonly' should not add requirements even if they can be -# resolved locally. +# 'go list' should not add requirements even if they can be resolved locally. cp go.mod go.mod.orig -! go list -mod=readonly all +! go list all cmp go.mod go.mod.orig # 'go list' should resolve imports using replacements. +go get -d go list all stdout 'example.com/a/b$' stdout 'example.com/x/v3$' @@ -25,10 +25,11 @@ stdout 'example.com/v v1.12.0 => ./v12' # The go command should print an informative error when the matched # module does not contain a package. +# TODO(#26909): Ideally these errors should include line numbers for the imports within the main module. cd fail -! go list all -stderr '^m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' -stderr '^m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' +! go mod tidy +stderr '^localhost.fail imports\n\tw: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' +stderr '^localhost.fail imports\n\tnonexist: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' -- go.mod -- module example.com/m diff --git a/src/cmd/go/testdata/script/mod_replace_readonly.txt b/src/cmd/go/testdata/script/mod_replace_readonly.txt new file mode 100644 index 0000000000..882c755337 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_readonly.txt @@ -0,0 +1,62 @@ +# Check that with -mod=readonly, when we load a package in a module that is +# replaced but not required, we emit an error with the command to add the +# requirement. +# Verifies golang.org/issue/41416, golang.org/issue/41577. +cp go.mod go.mod.orig + +# Replace all versions of a module without requiring it. +# With -mod=mod, we'd add a requirement for a "zero" pseudo-version, but we +# can't in readonly mode, since its go.mod may alter the build list. +go mod edit -replace rsc.io/quote=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote'' to add it$' +go get -d rsc.io/quote +cmp go.mod go.mod.latest +go list rsc.io/quote +cp go.mod.orig go.mod + +# Same test with a specific version. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote@v1.0.0-doesnotexist'' to add it$' +go get -d rsc.io/quote@v1.0.0-doesnotexist +cmp go.mod go.mod.specific +go list rsc.io/quote +cp go.mod.orig go.mod + +# If there are multiple versions, the highest is suggested. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +go mod edit -replace rsc.io/quote@v1.1.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote@v1.1.0-doesnotexist'' to add it$' + +-- go.mod -- +module m + +go 1.16 +-- go.mod.latest -- +module m + +go 1.16 + +replace rsc.io/quote => ./quote + +require rsc.io/quote v1.5.2 // indirect +-- go.mod.specific -- +module m + +go 1.16 + +replace rsc.io/quote v1.0.0-doesnotexist => ./quote + +require rsc.io/quote v1.0.0-doesnotexist // indirect +-- use.go -- +package use + +import _ "rsc.io/quote" +-- quote/go.mod -- +module rsc.io/quote + +go 1.16 +-- quote/quote.go -- +package quote diff --git a/src/cmd/go/testdata/script/mod_require_exclude.txt b/src/cmd/go/testdata/script/mod_require_exclude.txt index 1a0fc3097b..9156d4ce5d 100644 --- a/src/cmd/go/testdata/script/mod_require_exclude.txt +++ b/src/cmd/go/testdata/script/mod_require_exclude.txt @@ -20,7 +20,7 @@ cmp go.mod go.mod.orig # With the selected version excluded, commands that load only modules should # drop the excluded module. -go list -m all +go list -m -mod=mod all stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' stdout '^x$' ! stdout '^rsc.io/sampler' @@ -30,7 +30,7 @@ cmp go.mod go.moddrop # from the next-highest version. cp go.mod.orig go.mod -go list -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' stdout '^x $' ! stdout '^rsc.io/sampler v1.99.99' @@ -38,13 +38,13 @@ stdout '^rsc.io/sampler v1.3.0' # build with newer version available cp go.mod2 go.mod -go list -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all stderr '^go: dropping requirement on excluded version rsc.io/quote v1\.5\.1$' stdout 'rsc.io/quote v1.5.2' # build with excluded newer version cp go.mod3 go.mod -go list -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all ! stderr '^go: dropping requirement' stdout 'rsc.io/quote v1.5.1' diff --git a/src/cmd/go/testdata/script/mod_retention.txt b/src/cmd/go/testdata/script/mod_retention.txt index 1d83e6c07e..a4441c4b3c 100644 --- a/src/cmd/go/testdata/script/mod_retention.txt +++ b/src/cmd/go/testdata/script/mod_retention.txt @@ -7,7 +7,7 @@ env GO111MODULE=on # Control case: verify that go.mod.tidy is actually tidy. cp go.mod.tidy go.mod -go list all +go list -mod=mod all cmp go.mod go.mod.tidy @@ -35,7 +35,7 @@ cmp go.mod go.mod.tidy # "// indirect" comments should be removed if direct dependencies are seen. # changes. cp go.mod.indirect go.mod -go list all +go list -mod=mod all cmp go.mod go.mod.tidy # "// indirect" comments should be added if appropriate. @@ -63,7 +63,7 @@ cmp go.mod go.mod.tidy # A missing "go" version directive should be added. # However, that should not remove other redundant requirements. cp go.mod.nogo go.mod -go list all +go list -mod=mod all cmpenv go.mod go.mod.currentgo diff --git a/src/cmd/go/testdata/script/mod_retract.txt b/src/cmd/go/testdata/script/mod_retract.txt index 5d21902043..a52e05bc72 100644 --- a/src/cmd/go/testdata/script/mod_retract.txt +++ b/src/cmd/go/testdata/script/mod_retract.txt @@ -1,5 +1,8 @@ cp go.mod go.mod.orig +# Populate go.sum. +go mod download + # 'go list pkg' does not report an error when a retracted version is used. go list -e -f '{{if .Error}}{{.Error}}{{end}}' ./use ! stdout . @@ -17,7 +20,7 @@ exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.0.0-bad.mod # Importing a package from a module with a retracted latest version will # select the latest non-retracted version. -go list ./use_self_prev +go get -d ./use_self_prev go list -m example.com/retract/self/prev stdout '^example.com/retract/self/prev v1.1.0$' exists $GOPATH/pkg/mod/cache/download/example.com/retract/self/prev/@v/v1.9.0.mod diff --git a/src/cmd/go/testdata/script/mod_retract_incompatible.txt b/src/cmd/go/testdata/script/mod_retract_incompatible.txt new file mode 100644 index 0000000000..61538e8024 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_incompatible.txt @@ -0,0 +1,15 @@ +# The current version of a module should not be considered when loading +# retractions. If the current version is +incompatible, we should not prefer +# +incompatible versions when looking for retractions. +# Verifies #42601. + +go mod init m + +# Request a +incompatible version retracted in v1.0.0. +go get -d example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' + +# We should still see a warning if the +incompatible was previously in the +# build list. +go get -d example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' diff --git a/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt new file mode 100644 index 0000000000..eb00e8405c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt @@ -0,0 +1,62 @@ +# When converting a commit to a pseudo-version, don't use a retracted version +# as the base. +# Verifies golang.org/issue/41700. + +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off +go mod init m + +# Control: check that v1.0.0 is the only version and is retracted. +go list -m -versions vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git$' +go list -m -versions -retracted vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.0$' + +# 713affd19d7b is a commit after v1.0.0. Don't use v1.0.0 as the base. +go list -m vcs-test.golang.org/git/retract-pseudo.git@713affd19d7b +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-713affd19d7b$' + +# 64c061ed4371 is the commit v1.0.0 refers to. Don't convert to v1.0.0. +go list -m vcs-test.golang.org/git/retract-pseudo.git@64c061ed4371 +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-64c061ed4371' + +# A retracted version is a valid base. Retraction should not validate existing +# pseudo-versions, nor should it turn invalid pseudo-versions valid. +go get -d vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-713affd19d7b +go list -m vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.1-0.20201009173747-713affd19d7b$' + +! go get -d vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371 +stderr '^go get: vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371: invalid pseudo-version: tag \(v1.0.0\) found on revision 64c061ed4371 is already canonical, so should not be replaced with a pseudo-version derived from that tag$' + +-- retract-pseudo.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail + +rm -rf retract-pseudo +mkdir retract-pseudo +cd retract-pseudo +git init + +# Create the module. +# Retract v1.0.0 and tag v1.0.0 at the same commit. +# The module has no unretracted release versions. +go mod init vcs-test.golang.org/git/retract-pseudo.git +go mod edit -retract v1.0.0 +echo 'package p' >p.go +git add -A +git commit -m 'create module retract-pseudo' +git tag v1.0.0 + +# Commit a trivial change so the default branch does not point to v1.0.0. +git mv p.go q.go +git commit -m 'trivial change' + +zip -r ../retract-pseudo.zip . +gsutil cp ../retract-pseudo.zip gs://vcs-test/git/retract-pseudo.zip diff --git a/src/cmd/go/testdata/script/mod_retract_rationale.txt b/src/cmd/go/testdata/script/mod_retract_rationale.txt index 584c3a3849..4d3a3d67c6 100644 --- a/src/cmd/go/testdata/script/mod_retract_rationale.txt +++ b/src/cmd/go/testdata/script/mod_retract_rationale.txt @@ -1,6 +1,6 @@ # When there is no rationale, 'go get' should print a hard-coded message. go get -d example.com/retract/rationale@v1.0.0-empty -stderr '^go: warning: example.com/retract/rationale@v1.0.0-empty is retracted: retracted by module author$' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-empty: retracted by module author$' # 'go list' should print the same hard-coded message. go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale @@ -9,7 +9,7 @@ stdout '^\[retracted by module author\]$' # When there is a multi-line message, 'go get' should print the first line. go get -d example.com/retract/rationale@v1.0.0-multiline1 -stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline1 is retracted: short description$' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline1: retracted by module author: short description$' ! stderr 'detail' # 'go list' should show the full message. @@ -19,7 +19,7 @@ cmp stdout multiline # 'go get' output should be the same whether the retraction appears at top-level # or in a block. go get -d example.com/retract/rationale@v1.0.0-multiline2 -stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline2 is retracted: short description$' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline2: retracted by module author: short description$' ! stderr 'detail' # Same for 'go list'. @@ -29,7 +29,7 @@ cmp stdout multiline # 'go get' should omit long messages. go get -d example.com/retract/rationale@v1.0.0-long -stderr '^go: warning: example.com/retract/rationale@v1.0.0-long is retracted: \(rationale omitted: too long\)' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-long: retracted by module author: \(rationale omitted: too long\)' # 'go list' should show the full message. go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale @@ -38,7 +38,7 @@ stdout '^\[lo{500}ng\]$' # 'go get' should omit messages with unprintable characters. go get -d example.com/retract/rationale@v1.0.0-unprintable -stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable is retracted: \(rationale omitted: contains non-printable characters\)' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable: retracted by module author: \(rationale omitted: contains non-printable characters\)' # 'go list' should show the full message. go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale @@ -62,9 +62,9 @@ stdout '^single version,degenerate range,$' # 'go get' will only report the first retraction to avoid being too verbose. go get -d example.com/retract/rationale@v1.0.0-order -stderr '^go: warning: example.com/retract/rationale@v1.0.0-order is retracted: degenerate range$' +stderr '^go: warning: example.com/retract/rationale@v1.0.0-order: retracted by module author: degenerate range$' go get -d example.com/retract/rationale@v1.0.1-order -stderr '^go: warning: example.com/retract/rationale@v1.0.1-order is retracted: single version$' +stderr '^go: warning: example.com/retract/rationale@v1.0.1-order: retracted by module author: single version$' -- go.mod -- module m diff --git a/src/cmd/go/testdata/script/mod_retract_rename.txt b/src/cmd/go/testdata/script/mod_retract_rename.txt new file mode 100644 index 0000000000..f54742c523 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_rename.txt @@ -0,0 +1,28 @@ +# Populate go.sum. +go get -d + +# 'go list -m -retracted' should load retractions, even if the version +# containing retractions has a different module path. +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go list -m -u' should load retractions, too. +go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go get' should warn about the retracted version. +go get -d +stderr '^go: warning: example.com/retract/rename@v1.0.0-bad: retracted by module author: bad$' + +# We can't upgrade, since this latest version has a different module path. +! go get -d example.com/retract/rename +stderr 'module declares its path as: example.com/retract/newname' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/rename v1.0.0-bad +-- use.go -- +package use + +import _ "example.com/retract/rename" diff --git a/src/cmd/go/testdata/script/mod_retract_replace.txt b/src/cmd/go/testdata/script/mod_retract_replace.txt index b710485fa7..770aea41a5 100644 --- a/src/cmd/go/testdata/script/mod_retract_replace.txt +++ b/src/cmd/go/testdata/script/mod_retract_replace.txt @@ -1,9 +1,12 @@ # If the latest unretracted version of a module is replaced, 'go list' should # obtain retractions from the replacement. +# Populate go.sum. +go get -d + # The latest version, v1.9.0, is not available on the proxy. ! go list -m -retracted example.com/retract/missingmod -stderr '^go list -m: loading module retractions: example.com/retract/missingmod@v1.9.0:.*404 Not Found$' +stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$' # If we replace that version, we should see retractions. go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0 @@ -24,9 +27,9 @@ go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract go list -m -retracted -f '{{if .Replace}}replaced{{end}}' example.com/retract ! stdout . go mod edit -replace example.com/retract@v1.0.0-good=example.com/retract@v1.0.0-bad -go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract +go list -m -mod=mod -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract stdout '^bad$' -go list -m -retracted -f '{{with .Replace}}{{range .Retracted}}{{.}}{{end}}{{end}}' example.com/retract +go list -m -mod=mod -retracted -f '{{with .Replace}}{{range .Retracted}}{{.}}{{end}}{{end}}' example.com/retract stdout '^bad$' -- go.mod -- @@ -38,6 +41,13 @@ require ( example.com/retract v1.0.0-good example.com/retract/missingmod v1.0.0 ) +-- use.go -- +package use + +import ( + _ "example.com/retract" + _ "example.com/retract/missingmod" +) -- missingmod-v1.0.0/go.mod -- module example.com/retract/missingmod diff --git a/src/cmd/go/testdata/script/mod_std_vendor.txt b/src/cmd/go/testdata/script/mod_std_vendor.txt index 5986cff594..fb954d74ed 100644 --- a/src/cmd/go/testdata/script/mod_std_vendor.txt +++ b/src/cmd/go/testdata/script/mod_std_vendor.txt @@ -37,12 +37,10 @@ stderr 'use of vendored package' # When run within the 'std' module, 'go list -test' should report vendored # transitive dependencies at their original module paths. -# TODO(golang.org/issue/30241): Make that work. -# Today, they're standard packages as long as they exist. cd $GOROOT/src go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' net/http -stdout ^vendor/golang.org/x/net/http2/hpack # TODO: remove vendor/ prefix -! stdout ^golang.org/x/net/http2/hpack +stdout ^golang.org/x/net/http2/hpack +! stdout ^vendor/golang.org/x/net/http2/hpack -- go.mod -- module m diff --git a/src/cmd/go/testdata/script/mod_sum_ambiguous.txt b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt new file mode 100644 index 0000000000..999257c419 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt @@ -0,0 +1,48 @@ +# Confirm our build list. +cp go.sum.buildlist-only go.sum +go list -m all +stdout '^example.com/ambiguous/a v1.0.0$' +stdout '^example.com/ambiguous/a/b v0.0.0-empty$' + +# If two modules could provide a package, but only one does, +# 'go mod tidy' should retain sums for both zips. +go mod tidy +grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum +grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum + +# If two modules could provide a package, and we're missing a sum for one, +# we should see a missing sum error, even if we have a sum for a module that +# provides the package. +cp go.sum.a-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module; try ''go mod tidy'' to add it$' + +cp go.sum.b-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b; try ''go mod tidy'' to add it$' + +-- go.mod -- +module m + +go 1.15 + +require example.com/ambiguous/a v1.0.0 +-- go.sum.buildlist-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.a-only -- +example.com/ambiguous/a v1.0.0 h1:pGZhTXy6+titE2rNfwHwJykSjXDR4plO52PfZrBM0T8= +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.b-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty h1:xS29ReXXuhjT7jc79mo91h/PevaZ2oS9PciF1DucXtg= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- use.go -- +package use + +import _ "example.com/ambiguous/a/b" diff --git a/src/cmd/go/testdata/script/mod_sum_lookup.txt b/src/cmd/go/testdata/script/mod_sum_lookup.txt index ed80a44984..e021921380 100644 --- a/src/cmd/go/testdata/script/mod_sum_lookup.txt +++ b/src/cmd/go/testdata/script/mod_sum_lookup.txt @@ -1,13 +1,14 @@ # When we attempt to resolve an import that doesn't exist, we should not save # hashes for downloaded modules. # Verifies golang.org/issue/36260. -go list -e -tags=ignore ./noexist +# TODO(golang.org/issue/26603): use 'go mod tidy -e' when implemented. +go list -e -mod=mod -tags=ignore ./noexist ! exists go.sum # When an import is resolved successfully, we should only save hashes for # the module that provides the package, not for other modules looked up. # Verifies golang.org/issue/31580. -go list ./exist +go get -d ./exist grep '^example.com/join v1.1.0 h1:' go.sum ! grep '^example.com/join/subpkg' go.sum cp go.sum go.list.sum diff --git a/src/cmd/go/testdata/script/mod_sum_readonly.txt b/src/cmd/go/testdata/script/mod_sum_readonly.txt new file mode 100644 index 0000000000..4d6e8aae6a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_readonly.txt @@ -0,0 +1,87 @@ +# Test that go.sum does not get updated when -mod=readonly flag is set +env GO111MODULE=on + +# When a sum is needed to load the build list, we get an error for the +# specific module. The .mod file is not downloaded, and go.sum is not written. +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +! exists go.sum + +# If go.sum exists but contains hashes from an algorithm we don't know about, +# we should see the same error. +cp go.sum.h2only go.sum +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +cmp go.sum go.sum.h2only +rm go.sum + +# If we replace a module, we should see a missing sum error for the replacement. +cp go.mod go.mod.orig +go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1 +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod +! exists go.sum +cp go.mod.orig go.mod + +# Control: when sums are present, loading the build list downloads .mod files. +cp go.sum.buildlistonly go.sum +go list -m all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod + + +# When a sum is needed to load a .mod file for a package outside the build list, +# we get a generic missing import error. +! go list example.com/doesnotexist +stderr '^no required module provides package example.com/doesnotexist; try ''go get -d example.com/doesnotexist'' to add it$' + +# When a sum is needed to load a .zip file, we get a more specific error. +# The .zip file is not downloaded. +! go list rsc.io/quote +stderr '^missing go.sum entry for module providing package rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# The error is attached to the package from the missing module. We can load +# a package that imports it without that error. +go list -e -deps -f '{{.ImportPath}}{{with .Error}} {{.Err}}{{end}}' . +stdout '^m$' +stdout '^rsc.io/quote missing go.sum entry for module providing package rsc.io/quote; try ''go mod tidy'' to add it$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# go.sum should not have been written. +cmp go.sum go.sum.buildlistonly + +# Control: when sums are present, 'go list' downloads .zip files. +cp go.sum.tidy go.sum +go list . +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +-- go.mod -- +module m + +go 1.15 + +require rsc.io/quote v1.5.2 +-- use.go -- +package use + +import _ "rsc.io/quote" +-- go.sum.h2only -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h2:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h2:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h2:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.buildlistonly -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.tidy -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= diff --git a/src/cmd/go/testdata/script/mod_sumdb.txt b/src/cmd/go/testdata/script/mod_sumdb.txt index 68bbd9c274..9a688e1461 100644 --- a/src/cmd/go/testdata/script/mod_sumdb.txt +++ b/src/cmd/go/testdata/script/mod_sumdb.txt @@ -9,7 +9,7 @@ env dbname=localhost.localdev/sumdb cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get -d rsc.io/quote -stderr 'go get rsc.io/quote: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' +stderr 'go get: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' stderr 'downloaded: h1:3fEy' stderr 'localhost.localdev/sumdb: h1:wrong' stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.' @@ -17,7 +17,7 @@ stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the che ! go get -d golang.org/x/text go mod edit -require rsc.io/quote@v1.5.2 -! go list all +! go mod tidy stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch' stderr 'SECURITY ERROR\n' diff --git a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt index 6108c0a5d3..22fcbf3de8 100644 --- a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt +++ b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt @@ -13,7 +13,7 @@ env GOPATH=$WORK/gopath1 [windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org [!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org ! go get -d golang.org/x/text@v0.3.2 -stderr '^go get golang.org/x/text@v0.3.2: golang.org/x/text@v0.3.2: verifying module: golang.org/x/text@v0.3.2: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/text@v0.3.2: (no such file or directory|.*cannot find the path specified.*)' +stderr '^go get: golang.org/x/text@v0.3.2: verifying module: golang.org/x/text@v0.3.2: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/text@v0.3.2: (no such file or directory|.*cannot find the path specified.*)' # If the proxy does not claim to support the database, # checksum verification should fall through to the next proxy, diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt index d9fb63acb0..cc0b0da474 100644 --- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt +++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -34,7 +34,7 @@ cmp go.sum saved.sum # Should use the checksum database to validate new go.sum lines, # but not need to fetch any new data from the proxy. rm go.sum -go list -x rsc.io/quote +go list -mod=mod -x rsc.io/quote ! stderr github ! stderr proxy.golang.org/rsc.io/quote stderr sum.golang.org/tile @@ -45,7 +45,7 @@ cmp go.sum saved.sum env TESTGOPROXY404=1 go clean -modcache rm go.sum -go list -x rsc.io/quote +go list -mod=mod -x rsc.io/quote stderr 'proxy.golang.org.*404 testing' stderr github.com/rsc cmp go.sum saved.sum diff --git a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt index 7bbc3f9e19..70b8e3fc44 100644 --- a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt +++ b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -17,14 +17,12 @@ rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum # direct access fails (because localhost.localdev does not exist) -# The text of the error message is hard to predict because some DNS servers -# will resolve unknown domains like localhost.localdev to a real IP -# to serve ads. +# web.get is providing the error message - there's no actual network access. cp go.mod.orig go.mod env GOSUMDB=$sumdb env GOPROXY=direct ! go get -d rsc.io/fortune@v1.0.0 -stderr 'verifying.*localhost.localdev' +stderr 'verifying module: rsc.io/fortune@v1.0.0: .*: no such host localhost.localdev' rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum diff --git a/src/cmd/go/testdata/script/mod_symlink.txt b/src/cmd/go/testdata/script/mod_symlink.txt index 49bece2b84..dbc23fb8f0 100644 --- a/src/cmd/go/testdata/script/mod_symlink.txt +++ b/src/cmd/go/testdata/script/mod_symlink.txt @@ -1,16 +1,19 @@ env GO111MODULE=on [!symlink] skip -# 'go list' should resolve modules of imported packages. +# 'go get -d' should resolve modules of imported packages. +go get -d go list -deps -f '{{.Module}}' . stdout golang.org/x/text +go get -d ./subpkg go list -deps -f '{{.Module}}' ./subpkg stdout golang.org/x/text # Create a copy of the module using symlinks in src/links. mkdir links symlink links/go.mod -> $GOPATH/src/go.mod +symlink links/go.sum -> $GOPATH/src/go.sum symlink links/issue.go -> $GOPATH/src/issue.go mkdir links/subpkg symlink links/subpkg/issue.go -> $GOPATH/src/subpkg/issue.go diff --git a/src/cmd/go/testdata/script/mod_test.txt b/src/cmd/go/testdata/script/mod_test.txt index 8f2da2f2a5..50f00355c1 100644 --- a/src/cmd/go/testdata/script/mod_test.txt +++ b/src/cmd/go/testdata/script/mod_test.txt @@ -1,4 +1,5 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # TODO(bcmills): Convert the 'go test' calls below to 'go list -test' once 'go diff --git a/src/cmd/go/testdata/script/mod_test_cached.txt b/src/cmd/go/testdata/script/mod_test_cached.txt index ffd573c02a..3da4358fa1 100644 --- a/src/cmd/go/testdata/script/mod_test_cached.txt +++ b/src/cmd/go/testdata/script/mod_test_cached.txt @@ -51,26 +51,25 @@ bar package foo_test import ( - "io/ioutil" "os" "path/filepath" "testing" ) func TestWriteTmp(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) - err = ioutil.WriteFile(filepath.Join(dir, "x"), nil, 0666) + err = os.WriteFile(filepath.Join(dir, "x"), nil, 0666) if err != nil { t.Fatal(err) } } func TestReadTestdata(t *testing.T) { - _, err := ioutil.ReadFile("testdata/foo.txt") + _, err := os.ReadFile("testdata/foo.txt") if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/testdata/script/mod_tidy_replace.txt b/src/cmd/go/testdata/script/mod_tidy_replace.txt index c3158f8610..dd99438891 100644 --- a/src/cmd/go/testdata/script/mod_tidy_replace.txt +++ b/src/cmd/go/testdata/script/mod_tidy_replace.txt @@ -1,4 +1,5 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # golang.org/issue/30166: 'go mod tidy' should not crash if a replaced module is @@ -34,7 +35,7 @@ grep 'golang.org/x/text' go.mod # 'go get' and 'go mod tidy' should follow the requirements of the replacements, # not the originals, even if that results in a set of versions that are # misleading or redundant without those replacements. -go get rsc.io/sampler@v1.2.0 +go get -d rsc.io/sampler@v1.2.0 go mod tidy go list -m all stdout 'rsc.io/quote/v3 v3.0.0' diff --git a/src/cmd/go/testdata/script/mod_upgrade_patch.txt b/src/cmd/go/testdata/script/mod_upgrade_patch.txt index 3939e54c1b..8b34f8bf27 100644 --- a/src/cmd/go/testdata/script/mod_upgrade_patch.txt +++ b/src/cmd/go/testdata/script/mod_upgrade_patch.txt @@ -2,12 +2,18 @@ env GO111MODULE=on [short] skip # Initially, we are at v1.0.0 for all dependencies. +go get -d cp go.mod go.mod.orig go list -m all stdout '^patch.example.com/direct v1.0.0' stdout '^patch.example.com/indirect v1.0.0' ! stdout '^patch.example.com/depofdirectpatch' +# @patch should be rejected for modules not already in the build list. +! go get -d patch.example.com/depofdirectpatch@patch +stderr '^go get: can''t query version "patch" of module patch.example.com/depofdirectpatch: no existing version is required$' +cmp go.mod.orig go.mod + # get -u=patch, with no arguments, should patch-update all dependencies # of the package in the current directory, pulling in transitive dependencies # and also patching those. @@ -18,7 +24,7 @@ stdout '^patch.example.com/direct v1.0.1' stdout '^patch.example.com/indirect v1.0.1' stdout '^patch.example.com/depofdirectpatch v1.0.0' -# 'get all@patch' should be equivalent to 'get -u=patch all' +# 'get all@patch' should patch the modules that provide packages in 'all'. cp go.mod.orig go.mod go get -d all@patch go list -m all @@ -26,6 +32,15 @@ stdout '^patch.example.com/direct v1.0.1' stdout '^patch.example.com/indirect v1.0.1' stdout '^patch.example.com/depofdirectpatch v1.0.0' +# ...but 'all@patch' should fail if any of the affected modules do not already +# have a selected version. +cp go.mod.orig go.mod +go mod edit -droprequire=patch.example.com/direct +cp go.mod go.mod.dropped +! go get -d all@patch +stderr '^go get all@patch: can''t query version "patch" of module patch.example.com/direct: no existing version is required$' +cmp go.mod.dropped go.mod + # Requesting the direct dependency with -u=patch but without an explicit version # should patch-update it and its dependencies. cp go.mod.orig go.mod @@ -68,10 +83,10 @@ stdout '^patch.example.com/direct v1.1.0' stdout '^patch.example.com/indirect v1.0.1' ! stdout '^patch.example.com/depofdirectpatch' -# Standard-library packages cannot be upgraded explicitly. +# Standard library packages cannot be upgraded explicitly. cp go.mod.orig go.mod ! go get cmd/vet@patch -stderr 'cannot use pattern .* with explicit version' +stderr 'go get: can''t request explicit version "patch" of standard library package cmd/vet$' # However, standard-library packages without explicit versions are fine. go get -d -u=patch -d cmd/go @@ -84,6 +99,7 @@ go get -d example.com/noroot@patch go list -m all stdout '^example.com/noroot v1.0.1$' + -- go.mod -- module x diff --git a/src/cmd/go/testdata/script/mod_vcs_missing.txt b/src/cmd/go/testdata/script/mod_vcs_missing.txt index a755935b53..f8be43cf4c 100644 --- a/src/cmd/go/testdata/script/mod_vcs_missing.txt +++ b/src/cmd/go/testdata/script/mod_vcs_missing.txt @@ -5,14 +5,14 @@ env GO111MODULE=on env GOPROXY=direct cd empty -! go list launchpad.net/gocheck +! go get -d launchpad.net/gocheck stderr '"bzr": executable file not found' cd .. # 1.11 used to give the cryptic error "cannot find module for path" here, but # only for a main package. cd main -! go build +! go build -mod=mod stderr '"bzr": executable file not found' cd .. diff --git a/src/cmd/go/testdata/script/mod_vendor_auto.txt b/src/cmd/go/testdata/script/mod_vendor_auto.txt index 53120dcfa1..1b362eda0b 100644 --- a/src/cmd/go/testdata/script/mod_vendor_auto.txt +++ b/src/cmd/go/testdata/script/mod_vendor_auto.txt @@ -177,7 +177,7 @@ stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' # 'go get' should update from the network or module cache, # even if a vendor directory is present. -go get -u example.com/printversion +go get -d example.com/version@v1.1.0 ! go list -f {{.Dir}} -tags tools all stderr '^go: inconsistent vendoring' diff --git a/src/cmd/go/testdata/script/mod_vendor_build.txt b/src/cmd/go/testdata/script/mod_vendor_build.txt index 0c359cea6e..3b8eec0119 100644 --- a/src/cmd/go/testdata/script/mod_vendor_build.txt +++ b/src/cmd/go/testdata/script/mod_vendor_build.txt @@ -1,13 +1,16 @@ env GO111MODULE=on [short] skip +# Populate go.mod and go.sum. +go mod tidy + # initial conditions: using sampler v1.3.0, not listed in go.mod. go list -deps stdout rsc.io/sampler ! grep 'rsc.io/sampler v1.3.0' go.mod # update to v1.3.1, now indirect in go.mod. -go get rsc.io/sampler@v1.3.1 +go get -d rsc.io/sampler@v1.3.1 grep 'rsc.io/sampler v1.3.1 // indirect' go.mod cp go.mod go.mod.good diff --git a/src/cmd/go/testdata/script/mod_verify.txt b/src/cmd/go/testdata/script/mod_verify.txt index 3918400435..43812d069f 100644 --- a/src/cmd/go/testdata/script/mod_verify.txt +++ b/src/cmd/go/testdata/script/mod_verify.txt @@ -56,7 +56,7 @@ go mod tidy # Packages below module root should not be mentioned in go.sum. rm go.sum go mod edit -droprequire rsc.io/quote -go list rsc.io/quote/buggy # re-resolves import path and updates go.mod +go get -d rsc.io/quote/buggy grep '^rsc.io/quote v1.5.2/go.mod ' go.sum ! grep buggy go.sum diff --git a/src/cmd/go/testdata/script/mod_why.txt b/src/cmd/go/testdata/script/mod_why.txt index 10a4f9fbea..b3036fa830 100644 --- a/src/cmd/go/testdata/script/mod_why.txt +++ b/src/cmd/go/testdata/script/mod_why.txt @@ -1,6 +1,10 @@ env GO111MODULE=on [short] skip +# Populate go.sum. +go mod tidy +cp go.mod go.mod.orig + go list -test all stdout rsc.io/quote stdout golang.org/x/text/language @@ -17,7 +21,7 @@ cmp stdout why-text-module.txt go mod why rsc.io/testonly cmp stdout why-testonly.txt -# why a module used only in tests? +# why a module used only in a test of a dependency? go mod why -m rsc.io/testonly cmp stdout why-testonly.txt @@ -41,6 +45,14 @@ cmp stdout why-both.txt go mod why -m rsc.io/quote rsc.io/sampler cmp stdout why-both-module.txt +# package in a module that isn't even in the module graph +# (https://golang.org/issue/26977) +go mod why rsc.io/fortune +cmp stdout why-missing.txt + +# None of these command should have changed the go.mod file. +cmp go.mod go.mod.orig + -- go.mod -- module mymodule require rsc.io/quote v1.5.2 @@ -113,3 +125,6 @@ mymodule/y mymodule/y.test rsc.io/quote rsc.io/sampler +-- why-missing.txt -- +# rsc.io/fortune +(main module does not need package rsc.io/fortune) diff --git a/src/cmd/go/testdata/script/modfile_flag.txt b/src/cmd/go/testdata/script/modfile_flag.txt index f05bf03fbf..0ad0880817 100644 --- a/src/cmd/go/testdata/script/modfile_flag.txt +++ b/src/cmd/go/testdata/script/modfile_flag.txt @@ -37,10 +37,10 @@ go mod why rsc.io/quote # 'go list' and other commands with build flags should work. # They should update the alternate go.mod when a dependency is missing. go mod edit -droprequire rsc.io/quote -go list . +go list -mod=mod . grep rsc.io/quote go.alt.mod -go build -n . -go test -n . +go build -n -mod=mod . +go test -n -mod=mod . go get -d rsc.io/quote diff --git a/src/cmd/go/testdata/script/run_hello_pkg.txt b/src/cmd/go/testdata/script/run_hello_pkg.txt index 03fba13c77..ea2b4d7cde 100644 --- a/src/cmd/go/testdata/script/run_hello_pkg.txt +++ b/src/cmd/go/testdata/script/run_hello_pkg.txt @@ -1,11 +1,14 @@ -cd $GOPATH -go run hello +go run m/hello stderr 'hello, world' -cd src/hello +cd hello go run . stderr 'hello, world' +-- go.mod -- +module m + +go 1.16 -- hello/hello.go -- package main diff --git a/src/cmd/go/testdata/script/run_vendor.txt b/src/cmd/go/testdata/script/run_vendor.txt index 8544281db9..46cac06bf4 100644 --- a/src/cmd/go/testdata/script/run_vendor.txt +++ b/src/cmd/go/testdata/script/run_vendor.txt @@ -1,4 +1,5 @@ # Run +env GO111MODULE=off cd vend/hello go run hello.go stdout 'hello, world' diff --git a/src/cmd/go/testdata/script/sum_readonly.txt b/src/cmd/go/testdata/script/sum_readonly.txt deleted file mode 100644 index 8aa61166ac..0000000000 --- a/src/cmd/go/testdata/script/sum_readonly.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Test that go.sum does not get updated when -mod=readonly flag is set -env GO111MODULE=on - -go get -d rsc.io/quote -go mod tidy - -# go.sum != dirty; -mod=readonly -go list -mod=readonly - -# dirty up go.sum by removing it. -rm go.sum - -# go.sum == dirty; -mod=readonly -! go list -mod=readonly - -stderr 'go: updates to go.sum needed, disabled by -mod=readonly' - --- go.mod -- -module m - --- main.go -- - -package main - -import "rsc.io/quote" - -func main() { - println(quote.Hello()) -}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_fatal.txt b/src/cmd/go/testdata/script/test_benchmark_fatal.txt index 1e20c4eb61..e281379ebd 100644 --- a/src/cmd/go/testdata/script/test_benchmark_fatal.txt +++ b/src/cmd/go/testdata/script/test_benchmark_fatal.txt @@ -5,7 +5,11 @@ ! stderr ^ok stdout FAIL.*benchfatal --- benchfatal/x_test.go -- +-- go.mod -- +module benchfatal + +go 1.16 +-- x_test.go -- package benchfatal import "testing" diff --git a/src/cmd/go/testdata/script/test_benchmark_labels.txt b/src/cmd/go/testdata/script/test_benchmark_labels.txt index affab6b806..6b424c1bd8 100644 --- a/src/cmd/go/testdata/script/test_benchmark_labels.txt +++ b/src/cmd/go/testdata/script/test_benchmark_labels.txt @@ -10,7 +10,11 @@ stdout '^pkg: bench' ! stdout 'pkg:.*pkg: ' ! stderr 'pkg:.*pkg:' --- bench/x_test.go -- +-- go.mod -- +module bench + +go 1.16 +-- x_test.go -- package bench import "testing" diff --git a/src/cmd/go/testdata/script/test_build_failure.txt b/src/cmd/go/testdata/script/test_build_failure.txt index 2ae448a566..8d13634c8c 100644 --- a/src/cmd/go/testdata/script/test_build_failure.txt +++ b/src/cmd/go/testdata/script/test_build_failure.txt @@ -5,13 +5,17 @@ stderr 'undefined: g' stderr 'undefined: j' --- coverbad/p.go -- +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- package p func f() { g() } --- coverbad/p1.go -- +-- p1.go -- package p import "C" @@ -19,7 +23,7 @@ import "C" func h() { j() } --- coverbad/p_test.go -- +-- p_test.go -- package p import "testing" diff --git a/src/cmd/go/testdata/script/test_cache_inputs.txt b/src/cmd/go/testdata/script/test_cache_inputs.txt index 57602e91dc..50486e1909 100644 --- a/src/cmd/go/testdata/script/test_cache_inputs.txt +++ b/src/cmd/go/testdata/script/test_cache_inputs.txt @@ -137,7 +137,7 @@ exit 0 package testcache import ( - "io/ioutil" + "io" "os" "testing" ) @@ -159,7 +159,7 @@ func TestOddFileContent(t *testing.T) { if err != nil { t.Fatal(err) } - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) f.Close() if err != nil { t.Fatal(err) diff --git a/src/cmd/go/testdata/script/test_cleanup_failnow.txt b/src/cmd/go/testdata/script/test_cleanup_failnow.txt new file mode 100644 index 0000000000..0737a93db2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_cleanup_failnow.txt @@ -0,0 +1,47 @@ +# For issue 41355 +[short] skip + +# This test could fail if the testing package does not wait until +# a panicking test does the panic. Turn off multithreading, GC, and +# async preemption to increase the probability of such a failure. +env GOMAXPROCS=1 +env GOGC=off +env GODEBUG=asyncpreempt=off + +# If the test exits with 'no tests to run', it means the testing package +# implementation is incorrect and does not wait until a test panic. +# If the test exits with '(?s)panic: die.*panic: die', it means +# the testing package did an extra panic for a panicking test. + +! go test -v cleanup_failnow/panic_nocleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +! go test -v cleanup_failnow/panic_withcleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +-- cleanup_failnow/panic_nocleanup_test.go -- +package panic_nocleanup_test +import "testing" +func TestX(t *testing.T) { + t.Run("x", func(t *testing.T) { + panic("die") + }) +} + +-- cleanup_failnow/panic_withcleanup_test.go -- +package panic_withcleanup_test +import "testing" +func TestCleanupWithFailNow(t *testing.T) { + t.Cleanup(func() { + t.FailNow() + }) + t.Run("x", func(t *testing.T) { + t.Run("y", func(t *testing.T) { + panic("die") + }) + }) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_compile_tempfile.txt b/src/cmd/go/testdata/script/test_compile_tempfile.txt index 912410814f..05f721a800 100644 --- a/src/cmd/go/testdata/script/test_compile_tempfile.txt +++ b/src/cmd/go/testdata/script/test_compile_tempfile.txt @@ -1,7 +1,7 @@ [short] skip # Ensure that the target of 'go build -o' can be an existing, empty file so that -# its name can be reserved using ioutil.TempFile or the 'mktemp` command. +# its name can be reserved using os.CreateTemp or the 'mktemp` command. go build -o empty-file$GOEXE main.go diff --git a/src/cmd/go/testdata/script/test_deadline.txt b/src/cmd/go/testdata/script/test_deadline.txt index 5a19f6590f..06ae16ffd2 100644 --- a/src/cmd/go/testdata/script/test_deadline.txt +++ b/src/cmd/go/testdata/script/test_deadline.txt @@ -4,6 +4,10 @@ go test -timeout=0 -run=TestNoDeadline go test -timeout=1m -run=TestDeadlineWithinMinute go test -timeout=1m -run=TestSubtestDeadlineWithinMinute +-- go.mod -- +module m + +go 1.16 -- deadline_test.go -- package testing_test diff --git a/src/cmd/go/testdata/script/test_empty.txt b/src/cmd/go/testdata/script/test_empty.txt index f2c512e791..5ebbecd53d 100644 --- a/src/cmd/go/testdata/script/test_empty.txt +++ b/src/cmd/go/testdata/script/test_empty.txt @@ -23,6 +23,10 @@ go test -cover -coverpkg=. -race cd $GOPATH/src/empty/testxtest go test -cover -coverpkg=. -race +-- empty/go.mod -- +module empty + +go 1.16 -- empty/pkg/pkg.go -- package p -- empty/pkgtest/pkg.go -- diff --git a/src/cmd/go/testdata/script/test_example_goexit.txt b/src/cmd/go/testdata/script/test_example_goexit.txt index 59219e3366..984f4349f5 100644 --- a/src/cmd/go/testdata/script/test_example_goexit.txt +++ b/src/cmd/go/testdata/script/test_example_goexit.txt @@ -5,7 +5,11 @@ stdout '(?s)--- PASS.*--- FAIL.*' stdout 'panic: test executed panic\(nil\) or runtime\.Goexit' --- examplegoexit/example_test.go -- +-- go.mod -- +module examplegoexit + +go 1.16 +-- example_test.go -- package main import ( diff --git a/src/cmd/go/testdata/script/test_flag.txt b/src/cmd/go/testdata/script/test_flag.txt index bbcad1c59c..ec88d38cbe 100644 --- a/src/cmd/go/testdata/script/test_flag.txt +++ b/src/cmd/go/testdata/script/test_flag.txt @@ -3,6 +3,22 @@ go test flag_test.go -v -args -v=7 # Two distinct -v flags go test -v flag_test.go -args -v=7 # Two distinct -v flags +# Using a custom flag mixed with regular 'go test' flags should be OK. +go test -count=1 -custom -args -v=7 + +# However, it should be an error to use custom flags when -i or -c are used, +# since we know for sure that no test binary will run at all. +! go test -i -custom +stderr '^flag -custom is not a ''go test'' flag \(unknown flags cannot be used with -i\)$' +! go test -c -custom +stderr '^flag -custom is not a ''go test'' flag \(unknown flags cannot be used with -c\)$' + +# The same should apply even if -c or -i come after a custom flag. +! go test -custom -c +stderr '^flag -custom is not a ''go test'' flag \(unknown flags cannot be used with -c\)$' + +-- go.mod -- +module m -- flag_test.go -- package flag_test @@ -14,6 +30,8 @@ import ( var v = flag.Int("v", 0, "v flag") +var custom = flag.Bool("custom", false, "") + // Run this as go test pkg -v=7 func TestVFlagIsSet(t *testing.T) { if *v != 7 { diff --git a/src/cmd/go/testdata/script/test_generated_main.txt b/src/cmd/go/testdata/script/test_generated_main.txt index 75ffa9cde2..2e991a5797 100644 --- a/src/cmd/go/testdata/script/test_generated_main.txt +++ b/src/cmd/go/testdata/script/test_generated_main.txt @@ -12,7 +12,6 @@ package x import ( "os" "path/filepath" - "io/ioutil" "regexp" "testing" ) @@ -23,7 +22,7 @@ func Test(t *testing.T) { t.Fatal(err) } testmainPath := filepath.Join(filepath.Dir(exePath), "_testmain.go") - source, err := ioutil.ReadFile(testmainPath) + source, err := os.ReadFile(testmainPath) if err != nil { t.Fatal(err) } diff --git a/src/cmd/go/testdata/script/test_import_error_stack.txt b/src/cmd/go/testdata/script/test_import_error_stack.txt index c66c1213a4..6c60f3d2ab 100644 --- a/src/cmd/go/testdata/script/test_import_error_stack.txt +++ b/src/cmd/go/testdata/script/test_import_error_stack.txt @@ -1,9 +1,20 @@ +env GO111MODULE=off ! go test testdep/p1 stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +! go vet testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +env GO111MODULE=on +cd testdep +! go test testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack ! go vet testdep/p1 stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +-- testdep/go.mod -- +module testdep + +go 1.16 -- testdep/p1/p1.go -- package p1 -- testdep/p1/p1_test.go -- diff --git a/src/cmd/go/testdata/script/test_json.txt b/src/cmd/go/testdata/script/test_json.txt index 1bd530514c..cd5b0b9d7a 100644 --- a/src/cmd/go/testdata/script/test_json.txt +++ b/src/cmd/go/testdata/script/test_json.txt @@ -3,23 +3,23 @@ env GOCACHE=$WORK/tmp -# Run go test -json on errors empty/pkg and skipper +# Run go test -json on errors m/empty/pkg and m/skipper # It would be nice to test that the output is interlaced # but it seems to be impossible to do that in a short test # that isn't also flaky. Just check that we get JSON output. -go test -json -short -v errors empty/pkg skipper +go test -json -short -v errors m/empty/pkg m/skipper # Check errors for run action stdout '"Package":"errors"' stdout '"Action":"run","Package":"errors"' -# Check empty/pkg for output and skip actions -stdout '"Action":"output","Package":"empty/pkg","Output":".*no test files' -stdout '"Action":"skip","Package":"empty/pkg"' +# Check m/empty/pkg for output and skip actions +stdout '"Action":"output","Package":"m/empty/pkg","Output":".*no test files' +stdout '"Action":"skip","Package":"m/empty/pkg"' # Check skipper for output and skip actions -stdout '"Action":"output","Package":"skipper","Test":"Test","Output":"--- SKIP:' -stdout '"Action":"skip","Package":"skipper","Test":"Test"' +stdout '"Action":"output","Package":"m/skipper","Test":"Test","Output":"--- SKIP:' +stdout '"Action":"skip","Package":"m/skipper","Test":"Test"' # Run go test -json on errors and check it's cached go test -json -short -v errors @@ -36,6 +36,10 @@ stdout '"Package":"errors"' stdout '"Action":"run"' stdout '\{"Action":"pass","Package":"errors"\}' +-- go.mod -- +module m + +go 1.16 -- skipper/skip_test.go -- package skipper diff --git a/src/cmd/go/testdata/script/test_main_twice.txt b/src/cmd/go/testdata/script/test_main_twice.txt index 1e68dabec0..f32d4fc3b5 100644 --- a/src/cmd/go/testdata/script/test_main_twice.txt +++ b/src/cmd/go/testdata/script/test_main_twice.txt @@ -4,7 +4,11 @@ env GOCACHE=$WORK/tmp go test -v multimain stdout -count=2 notwithstanding # check tests ran twice --- multimain/multimain_test.go -- +-- go.mod -- +module multimain + +go 1.16 +-- multimain_test.go -- package multimain_test import "testing" diff --git a/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt index 92cb690dcc..e1c96438c8 100644 --- a/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt +++ b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt @@ -6,9 +6,13 @@ ! stderr '(?m)^ok.*\[no tests to run\]' stdout 'FAIL' --- syntaxerror/x.go -- +-- go.mod -- +module syntaxerror + +go 1.16 +-- x.go -- package p --- syntaxerror/x_test.go -- +-- x_test.go -- package p func f() (x.y, z int) { diff --git a/src/cmd/go/testdata/script/test_no_run_example.txt b/src/cmd/go/testdata/script/test_no_run_example.txt index 66daa310fa..53ac755902 100644 --- a/src/cmd/go/testdata/script/test_no_run_example.txt +++ b/src/cmd/go/testdata/script/test_no_run_example.txt @@ -1,7 +1,11 @@ go test -v norunexample stdout 'File with non-runnable example was built.' --- norunexample/example_test.go -- +-- go.mod -- +module norunexample + +go 1.16 +-- example_test.go -- package pkg_test import "os" @@ -13,7 +17,7 @@ func init() { func Example_test() { // This test will not be run, it has no "Output:" comment. } --- norunexample/test_test.go -- +-- test_test.go -- package pkg import ( diff --git a/src/cmd/go/testdata/script/test_no_tests.txt b/src/cmd/go/testdata/script/test_no_tests.txt index d75bcff934..2d624d1da6 100644 --- a/src/cmd/go/testdata/script/test_no_tests.txt +++ b/src/cmd/go/testdata/script/test_no_tests.txt @@ -3,7 +3,11 @@ go test testnorun stdout 'testnorun\t\[no test files\]' --- testnorun/p.go -- +-- go.mod -- +module testnorun + +go 1.16 +-- p.go -- package p func init() { diff --git a/src/cmd/go/testdata/script/test_race.txt b/src/cmd/go/testdata/script/test_race.txt index 5d15189e19..2ffea46092 100644 --- a/src/cmd/go/testdata/script/test_race.txt +++ b/src/cmd/go/testdata/script/test_race.txt @@ -13,7 +13,11 @@ stdout 'FAIL: BenchmarkRace' ! stdout 'PASS' ! stderr 'PASS' --- testrace/race_test.go -- +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- package testrace import "testing" diff --git a/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt index bff9502ac7..eacc882091 100644 --- a/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt +++ b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt @@ -10,7 +10,11 @@ stderr '-covermode must be "atomic", not "set", when -race is enabled' ! stdout PASS ! stderr PASS --- testrace/race_test.go -- +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- package testrace import "testing" diff --git a/src/cmd/go/testdata/script/test_race_install.txt b/src/cmd/go/testdata/script/test_race_install.txt index 66dc19ebb6..8b1f343a32 100644 --- a/src/cmd/go/testdata/script/test_race_install.txt +++ b/src/cmd/go/testdata/script/test_race_install.txt @@ -6,8 +6,13 @@ go install -race -pkgdir=$WORKDIR/tmp/pkg std # Make sure go test -i -race doesn't rebuild cached packages go test -race -pkgdir=$WORKDIR/tmp/pkg -i -v empty/pkg -! stderr . +cmp stderr stderr.txt --- empty/pkg/pkg.go -- -package p +-- go.mod -- +module empty +go 1.16 +-- pkg/pkg.go -- +package p +-- stderr.txt -- +go test: -i flag is deprecated diff --git a/src/cmd/go/testdata/script/test_race_install_cgo.txt b/src/cmd/go/testdata/script/test_race_install_cgo.txt index feddc8f922..3f4eb90e3f 100644 --- a/src/cmd/go/testdata/script/test_race_install_cgo.txt +++ b/src/cmd/go/testdata/script/test_race_install_cgo.txt @@ -5,7 +5,7 @@ [!darwin] ! stale cmd/cgo # The darwin builders are spuriously stale; see #33598. env GOBIN=$WORK/bin -go install mtime sametime +go install m/mtime m/sametime go tool -n cgo cp stdout cgopath.txt @@ -21,11 +21,14 @@ exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopa cp stdout cgotime_after.txt exec $GOBIN/sametime cgotime_before.txt cgotime_after.txt +-- go.mod -- +module m + +go 1.16 -- mtime/mtime.go -- package main import ( - "io/ioutil" "encoding/json" "fmt" "os" @@ -33,7 +36,7 @@ import ( ) func main() { - b, err := ioutil.ReadFile(os.Args[1]) + b, err := os.ReadFile(os.Args[1]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -55,7 +58,6 @@ package main import ( "encoding/json" "fmt" - "io/ioutil" "os" "time" ) @@ -63,7 +65,7 @@ import ( func main() { var t1 time.Time - b1, err := ioutil.ReadFile(os.Args[1]) + b1, err := os.ReadFile(os.Args[1]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) @@ -74,7 +76,7 @@ func main() { } var t2 time.Time - b2, err := ioutil.ReadFile(os.Args[2]) + b2, err := os.ReadFile(os.Args[2]) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) diff --git a/src/cmd/go/testdata/script/test_regexps.txt b/src/cmd/go/testdata/script/test_regexps.txt index a616195cab..2f33080a00 100644 --- a/src/cmd/go/testdata/script/test_regexps.txt +++ b/src/cmd/go/testdata/script/test_regexps.txt @@ -35,7 +35,11 @@ stdout -count=1 '^ z_test.go:18: LOG: XX running N=1$' # a large number, and the last iteration count prints right before the results. stdout -count=2 '^ x_test.go:15: LOG: Y running N=[1-9]\d{4,}\nBenchmarkX/Y\s+\d+' --- testregexp/x_test.go -- +-- go.mod -- +module testregexp + +go 1.16 +-- x_test.go -- package x import "testing" @@ -53,7 +57,7 @@ func BenchmarkX(b *testing.B) { b.Logf("LOG: Y running N=%d", b.N) }) } --- testregexp/z_test.go -- +-- z_test.go -- package x import "testing" diff --git a/src/cmd/go/testdata/script/test_relative_import.txt b/src/cmd/go/testdata/script/test_relative_import.txt index 0d212b4924..938a875b55 100644 --- a/src/cmd/go/testdata/script/test_relative_import.txt +++ b/src/cmd/go/testdata/script/test_relative_import.txt @@ -1,4 +1,5 @@ # Relative imports in go test +env GO111MODULE=off # relative import not supported in module mode # Run tests outside GOPATH. env GOPATH=$WORK/tmp @@ -27,4 +28,4 @@ func TestF(t *testing.T) { if F() != p1.F() { t.Fatal(F()) } -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt index dafa04ef02..b2716d8403 100644 --- a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt +++ b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt @@ -1,4 +1,5 @@ # Relative imports in go test -i +env GO111MODULE=off # relative import not supported in module mode # Run tests outside GOPATH. env GOPATH=$WORK/tmp @@ -28,4 +29,4 @@ func TestF(t *testing.T) { if F() != p1.F() { t.Fatal(F()) } -}
\ No newline at end of file +} diff --git a/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt index 29fa805b43..44ff6e2b39 100644 --- a/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt +++ b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt @@ -1,10 +1,21 @@ # Test that the error message for a syntax error in a test go file # says FAIL. +env GO111MODULE=off ! go test syntaxerror stderr 'x_test.go:' # check that the error is diagnosed stdout 'FAIL' # check that go test says FAIL +env GO111MODULE=on +cd syntaxerror +! go test syntaxerror +stderr 'x_test.go:' # check that the error is diagnosed +stdout 'FAIL' # check that go test says FAIL + +-- syntaxerror/go.mod -- +module syntaxerror + +go 1.16 -- syntaxerror/x.go -- package p -- syntaxerror/x_test.go -- diff --git a/src/cmd/go/testdata/script/test_vendor.txt b/src/cmd/go/testdata/script/test_vendor.txt index d72d672827..c6a88b6fed 100644 --- a/src/cmd/go/testdata/script/test_vendor.txt +++ b/src/cmd/go/testdata/script/test_vendor.txt @@ -1,9 +1,19 @@ -# Test +# In GOPATH mode, vendored packages can replace std packages. +env GO111MODULE=off cd vend/hello go test -v stdout TestMsgInternal stdout TestMsgExternal +# In module mode, they cannot. +env GO111MODULE=on +! go test -mod=vendor +stderr 'undefined: strings.Msg' + +-- vend/hello/go.mod -- +module vend/hello + +go 1.16 -- vend/hello/hello.go -- package main diff --git a/src/cmd/go/testdata/script/test_vet.txt b/src/cmd/go/testdata/script/test_vet.txt index af26b4de79..5af26b54f9 100644 --- a/src/cmd/go/testdata/script/test_vet.txt +++ b/src/cmd/go/testdata/script/test_vet.txt @@ -17,20 +17,24 @@ go test -vet=off p1.go stdout '\[no test files\]' # Test issue #22890 -go test vetcycle -stdout 'vetcycle.*\[no test files\]' +go test m/vetcycle +stdout 'm/vetcycle.*\[no test files\]' # Test with ... -! go test vetfail/... +! go test ./vetfail/... stderr 'Printf format %d' -stdout 'ok\s+vetfail/p2' +stdout 'ok\s+m/vetfail/p2' # Check there's no diagnosis of a bad build constraint in vetxonly mode. # Use -a so that we need to recompute the vet-specific export data for # vetfail/p1. -go test -a vetfail/p2 +go test -a m/vetfail/p2 ! stderr 'invalid.*constraint' +-- go.mod -- +module m + +go 1.16 -- p1_test.go -- package p @@ -74,7 +78,7 @@ func F() { -- vetfail/p2/p2.go -- package p2 -import _ "vetfail/p1" +import _ "m/vetfail/p1" func F() { } diff --git a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt index a6cb934709..08e67a429e 100644 --- a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt +++ b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt @@ -2,13 +2,16 @@ [short] skip -cd profiling ! go test -cpuprofile cpu.pprof -memprofile mem.pprof -timeout 1ms grep . cpu.pprof grep . mem.pprof --- profiling/timeout_test.go -- +-- go.mod -- +module profiling + +go 1.16 +-- timeout_test.go -- package timeouttest_test import "testing" import "time" -func TestSleep(t *testing.T) { time.Sleep(time.Second) }
\ No newline at end of file +func TestSleep(t *testing.T) { time.Sleep(time.Second) } diff --git a/src/cmd/go/testdata/script/test_xtestonly_works.txt b/src/cmd/go/testdata/script/test_xtestonly_works.txt index 01bafb733b..8e150dbfc2 100644 --- a/src/cmd/go/testdata/script/test_xtestonly_works.txt +++ b/src/cmd/go/testdata/script/test_xtestonly_works.txt @@ -4,11 +4,15 @@ go test xtestonly ! stdout '^ok.*\[no tests to run\]' stdout '^ok' --- xtestonly/f.go -- +-- go.mod -- +module xtestonly + +go 1.16 +-- f.go -- package xtestonly func F() int { return 42 } --- xtestonly/f_test.go -- +-- f_test.go -- package xtestonly_test import ( diff --git a/src/cmd/go/testdata/script/testing_issue40908.txt b/src/cmd/go/testdata/script/testing_issue40908.txt index 4939de080c..839320e4e8 100644 --- a/src/cmd/go/testdata/script/testing_issue40908.txt +++ b/src/cmd/go/testdata/script/testing_issue40908.txt @@ -3,7 +3,11 @@ go test -race testrace --- testrace/race_test.go -- +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- package testrace import "testing" diff --git a/src/cmd/go/testdata/script/toolexec.txt b/src/cmd/go/testdata/script/toolexec.txt new file mode 100644 index 0000000000..526234196b --- /dev/null +++ b/src/cmd/go/testdata/script/toolexec.txt @@ -0,0 +1,85 @@ +[short] skip + +# Build our simple toolexec program. +go build ./cmd/mytool + +# Build the main package with our toolexec program. For each action, it will +# print the tool's name and the TOOLEXEC_IMPORTPATH value. We expect to compile +# each package once, and link the main package once. +# Don't check the entire output at once, because the order in which the tools +# are run is irrelevant here. +# Finally, note that asm and cgo are run twice. + +go build -toolexec=$PWD/mytool +[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$' +[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$' +[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$' +stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$' + +-- go.mod -- +module test/main +-- foo.go -- +// Simple package so we can test a program build with -toolexec. +// With a dummy import, to test different TOOLEXEC_IMPORTPATH values. +// Includes dummy uses of cgo and asm, to cover those tools as well. +package main + +import ( + _ "test/main/withasm" + _ "test/main/withcgo" +) + +func main() {} +-- withcgo/withcgo.go -- +package withcgo + +// int fortytwo() +// { +// return 42; +// } +import "C" +-- withcgo/stub.go -- +package withcgo + +// Stub file to ensure we build without cgo too. +-- withasm/withasm.go -- +package withasm + +// Note that we don't need to declare the Add func at all. +-- withasm/withasm_amd64.s -- +TEXT ·Add(SB),$0-24 + MOVQ a+0(FP), AX + ADDQ b+8(FP), AX + MOVQ AX, ret+16(FP) + RET +-- cmd/mytool/main.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" +) + +func main() { + tool, args := os.Args[1], os.Args[2:] + toolName := filepath.Base(tool) + if len(args) > 0 && args[0] == "-V=full" { + // We can't alter the version output. + } else { + // Print which tool we're running, and on what package. + fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%s\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH")) + } + + // Simply run the tool. + cmd := exec.Command(tool, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt index 746a34a744..da52f9acf2 100644 --- a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt +++ b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt @@ -1,4 +1,5 @@ [!windows] [short] stop 'this test only applies to Windows' +env GO111MODULE=off go build run_go.go exec ./run_go$GOEXE $GOPATH $GOPATH/src/vend/hello diff --git a/src/cmd/go/testdata/script/vendor_import.txt b/src/cmd/go/testdata/script/vendor_import.txt index 35419f36f1..df4c27df81 100644 --- a/src/cmd/go/testdata/script/vendor_import.txt +++ b/src/cmd/go/testdata/script/vendor_import.txt @@ -1,4 +1,5 @@ # Imports +env GO111MODULE=off go list -f '{{.ImportPath}} {{.Imports}}' 'vend/...' 'vend/vendor/...' 'vend/x/vendor/...' cmp stdout want_vendor_imports.txt diff --git a/src/cmd/go/testdata/script/vendor_import_wrong.txt b/src/cmd/go/testdata/script/vendor_import_wrong.txt index aba6269784..73bf595640 100644 --- a/src/cmd/go/testdata/script/vendor_import_wrong.txt +++ b/src/cmd/go/testdata/script/vendor_import_wrong.txt @@ -1,7 +1,18 @@ # Wrong import path +env GO111MODULE=off ! go build vend/x/invalid stderr 'must be imported as foo' +env GO111MODULE= +cd vend/x/invalid +! go build vend/x/invalid +stderr 'must be imported as foo' + +-- vend/x/invalid/go.mod -- +module vend/x/invalid + +go 1.16 + -- vend/x/invalid/invalid.go -- package invalid diff --git a/src/cmd/go/testdata/script/vendor_issue12156.txt b/src/cmd/go/testdata/script/vendor_issue12156.txt index 49eb235ba5..ac95c6d3da 100644 --- a/src/cmd/go/testdata/script/vendor_issue12156.txt +++ b/src/cmd/go/testdata/script/vendor_issue12156.txt @@ -1,5 +1,6 @@ # Tests issue #12156, a former index out of range panic. +env GO111MODULE=off env GOPATH=$WORK/gopath/src/testvendor2 # vendor/x is directly in $GOPATH, not in $GOPATH/src cd $WORK/gopath/src/testvendor2/src/p diff --git a/src/cmd/go/testdata/script/vendor_list_issue11977.txt b/src/cmd/go/testdata/script/vendor_list_issue11977.txt index d97c6518b4..ce2e29f99a 100644 --- a/src/cmd/go/testdata/script/vendor_list_issue11977.txt +++ b/src/cmd/go/testdata/script/vendor_list_issue11977.txt @@ -1,7 +1,8 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off -go get github.com/rsc/go-get-issue-11864 +go get -d github.com/rsc/go-get-issue-11864 go list -f '{{join .TestImports "\n"}}' github.com/rsc/go-get-issue-11864/t stdout 'go-get-issue-11864/vendor/vendor.org/p' @@ -13,4 +14,4 @@ go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendo stdout 'go-get-issue-11864/vendor/vendor.org/tx2' go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3 -stdout 'go-get-issue-11864/vendor/vendor.org/tx3'
\ No newline at end of file +stdout 'go-get-issue-11864/vendor/vendor.org/tx3' diff --git a/src/cmd/go/testdata/script/vendor_resolve.txt b/src/cmd/go/testdata/script/vendor_resolve.txt index 220b92f80b..bc8cf0ab38 100644 --- a/src/cmd/go/testdata/script/vendor_resolve.txt +++ b/src/cmd/go/testdata/script/vendor_resolve.txt @@ -1,3 +1,4 @@ +env GO111MODULE=off ! go build p stderr 'must be imported as x' diff --git a/src/cmd/go/testdata/script/vendor_test_issue11864.txt b/src/cmd/go/testdata/script/vendor_test_issue11864.txt index f11d790e6f..cfb43bf343 100644 --- a/src/cmd/go/testdata/script/vendor_test_issue11864.txt +++ b/src/cmd/go/testdata/script/vendor_test_issue11864.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off go get github.com/rsc/go-get-issue-11864 @@ -16,4 +17,4 @@ go test github.com/rsc/go-get-issue-11864 go test github.com/rsc/go-get-issue-11864/t # external tests should observe internal test exports (golang.org/issue/11977) -go test github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2
\ No newline at end of file +go test github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2 diff --git a/src/cmd/go/testdata/script/vendor_test_issue14613.txt b/src/cmd/go/testdata/script/vendor_test_issue14613.txt index 4e5e066d6b..7801e6944d 100644 --- a/src/cmd/go/testdata/script/vendor_test_issue14613.txt +++ b/src/cmd/go/testdata/script/vendor_test_issue14613.txt @@ -1,5 +1,6 @@ [!net] skip [!exec:git] skip +env GO111MODULE=off cd $GOPATH diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt index 0123ac6d53..8615a4aac5 100644 --- a/src/cmd/go/testdata/script/version.txt +++ b/src/cmd/go/testdata/script/version.txt @@ -9,11 +9,18 @@ stderr 'with arguments' ! go version -v stderr 'with arguments' +# Neither of the two flags above should be an issue via GOFLAGS. +env GOFLAGS='-m -v' +go version +stdout '^go version' +env GOFLAGS= + env GO111MODULE=on # Skip the builds below if we are running in short mode. [short] skip # Check that 'go version' and 'go version -m' work on a binary built in module mode. +go get -d rsc.io/fortune go build -o fortune.exe rsc.io/fortune go version fortune.exe stdout '^fortune.exe: .+' diff --git a/src/cmd/go/testdata/script/version_replace.txt b/src/cmd/go/testdata/script/version_replace.txt index b657086f09..ec98f4e3f3 100644 --- a/src/cmd/go/testdata/script/version_replace.txt +++ b/src/cmd/go/testdata/script/version_replace.txt @@ -1,7 +1,7 @@ [short] skip go mod download example.com/printversion@v0.1.0 example.com/printversion@v1.0.0 - +go get -d example.com/printversion@v0.1.0 go install example.com/printversion go run example.com/printversion diff --git a/src/cmd/go/testdata/script/vet.txt b/src/cmd/go/testdata/script/vet.txt index 73fe2958fc..6573ae3ebd 100644 --- a/src/cmd/go/testdata/script/vet.txt +++ b/src/cmd/go/testdata/script/vet.txt @@ -1,29 +1,33 @@ # Package with external tests -! go vet vetpkg +! go vet m/vetpkg stderr 'Printf' # With tags -! go vet -tags tagtest vetpkg +! go vet -tags tagtest m/vetpkg stderr 'c\.go.*Printf' # With flags on -! go vet -printf vetpkg +! go vet -printf m/vetpkg stderr 'Printf' # With flags off -go vet -printf=false vetpkg +go vet -printf=false m/vetpkg ! stderr . # With only test files (tests issue #23395) -go vet onlytest +go vet m/onlytest ! stderr . # With only cgo files (tests issue #24193) [!cgo] skip [short] skip -go vet onlycgo +go vet m/onlycgo ! stderr . +-- go.mod -- +module m + +go 1.16 -- vetpkg/a_test.go -- package p_test -- vetpkg/b.go -- @@ -55,4 +59,4 @@ package p import "C" -func F() {}
\ No newline at end of file +func F() {} diff --git a/src/cmd/go/testdata/script/vet_flags.txt b/src/cmd/go/testdata/script/vet_flags.txt index b85b133c19..e2e3f5bc55 100644 --- a/src/cmd/go/testdata/script/vet_flags.txt +++ b/src/cmd/go/testdata/script/vet_flags.txt @@ -2,21 +2,25 @@ env GO111MODULE=on # Issue 35837: "go vet -<analyzer> <std package>" should use the requested # analyzers, not the default analyzers for 'go test'. -go vet -n -unreachable=false encoding/binary -stderr '-unreachable=false' +go vet -n -buildtags=false runtime +stderr '-buildtags=false' ! stderr '-unsafeptr=false' # Issue 37030: "go vet <std package>" without other flags should disable the # unsafeptr check by default. -go vet -n encoding/binary +go vet -n runtime stderr '-unsafeptr=false' ! stderr '-unreachable=false' # However, it should be enabled if requested explicitly. -go vet -n -unsafeptr encoding/binary +go vet -n -unsafeptr runtime stderr '-unsafeptr' ! stderr '-unsafeptr=false' +# -unreachable is disabled during test but on during plain vet. +go test -n runtime +stderr '-unreachable=false' + # A flag terminator should be allowed before the package list. go vet -n -- . @@ -60,10 +64,10 @@ stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' # "go test" on a standard package should by default disable an explicit list. go test -x -run=none encoding/binary -stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' go test -x -vet= -run=none encoding/binary -stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' # Both should allow users to override via the -vet flag. go test -x -vet=unreachable -run=none . diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go index 8c56af7559..2793c2c2a4 100644 --- a/src/cmd/gofmt/gofmt.go +++ b/src/cmd/gofmt/gofmt.go @@ -14,7 +14,7 @@ import ( "go/scanner" "go/token" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "runtime" @@ -73,7 +73,7 @@ func initParserMode() { } } -func isGoFile(f os.FileInfo) bool { +func isGoFile(f fs.DirEntry) bool { // ignore non-Go files name := f.Name() return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") @@ -81,7 +81,7 @@ func isGoFile(f os.FileInfo) bool { // If in == nil, the source is the contents of the file with the given filename. func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error { - var perm os.FileMode = 0644 + var perm fs.FileMode = 0644 if in == nil { f, err := os.Open(filename) if err != nil { @@ -96,7 +96,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error perm = fi.Mode().Perm() } - src, err := ioutil.ReadAll(in) + src, err := io.ReadAll(in) if err != nil { return err } @@ -136,7 +136,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error if err != nil { return err } - err = ioutil.WriteFile(filename, res, perm) + err = os.WriteFile(filename, res, perm) if err != nil { os.Rename(bakname, filename) return err @@ -163,7 +163,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error return err } -func visitFile(path string, f os.FileInfo, err error) error { +func visitFile(path string, f fs.DirEntry, err error) error { if err == nil && isGoFile(f) { err = processFile(path, nil, os.Stdout, false) } @@ -176,7 +176,7 @@ func visitFile(path string, f os.FileInfo, err error) error { } func walkDir(path string) { - filepath.Walk(path, visitFile) + filepath.WalkDir(path, visitFile) } func main() { @@ -275,9 +275,9 @@ const chmodSupported = runtime.GOOS != "windows" // backupFile writes data to a new file named filename<number> with permissions perm, // with <number randomly chosen such that the file name is unique. backupFile returns // the chosen file name. -func backupFile(filename string, data []byte, perm os.FileMode) (string, error) { +func backupFile(filename string, data []byte, perm fs.FileMode) (string, error) { // create backup file - f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)) + f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) if err != nil { return "", err } diff --git a/src/cmd/gofmt/gofmt_test.go b/src/cmd/gofmt/gofmt_test.go index 98d3eb7eb2..bf2adfe64c 100644 --- a/src/cmd/gofmt/gofmt_test.go +++ b/src/cmd/gofmt/gofmt_test.go @@ -7,7 +7,6 @@ package main import ( "bytes" "flag" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -93,7 +92,7 @@ func runTest(t *testing.T, in, out string) { return } - expected, err := ioutil.ReadFile(out) + expected, err := os.ReadFile(out) if err != nil { t.Error(err) return @@ -102,7 +101,7 @@ func runTest(t *testing.T, in, out string) { if got := buf.Bytes(); !bytes.Equal(got, expected) { if *update { if in != out { - if err := ioutil.WriteFile(out, got, 0666); err != nil { + if err := os.WriteFile(out, got, 0666); err != nil { t.Error(err) } return @@ -116,7 +115,7 @@ func runTest(t *testing.T, in, out string) { if err == nil { t.Errorf("%s", d) } - if err := ioutil.WriteFile(in+".gofmt", got, 0666); err != nil { + if err := os.WriteFile(in+".gofmt", got, 0666); err != nil { t.Error(err) } } @@ -157,7 +156,7 @@ func TestCRLF(t *testing.T) { const input = "testdata/crlf.input" // must contain CR/LF's const golden = "testdata/crlf.golden" // must not contain any CR's - data, err := ioutil.ReadFile(input) + data, err := os.ReadFile(input) if err != nil { t.Error(err) } @@ -165,7 +164,7 @@ func TestCRLF(t *testing.T) { t.Errorf("%s contains no CR/LF's", input) } - data, err = ioutil.ReadFile(golden) + data, err = os.ReadFile(golden) if err != nil { t.Error(err) } @@ -175,7 +174,7 @@ func TestCRLF(t *testing.T) { } func TestBackupFile(t *testing.T) { - dir, err := ioutil.TempDir("", "gofmt_test") + dir, err := os.MkdirTemp("", "gofmt_test") if err != nil { t.Fatal(err) } diff --git a/src/cmd/gofmt/long_test.go b/src/cmd/gofmt/long_test.go index e2a6208f87..4a821705f1 100644 --- a/src/cmd/gofmt/long_test.go +++ b/src/cmd/gofmt/long_test.go @@ -16,6 +16,7 @@ import ( "go/printer" "go/token" "io" + "io/fs" "os" "path/filepath" "runtime" @@ -107,12 +108,12 @@ func testFiles(t *testing.T, filenames <-chan string, done chan<- int) { func genFilenames(t *testing.T, filenames chan<- string) { defer close(filenames) - handleFile := func(filename string, fi os.FileInfo, err error) error { + handleFile := func(filename string, d fs.DirEntry, err error) error { if err != nil { t.Error(err) return nil } - if isGoFile(fi) { + if isGoFile(d) { filenames <- filename nfiles++ } @@ -123,13 +124,13 @@ func genFilenames(t *testing.T, filenames chan<- string) { if *files != "" { for _, filename := range strings.Split(*files, ",") { fi, err := os.Stat(filename) - handleFile(filename, fi, err) + handleFile(filename, &statDirEntry{fi}, err) } return // ignore files under -root } // otherwise, test all Go files under *root - filepath.Walk(*root, handleFile) + filepath.WalkDir(*root, handleFile) } func TestAll(t *testing.T) { @@ -163,3 +164,12 @@ func TestAll(t *testing.T) { fmt.Printf("processed %d files\n", nfiles) } } + +type statDirEntry struct { + info fs.FileInfo +} + +func (d *statDirEntry) Name() string { return d.info.Name() } +func (d *statDirEntry) IsDir() bool { return d.info.IsDir() } +func (d *statDirEntry) Type() fs.FileMode { return d.info.Mode().Type() } +func (d *statDirEntry) Info() (fs.FileInfo, error) { return d.info, nil } diff --git a/src/cmd/internal/archive/archive_test.go b/src/cmd/internal/archive/archive_test.go index 1468a58210..cb4eb842b4 100644 --- a/src/cmd/internal/archive/archive_test.go +++ b/src/cmd/internal/archive/archive_test.go @@ -243,7 +243,7 @@ func TestParseCGOArchive(t *testing.T) { c1 := "c1" c2 := "c2" switch runtime.GOOS { - case "darwin": + case "darwin", "ios": c1 = "_" + c1 c2 = "_" + c2 case "windows": @@ -275,7 +275,7 @@ func TestParseCGOArchive(t *testing.T) { obj := io.NewSectionReader(f, e.Offset, e.Size) switch runtime.GOOS { - case "darwin": + case "darwin", "ios": mf, err := macho.NewFile(obj) if err != nil { t.Fatal(err) diff --git a/src/cmd/internal/buildid/buildid.go b/src/cmd/internal/buildid/buildid.go index ac238d70ea..1e8855d3ac 100644 --- a/src/cmd/internal/buildid/buildid.go +++ b/src/cmd/internal/buildid/buildid.go @@ -10,18 +10,15 @@ import ( "fmt" "internal/xcoff" "io" + "io/fs" "os" "strconv" "strings" ) var ( - errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain") errBuildIDMalformed = fmt.Errorf("malformed object file") - errBuildIDUnknown = fmt.Errorf("lost build ID") -) -var ( bangArch = []byte("!<arch>") pkgdef = []byte("__.PKGDEF") goobject = []byte("go object ") @@ -109,7 +106,7 @@ func ReadFile(name string) (id string, err error) { // in cmd/go/internal/work/exec.go. func readGccgoArchive(name string, f *os.File) (string, error) { bad := func() (string, error) { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } off := int64(8) @@ -167,7 +164,7 @@ func readGccgoArchive(name string, f *os.File) (string, error) { // in cmd/go/internal/work/exec.go. func readGccgoBigArchive(name string, f *os.File) (string, error) { bad := func() (string, error) { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } // Read fixed-length header. @@ -309,13 +306,38 @@ func readRaw(name string, data []byte) (id string, err error) { j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd) if j < 0 { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1] id, err = strconv.Unquote(string(quoted)) if err != nil { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } return id, nil } + +// HashToString converts the hash h to a string to be recorded +// in package archives and binaries as part of the build ID. +// We use the first 120 bits of the hash (5 chunks of 24 bits each) and encode +// it in base64, resulting in a 20-byte string. Because this is only used for +// detecting the need to rebuild installed files (not for lookups +// in the object file cache), 120 bits are sufficient to drive the +// probability of a false "do not need to rebuild" decision to effectively zero. +// We embed two different hashes in archives and four in binaries, +// so cutting to 20 bytes is a significant savings when build IDs are displayed. +// (20*4+3 = 83 bytes compared to 64*4+3 = 259 bytes for the +// more straightforward option of printing the entire h in base64). +func HashToString(h [32]byte) string { + const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" + const chunks = 5 + var dst [chunks * 4]byte + for i := 0; i < chunks; i++ { + v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) + dst[4*i+0] = b64[(v>>18)&0x3F] + dst[4*i+1] = b64[(v>>12)&0x3F] + dst[4*i+2] = b64[(v>>6)&0x3F] + dst[4*i+3] = b64[v&0x3F] + } + return string(dst[:]) +} diff --git a/src/cmd/internal/buildid/buildid_test.go b/src/cmd/internal/buildid/buildid_test.go index 904c2c6f37..e832f9987e 100644 --- a/src/cmd/internal/buildid/buildid_test.go +++ b/src/cmd/internal/buildid/buildid_test.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "os" "reflect" + "strings" "testing" ) @@ -146,3 +147,33 @@ func TestFindAndHash(t *testing.T) { } } } + +func TestExcludedReader(t *testing.T) { + const s = "0123456789abcdefghijklmn" + tests := []struct { + start, end int64 // excluded range + results []string // expected results of reads + }{ + {12, 15, []string{"0123456789", "ab\x00\x00\x00fghij", "klmn"}}, // within one read + {8, 21, []string{"01234567\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00lmn"}}, // across multiple reads + {10, 20, []string{"0123456789", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "klmn"}}, // a whole read + {0, 5, []string{"\x00\x00\x00\x00\x0056789", "abcdefghij", "klmn"}}, // start + {12, 24, []string{"0123456789", "ab\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00"}}, // end + } + p := make([]byte, 10) + for _, test := range tests { + r := &excludedReader{strings.NewReader(s), 0, test.start, test.end} + for _, res := range test.results { + n, err := r.Read(p) + if err != nil { + t.Errorf("read failed: %v", err) + } + if n != len(res) { + t.Errorf("unexpected number of bytes read: want %d, got %d", len(res), n) + } + if string(p[:n]) != res { + t.Errorf("unexpected bytes: want %q, got %q", res, p[:n]) + } + } + } +} diff --git a/src/cmd/internal/buildid/note.go b/src/cmd/internal/buildid/note.go index 2d26ea9961..f5b6fc565f 100644 --- a/src/cmd/internal/buildid/note.go +++ b/src/cmd/internal/buildid/note.go @@ -11,6 +11,7 @@ import ( "encoding/binary" "fmt" "io" + "io/fs" "os" ) @@ -96,7 +97,7 @@ func readELF(name string, f *os.File, data []byte) (buildid string, err error) { ef, err := elf.NewFile(bytes.NewReader(data)) if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} + return "", &fs.PathError{Path: name, Op: "parse", Err: err} } var gnu string for _, p := range ef.Progs { @@ -181,13 +182,13 @@ func readMacho(name string, f *os.File, data []byte) (buildid string, err error) mf, err := macho.NewFile(f) if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} + return "", &fs.PathError{Path: name, Op: "parse", Err: err} } sect := mf.Section("__text") if sect == nil { // Every binary has a __text section. Something is wrong. - return "", &os.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")} + return "", &fs.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")} } // It should be in the first few bytes, but read a lot just in case, diff --git a/src/cmd/internal/buildid/rewrite.go b/src/cmd/internal/buildid/rewrite.go index 5be54552a6..a7928959c4 100644 --- a/src/cmd/internal/buildid/rewrite.go +++ b/src/cmd/internal/buildid/rewrite.go @@ -6,7 +6,9 @@ package buildid import ( "bytes" + "cmd/internal/codesign" "crypto/sha256" + "debug/macho" "fmt" "io" ) @@ -26,6 +28,11 @@ func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32 zeros := make([]byte, len(id)) idBytes := []byte(id) + // For Mach-O files, we want to exclude the code signature. + // The code signature contains hashes of the whole file (except the signature + // itself), including the buildid. So the buildid cannot contain the signature. + r = excludeMachoCodeSignature(r) + // The strategy is to read the file through buf, looking for id, // but we need to worry about what happens if id is broken up // and returned in parts by two different reads. @@ -87,5 +94,69 @@ func Rewrite(w io.WriterAt, pos []int64, id string) error { return err } } + + // Update Mach-O code signature, if any. + if f, cmd, ok := findMachoCodeSignature(w); ok { + if codesign.Size(int64(cmd.Dataoff), "a.out") == int64(cmd.Datasize) { + // Update the signature if the size matches, so we don't need to + // fix up headers. Binaries generated by the Go linker should have + // the expected size. Otherwise skip. + text := f.Segment("__TEXT") + cs := make([]byte, cmd.Datasize) + codesign.Sign(cs, w.(io.Reader), "a.out", int64(cmd.Dataoff), int64(text.Offset), int64(text.Filesz), f.Type == macho.TypeExec) + if _, err := w.WriteAt(cs, int64(cmd.Dataoff)); err != nil { + return err + } + } + } + return nil } + +func excludeMachoCodeSignature(r io.Reader) io.Reader { + _, cmd, ok := findMachoCodeSignature(r) + if !ok { + return r + } + return &excludedReader{r, 0, int64(cmd.Dataoff), int64(cmd.Dataoff + cmd.Datasize)} +} + +// excludedReader wraps an io.Reader. Reading from it returns the bytes from +// the underlying reader, except that when the byte offset is within the +// range between start and end, it returns zero bytes. +type excludedReader struct { + r io.Reader + off int64 // current offset + start, end int64 // the range to be excluded (read as zero) +} + +func (r *excludedReader) Read(p []byte) (int, error) { + n, err := r.r.Read(p) + if n > 0 && r.off+int64(n) > r.start && r.off < r.end { + cstart := r.start - r.off + if cstart < 0 { + cstart = 0 + } + cend := r.end - r.off + if cend > int64(n) { + cend = int64(n) + } + zeros := make([]byte, cend-cstart) + copy(p[cstart:cend], zeros) + } + r.off += int64(n) + return n, err +} + +func findMachoCodeSignature(r interface{}) (*macho.File, codesign.CodeSigCmd, bool) { + ra, ok := r.(io.ReaderAt) + if !ok { + return nil, codesign.CodeSigCmd{}, false + } + f, err := macho.NewFile(ra) + if err != nil { + return nil, codesign.CodeSigCmd{}, false + } + cmd, ok := codesign.FindCodeSigCmd(f) + return f, cmd, ok +} diff --git a/src/cmd/internal/codesign/codesign.go b/src/cmd/internal/codesign/codesign.go new file mode 100644 index 0000000000..0517a10640 --- /dev/null +++ b/src/cmd/internal/codesign/codesign.go @@ -0,0 +1,268 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package codesign provides basic functionalities for +// ad-hoc code signing of Mach-O files. +// +// This is not a general tool for code-signing. It is made +// specifically for the Go toolchain. It uses the same +// ad-hoc signing algorithm as the Darwin linker. +package codesign + +import ( + "crypto/sha256" + "debug/macho" + "encoding/binary" + "io" +) + +// Code signature layout. +// +// The code signature is a block of bytes that contains +// a SuperBlob, which contains one or more Blobs. For ad-hoc +// signing, a single CodeDirectory Blob suffices. +// +// A SuperBlob starts with its header (the binary representation +// of the SuperBlob struct), followed by a list of (in our case, +// one) Blobs (offset and size). A CodeDirectory Blob starts +// with its head (the binary representation of CodeDirectory struct), +// followed by the identifier (as a C string) and the hashes, at +// the corresponding offsets. +// +// The signature data must be included in the __LINKEDIT segment. +// In the Mach-O file header, an LC_CODE_SIGNATURE load command +// points to the data. + +const ( + pageSizeBits = 12 + pageSize = 1 << pageSizeBits +) + +const LC_CODE_SIGNATURE = 0x1d + +// Constants and struct layouts are from +// https://opensource.apple.com/source/xnu/xnu-4903.270.47/osfmk/kern/cs_blobs.h + +const ( + CSMAGIC_REQUIREMENT = 0xfade0c00 // single Requirement blob + CSMAGIC_REQUIREMENTS = 0xfade0c01 // Requirements vector (internal requirements) + CSMAGIC_CODEDIRECTORY = 0xfade0c02 // CodeDirectory blob + CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 // embedded form of signature data + CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1 // multi-arch collection of embedded signatures + + CSSLOT_CODEDIRECTORY = 0 // slot index for CodeDirectory +) + +const ( + CS_HASHTYPE_SHA1 = 1 + CS_HASHTYPE_SHA256 = 2 + CS_HASHTYPE_SHA256_TRUNCATED = 3 + CS_HASHTYPE_SHA384 = 4 +) + +const ( + CS_EXECSEG_MAIN_BINARY = 0x1 // executable segment denotes main binary + CS_EXECSEG_ALLOW_UNSIGNED = 0x10 // allow unsigned pages (for debugging) + CS_EXECSEG_DEBUGGER = 0x20 // main binary is debugger + CS_EXECSEG_JIT = 0x40 // JIT enabled + CS_EXECSEG_SKIP_LV = 0x80 // skip library validation + CS_EXECSEG_CAN_LOAD_CDHASH = 0x100 // can bless cdhash for execution + CS_EXECSEG_CAN_EXEC_CDHASH = 0x200 // can execute blessed cdhash +) + +type Blob struct { + typ uint32 // type of entry + offset uint32 // offset of entry + // data follows +} + +func (b *Blob) put(out []byte) []byte { + out = put32be(out, b.typ) + out = put32be(out, b.offset) + return out +} + +const blobSize = 2 * 4 + +type SuperBlob struct { + magic uint32 // magic number + length uint32 // total length of SuperBlob + count uint32 // number of index entries following + // blobs []Blob +} + +func (s *SuperBlob) put(out []byte) []byte { + out = put32be(out, s.magic) + out = put32be(out, s.length) + out = put32be(out, s.count) + return out +} + +const superBlobSize = 3 * 4 + +type CodeDirectory struct { + magic uint32 // magic number (CSMAGIC_CODEDIRECTORY) + length uint32 // total length of CodeDirectory blob + version uint32 // compatibility version + flags uint32 // setup and mode flags + hashOffset uint32 // offset of hash slot element at index zero + identOffset uint32 // offset of identifier string + nSpecialSlots uint32 // number of special hash slots + nCodeSlots uint32 // number of ordinary (code) hash slots + codeLimit uint32 // limit to main image signature range + hashSize uint8 // size of each hash in bytes + hashType uint8 // type of hash (cdHashType* constants) + _pad1 uint8 // unused (must be zero) + pageSize uint8 // log2(page size in bytes); 0 => infinite + _pad2 uint32 // unused (must be zero) + scatterOffset uint32 + teamOffset uint32 + _pad3 uint32 + codeLimit64 uint64 + execSegBase uint64 + execSegLimit uint64 + execSegFlags uint64 + // data follows +} + +func (c *CodeDirectory) put(out []byte) []byte { + out = put32be(out, c.magic) + out = put32be(out, c.length) + out = put32be(out, c.version) + out = put32be(out, c.flags) + out = put32be(out, c.hashOffset) + out = put32be(out, c.identOffset) + out = put32be(out, c.nSpecialSlots) + out = put32be(out, c.nCodeSlots) + out = put32be(out, c.codeLimit) + out = put8(out, c.hashSize) + out = put8(out, c.hashType) + out = put8(out, c._pad1) + out = put8(out, c.pageSize) + out = put32be(out, c._pad2) + out = put32be(out, c.scatterOffset) + out = put32be(out, c.teamOffset) + out = put32be(out, c._pad3) + out = put64be(out, c.codeLimit64) + out = put64be(out, c.execSegBase) + out = put64be(out, c.execSegLimit) + out = put64be(out, c.execSegFlags) + return out +} + +const codeDirectorySize = 13*4 + 4 + 4*8 + +// CodeSigCmd is Mach-O LC_CODE_SIGNATURE load command. +type CodeSigCmd struct { + Cmd uint32 // LC_CODE_SIGNATURE + Cmdsize uint32 // sizeof this command (16) + Dataoff uint32 // file offset of data in __LINKEDIT segment + Datasize uint32 // file size of data in __LINKEDIT segment +} + +func FindCodeSigCmd(f *macho.File) (CodeSigCmd, bool) { + get32 := f.ByteOrder.Uint32 + for _, l := range f.Loads { + data := l.Raw() + cmd := get32(data) + if cmd == LC_CODE_SIGNATURE { + return CodeSigCmd{ + cmd, + get32(data[4:]), + get32(data[8:]), + get32(data[12:]), + }, true + } + } + return CodeSigCmd{}, false +} + +func put32be(b []byte, x uint32) []byte { binary.BigEndian.PutUint32(b, x); return b[4:] } +func put64be(b []byte, x uint64) []byte { binary.BigEndian.PutUint64(b, x); return b[8:] } +func put8(b []byte, x uint8) []byte { b[0] = x; return b[1:] } +func puts(b, s []byte) []byte { n := copy(b, s); return b[n:] } + +// Size computes the size of the code signature. +// id is the identifier used for signing (a field in CodeDirectory blob, which +// has no significance in ad-hoc signing). +func Size(codeSize int64, id string) int64 { + nhashes := (codeSize + pageSize - 1) / pageSize + idOff := int64(codeDirectorySize) + hashOff := idOff + int64(len(id)+1) + cdirSz := hashOff + nhashes*sha256.Size + return int64(superBlobSize+blobSize) + cdirSz +} + +// Sign generates an ad-hoc code signature and writes it to out. +// out must have length at least Size(codeSize, id). +// data is the file content without the signature, of size codeSize. +// textOff and textSize is the file offset and size of the text segment. +// isMain is true if this is a main executable. +// id is the identifier used for signing (a field in CodeDirectory blob, which +// has no significance in ad-hoc signing). +func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int64, isMain bool) { + nhashes := (codeSize + pageSize - 1) / pageSize + idOff := int64(codeDirectorySize) + hashOff := idOff + int64(len(id)+1) + sz := Size(codeSize, id) + + // emit blob headers + sb := SuperBlob{ + magic: CSMAGIC_EMBEDDED_SIGNATURE, + length: uint32(sz), + count: 1, + } + blob := Blob{ + typ: CSSLOT_CODEDIRECTORY, + offset: superBlobSize + blobSize, + } + cdir := CodeDirectory{ + magic: CSMAGIC_CODEDIRECTORY, + length: uint32(sz) - (superBlobSize + blobSize), + version: 0x20400, + flags: 0x20002, // adhoc | linkerSigned + hashOffset: uint32(hashOff), + identOffset: uint32(idOff), + nCodeSlots: uint32(nhashes), + codeLimit: uint32(codeSize), + hashSize: sha256.Size, + hashType: CS_HASHTYPE_SHA256, + pageSize: uint8(pageSizeBits), + execSegBase: uint64(textOff), + execSegLimit: uint64(textSize), + } + if isMain { + cdir.execSegFlags = CS_EXECSEG_MAIN_BINARY + } + + outp := out + outp = sb.put(outp) + outp = blob.put(outp) + outp = cdir.put(outp) + + // emit the identifier + outp = puts(outp, []byte(id+"\000")) + + // emit hashes + var buf [pageSize]byte + h := sha256.New() + p := 0 + for p < int(codeSize) { + n, err := io.ReadFull(data, buf[:]) + if err == io.EOF { + break + } + if err != nil && err != io.ErrUnexpectedEOF { + panic(err) + } + if p+n > int(codeSize) { + n = int(codeSize) - p + } + p += n + h.Reset() + h.Write(buf[:n]) + b := h.Sum(nil) + outp = puts(outp, b[:]) + } +} diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index 6ab83639ac..e1a70ef853 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -101,26 +101,26 @@ func EnableLogging(doit bool) { logDwarf = doit } -// UnifyRanges merges the list of ranges of c into the list of ranges of s -func (s *Scope) UnifyRanges(c *Scope) { - out := make([]Range, 0, len(s.Ranges)+len(c.Ranges)) - +// MergeRanges creates a new range list by merging the ranges from +// its two arguments, then returns the new list. +func MergeRanges(in1, in2 []Range) []Range { + out := make([]Range, 0, len(in1)+len(in2)) i, j := 0, 0 for { var cur Range - if i < len(s.Ranges) && j < len(c.Ranges) { - if s.Ranges[i].Start < c.Ranges[j].Start { - cur = s.Ranges[i] + if i < len(in2) && j < len(in1) { + if in2[i].Start < in1[j].Start { + cur = in2[i] i++ } else { - cur = c.Ranges[j] + cur = in1[j] j++ } - } else if i < len(s.Ranges) { - cur = s.Ranges[i] + } else if i < len(in2) { + cur = in2[i] i++ - } else if j < len(c.Ranges) { - cur = c.Ranges[j] + } else if j < len(in1) { + cur = in1[j] j++ } else { break @@ -133,7 +133,12 @@ func (s *Scope) UnifyRanges(c *Scope) { } } - s.Ranges = out + return out +} + +// UnifyRanges merges the ranges from 'c' into the list of ranges for 's'. +func (s *Scope) UnifyRanges(c *Scope) { + s.Ranges = MergeRanges(s.Ranges, c.Ranges) } // AppendRange adds r to s, if r is non-empty. @@ -378,7 +383,7 @@ func expandPseudoForm(form uint8) uint8 { return form } expandedForm := DW_FORM_udata - if objabi.GOOS == "darwin" { + if objabi.GOOS == "darwin" || objabi.GOOS == "ios" { expandedForm = DW_FORM_data4 } return uint8(expandedForm) diff --git a/src/cmd/internal/goobj/funcinfo.go b/src/cmd/internal/goobj/funcinfo.go index e0e6068b4b..2cca8f6c4e 100644 --- a/src/cmd/internal/goobj/funcinfo.go +++ b/src/cmd/internal/goobj/funcinfo.go @@ -23,12 +23,11 @@ type FuncInfo struct { Locals uint32 FuncID objabi.FuncID - Pcsp uint32 - Pcfile uint32 - Pcline uint32 - Pcinline uint32 - Pcdata []uint32 - PcdataEnd uint32 + Pcsp SymRef + Pcfile SymRef + Pcline SymRef + Pcinline SymRef + Pcdata []SymRef Funcdataoff []uint32 File []CUFileIndex @@ -41,20 +40,24 @@ func (a *FuncInfo) Write(w *bytes.Buffer) { binary.LittleEndian.PutUint32(b[:], x) w.Write(b[:]) } + writeSymRef := func(s SymRef) { + writeUint32(s.PkgIdx) + writeUint32(s.SymIdx) + } writeUint32(a.Args) writeUint32(a.Locals) writeUint32(uint32(a.FuncID)) - writeUint32(a.Pcsp) - writeUint32(a.Pcfile) - writeUint32(a.Pcline) - writeUint32(a.Pcinline) + writeSymRef(a.Pcsp) + writeSymRef(a.Pcfile) + writeSymRef(a.Pcline) + writeSymRef(a.Pcinline) writeUint32(uint32(len(a.Pcdata))) - for _, x := range a.Pcdata { - writeUint32(x) + for _, sym := range a.Pcdata { + writeSymRef(sym) } - writeUint32(a.PcdataEnd) + writeUint32(uint32(len(a.Funcdataoff))) for _, x := range a.Funcdataoff { writeUint32(x) @@ -75,21 +78,23 @@ func (a *FuncInfo) Read(b []byte) { b = b[4:] return x } + readSymIdx := func() SymRef { + return SymRef{readUint32(), readUint32()} + } a.Args = readUint32() a.Locals = readUint32() a.FuncID = objabi.FuncID(readUint32()) - a.Pcsp = readUint32() - a.Pcfile = readUint32() - a.Pcline = readUint32() - a.Pcinline = readUint32() - pcdatalen := readUint32() - a.Pcdata = make([]uint32, pcdatalen) + a.Pcsp = readSymIdx() + a.Pcfile = readSymIdx() + a.Pcline = readSymIdx() + a.Pcinline = readSymIdx() + a.Pcdata = make([]SymRef, readUint32()) for i := range a.Pcdata { - a.Pcdata[i] = readUint32() + a.Pcdata[i] = readSymIdx() } - a.PcdataEnd = readUint32() + funcdataofflen := readUint32() a.Funcdataoff = make([]uint32, funcdataofflen) for i := range a.Funcdataoff { @@ -127,11 +132,13 @@ type FuncInfoLengths struct { func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths { var result FuncInfoLengths - const numpcdataOff = 28 + // Offset to the number of pcdata values. This value is determined by counting + // the number of bytes until we write pcdata to the file. + const numpcdataOff = 44 result.NumPcdata = binary.LittleEndian.Uint32(b[numpcdataOff:]) result.PcdataOff = numpcdataOff + 4 - numfuncdataoffOff := result.PcdataOff + 4*(result.NumPcdata+1) + numfuncdataoffOff := result.PcdataOff + 8*result.NumPcdata result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:]) result.FuncdataoffOff = numfuncdataoffOff + 4 @@ -154,29 +161,28 @@ func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32 func (*FuncInfo) ReadFuncID(b []byte) uint32 { return binary.LittleEndian.Uint32(b[8:]) } -// return start and end offsets. -func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:]) +func (*FuncInfo) ReadPcsp(b []byte) SymRef { + return SymRef{binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])} } -// return start and end offsets. -func (*FuncInfo) ReadPcfile(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:]) +func (*FuncInfo) ReadPcfile(b []byte) SymRef { + return SymRef{binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[24:])} } -// return start and end offsets. -func (*FuncInfo) ReadPcline(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[24:]) +func (*FuncInfo) ReadPcline(b []byte) SymRef { + return SymRef{binary.LittleEndian.Uint32(b[28:]), binary.LittleEndian.Uint32(b[32:])} } -// return start and end offsets. -func (*FuncInfo) ReadPcinline(b []byte, pcdataoffset uint32) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[24:]), binary.LittleEndian.Uint32(b[pcdataoffset:]) +func (*FuncInfo) ReadPcinline(b []byte) SymRef { + return SymRef{binary.LittleEndian.Uint32(b[36:]), binary.LittleEndian.Uint32(b[40:])} } -// return start and end offsets. -func (*FuncInfo) ReadPcdata(b []byte, pcdataoffset uint32, k uint32) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[pcdataoffset+4*k:]), binary.LittleEndian.Uint32(b[pcdataoffset+4+4*k:]) +func (*FuncInfo) ReadPcdata(b []byte) []SymRef { + syms := make([]SymRef, binary.LittleEndian.Uint32(b[44:])) + for i := range syms { + syms[i] = SymRef{binary.LittleEndian.Uint32(b[48+i*8:]), binary.LittleEndian.Uint32(b[52+i*8:])} + } + return syms } func (*FuncInfo) ReadFuncdataoff(b []byte, funcdataofffoff uint32, k uint32) int64 { diff --git a/src/cmd/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go index 8ec7c481d6..6e76bea111 100644 --- a/src/cmd/internal/goobj/objfile.go +++ b/src/cmd/internal/goobj/objfile.go @@ -433,8 +433,11 @@ const ( AuxDwarfLoc AuxDwarfRanges AuxDwarfLines - - // TODO: more. Pcdata? + AuxPcsp + AuxPcfile + AuxPcline + AuxPcinline + AuxPcdata ) func (a *Aux) Type() uint8 { return a[0] } @@ -839,11 +842,6 @@ func (r *Reader) Data(i uint32) []byte { return r.BytesAt(base+off, int(end-off)) } -// AuxDataBase returns the base offset of the aux data block. -func (r *Reader) PcdataBase() uint32 { - return r.h.Offsets[BlkPcdata] -} - // NRefName returns the number of referenced symbol names. func (r *Reader) NRefName() int { return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go index 2e6167322e..9ea21873c5 100644 --- a/src/cmd/internal/moddeps/moddeps_test.go +++ b/src/cmd/internal/moddeps/moddeps_test.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "internal/testenv" + "io/fs" "io/ioutil" "os" "os/exec" @@ -32,7 +33,7 @@ func findGorootModules(t *testing.T) []gorootModule { goBin := testenv.GoToolPath(t) goroot.once.Do(func() { - goroot.err = filepath.Walk(runtime.GOROOT(), func(path string, info os.FileInfo, err error) error { + goroot.err = filepath.WalkDir(runtime.GOROOT(), func(path string, info fs.DirEntry, err error) error { if err != nil { return err } diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index 269a4223d5..ebb98b4859 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -390,7 +390,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { var p *obj.Prog var op *obj.Prog - p = cursym.Func.Text + p = cursym.Func().Text if p == nil || p.Link == nil { // handle external functions and ELF section symbols return } @@ -482,8 +482,8 @@ func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { bflag = 0 pc = 0 times++ - c.cursym.Func.Text.Pc = 0 // force re-layout the code. - for p = c.cursym.Func.Text; p != nil; p = p.Link { + c.cursym.Func().Text.Pc = 0 // force re-layout the code. + for p = c.cursym.Func().Text; p != nil; p = p.Link { o = c.oplook(p) if int64(pc) > p.Pc { p.Pc = int64(pc) @@ -558,7 +558,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { * perhaps we'd be able to parallelize the span loop above. */ - p = c.cursym.Func.Text + p = c.cursym.Func().Text c.autosize = p.To.Offset + 4 c.cursym.Grow(c.cursym.Size) diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index 4d9187b530..29d3a5867d 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -249,13 +249,13 @@ const ( func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { autosize := int32(0) - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } c := ctxt5{ctxt: ctxt, cursym: cursym, newprog: newprog} - p := c.cursym.Func.Text + p := c.cursym.Func().Text autoffset := int32(p.To.Offset) if autoffset == -4 { // Historical way to mark NOFRAME. @@ -271,30 +271,30 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - cursym.Func.Locals = autoffset - cursym.Func.Args = p.To.Val.(int32) + cursym.Func().Locals = autoffset + cursym.Func().Args = p.To.Val.(int32) /* * find leaf subroutines */ - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case obj.ATEXT: p.Mark |= LEAF case ADIV, ADIVU, AMOD, AMODU: - cursym.Func.Text.Mark &^= LEAF + cursym.Func().Text.Mark &^= LEAF case ABL, ABX, obj.ADUFFZERO, obj.ADUFFCOPY: - cursym.Func.Text.Mark &^= LEAF + cursym.Func().Text.Mark &^= LEAF } } var q2 *obj.Prog - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { o := p.As switch o { case obj.ATEXT: @@ -311,20 +311,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { autosize += 4 } - if autosize == 0 && cursym.Func.Text.Mark&LEAF == 0 { + if autosize == 0 && cursym.Func().Text.Mark&LEAF == 0 { // A very few functions that do not return to their caller // are not identified as leaves but still have no frame. if ctxt.Debugvlog { ctxt.Logf("save suppressed in: %s\n", cursym.Name) } - cursym.Func.Text.Mark |= LEAF + cursym.Func().Text.Mark |= LEAF } // FP offsets need an updated p.To.Offset. p.To.Offset = int64(autosize) - 4 - if cursym.Func.Text.Mark&LEAF != 0 { + if cursym.Func().Text.Mark&LEAF != 0 { cursym.Set(obj.AttrLeaf, true) if p.From.Sym.NoFrame() { break @@ -347,7 +347,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Reg = REGSP p.Spadj = autosize - if cursym.Func.Text.From.Sym.Wrapper() { + if cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVW g_panic(g), R1 @@ -460,7 +460,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { case obj.ARET: nocache(p) - if cursym.Func.Text.Mark&LEAF != 0 { + if cursym.Func().Text.Mark&LEAF != 0 { if autosize == 0 { p.As = AB p.From = obj.Addr{} @@ -487,6 +487,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // If there are instructions following // this ARET, they come from a branch // with the same stackframe, so no spadj. + if p.To.Sym != nil { // retjmp p.To.Reg = REGLINK q2 = obj.Appendp(p, newprog) @@ -494,6 +495,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q2.To.Type = obj.TYPE_BRANCH q2.To.Sym = p.To.Sym p.To.Sym = nil + p.To.Name = obj.NAME_NONE p = q2 } @@ -508,7 +510,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } case ADIV, ADIVU, AMOD, AMODU: - if cursym.Func.Text.From.Sym.NoSplit() { + if cursym.Func().Text.From.Sym.NoSplit() { ctxt.Diag("cannot divide in NOSPLIT function") } const debugdivmod = false @@ -720,7 +722,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { end := c.ctxt.EndUnsafePoint(bls, c.newprog, -1) var last *obj.Prog - for last = c.cursym.Func.Text; last.Link != nil; last = last.Link { + for last = c.cursym.Func().Text; last.Link != nil; last = last.Link { } // Now we are at the end of the function, but logically @@ -751,7 +753,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { switch { case c.cursym.CFunc(): morestack = "runtime.morestackc" - case !c.cursym.Func.Text.From.Sym.NeedCtxt(): + case !c.cursym.Func().Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = c.ctxt.Lookup(morestack) @@ -762,7 +764,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { b := obj.Appendp(pcdata, c.newprog) b.As = obj.AJMP b.To.Type = obj.TYPE_BRANCH - b.To.SetTarget(c.cursym.Func.Text.Link) + b.To.SetTarget(c.cursym.Func().Text.Link) b.Spadj = +framesize return end diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go index 03e0278a33..1d1bea505c 100644 --- a/src/cmd/internal/obj/arm64/a.out.go +++ b/src/cmd/internal/obj/arm64/a.out.go @@ -410,35 +410,42 @@ const ( C_FCON // floating-point constant C_VCONADDR // 64-bit memory address - C_AACON // ADDCON offset in auto constant $a(FP) - C_LACON // 32-bit offset in auto constant $a(FP) - C_AECON // ADDCON offset in extern constant $e(SB) + C_AACON // ADDCON offset in auto constant $a(FP) + C_AACON2 // 24-bit offset in auto constant $a(FP) + C_LACON // 32-bit offset in auto constant $a(FP) + C_AECON // ADDCON offset in extern constant $e(SB) // TODO(aram): only one branch class should be enough C_SBRA // for TYPE_BRANCH C_LBRA - C_ZAUTO // 0(RSP) - C_NSAUTO_8 // -256 <= x < 0, 0 mod 8 - C_NSAUTO_4 // -256 <= x < 0, 0 mod 4 - C_NSAUTO // -256 <= x < 0 - C_NPAUTO // -512 <= x < 0, 0 mod 8 - C_NAUTO4K // -4095 <= x < 0 - C_PSAUTO_8 // 0 to 255, 0 mod 8 - C_PSAUTO_4 // 0 to 255, 0 mod 4 - C_PSAUTO // 0 to 255 - C_PPAUTO // 0 to 504, 0 mod 8 - C_UAUTO4K_8 // 0 to 4095, 0 mod 8 - C_UAUTO4K_4 // 0 to 4095, 0 mod 4 - C_UAUTO4K_2 // 0 to 4095, 0 mod 2 - C_UAUTO4K // 0 to 4095 - C_UAUTO8K_8 // 0 to 8190, 0 mod 8 - C_UAUTO8K_4 // 0 to 8190, 0 mod 4 - C_UAUTO8K // 0 to 8190, 0 mod 2 - C_UAUTO16K_8 // 0 to 16380, 0 mod 8 - C_UAUTO16K // 0 to 16380, 0 mod 4 - C_UAUTO32K // 0 to 32760, 0 mod 8 - C_LAUTO // any other 32-bit constant + C_ZAUTO // 0(RSP) + C_NSAUTO_8 // -256 <= x < 0, 0 mod 8 + C_NSAUTO_4 // -256 <= x < 0, 0 mod 4 + C_NSAUTO // -256 <= x < 0 + C_NPAUTO // -512 <= x < 0, 0 mod 8 + C_NAUTO4K // -4095 <= x < 0 + C_PSAUTO_8 // 0 to 255, 0 mod 8 + C_PSAUTO_4 // 0 to 255, 0 mod 4 + C_PSAUTO // 0 to 255 + C_PPAUTO_16 // 0 to 504, 0 mod 16 + C_PPAUTO // 0 to 504, 0 mod 8 + C_UAUTO4K_16 // 0 to 4095, 0 mod 16 + C_UAUTO4K_8 // 0 to 4095, 0 mod 8 + C_UAUTO4K_4 // 0 to 4095, 0 mod 4 + C_UAUTO4K_2 // 0 to 4095, 0 mod 2 + C_UAUTO4K // 0 to 4095 + C_UAUTO8K_16 // 0 to 8190, 0 mod 16 + C_UAUTO8K_8 // 0 to 8190, 0 mod 8 + C_UAUTO8K_4 // 0 to 8190, 0 mod 4 + C_UAUTO8K // 0 to 8190, 0 mod 2 + C_PSAUTO + C_UAUTO16K_16 // 0 to 16380, 0 mod 16 + C_UAUTO16K_8 // 0 to 16380, 0 mod 8 + C_UAUTO16K // 0 to 16380, 0 mod 4 + C_PSAUTO + C_UAUTO32K_16 // 0 to 32760, 0 mod 16 + C_PSAUTO + C_UAUTO32K // 0 to 32760, 0 mod 8 + C_PSAUTO + C_UAUTO64K // 0 to 65520, 0 mod 16 + C_PSAUTO + C_LAUTO // any other 32-bit constant C_SEXT1 // 0 to 4095, direct C_SEXT2 // 0 to 8190 @@ -456,17 +463,23 @@ const ( C_PSOREG_8 C_PSOREG_4 C_PSOREG + C_PPOREG_16 C_PPOREG + C_UOREG4K_16 C_UOREG4K_8 C_UOREG4K_4 C_UOREG4K_2 C_UOREG4K + C_UOREG8K_16 C_UOREG8K_8 C_UOREG8K_4 C_UOREG8K + C_UOREG16K_16 C_UOREG16K_8 C_UOREG16K + C_UOREG32K_16 C_UOREG32K + C_UOREG64K C_LOREG C_ADDR // TODO(aram): explain difference from C_VCONADDR @@ -604,22 +617,6 @@ const ( ALDADDLD ALDADDLH ALDADDLW - ALDANDAB - ALDANDAD - ALDANDAH - ALDANDAW - ALDANDALB - ALDANDALD - ALDANDALH - ALDANDALW - ALDANDB - ALDANDD - ALDANDH - ALDANDW - ALDANDLB - ALDANDLD - ALDANDLH - ALDANDLW ALDAR ALDARB ALDARH @@ -630,6 +627,22 @@ const ( ALDAXRB ALDAXRH ALDAXRW + ALDCLRAB + ALDCLRAD + ALDCLRAH + ALDCLRAW + ALDCLRALB + ALDCLRALD + ALDCLRALH + ALDCLRALW + ALDCLRB + ALDCLRD + ALDCLRH + ALDCLRW + ALDCLRLB + ALDCLRLD + ALDCLRLH + ALDCLRLW ALDEORAB ALDEORAD ALDEORAH @@ -830,6 +843,20 @@ const ( ASWPLW ASWPLH ASWPLB + ACASD + ACASW + ACASH + ACASB + ACASAD + ACASAW + ACASLD + ACASLW + ACASALD + ACASALW + ACASALH + ACASALB + ACASPD + ACASPW ABEQ ABNE ABCS @@ -872,8 +899,12 @@ const ( AFDIVS AFLDPD AFLDPS + AFMOVQ AFMOVD AFMOVS + AVMOVQ + AVMOVD + AVMOVS AFMULD AFMULS AFNEGD @@ -953,9 +984,12 @@ const ( AVADD AVADDP AVAND + AVBIF + AVBCAX AVCMEQ AVCNT AVEOR + AVEOR3 AVMOV AVLD1 AVLD2 @@ -984,12 +1018,27 @@ const ( AVPMULL2 AVEXT AVRBIT + AVRAX1 AVUSHR + AVUSHLL + AVUSHLL2 + AVUXTL + AVUXTL2 + AVUZP1 + AVUZP2 AVSHL AVSRI + AVSLI + AVBSL + AVBIT AVTBL + AVXAR AVZIP1 AVZIP2 + AVCMTST + AVUADDW2 + AVUADDW + AVUSRA ALAST AB = obj.AJMP ABL = obj.ACALL diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go index 65ecd007ea..a98f8c7ed5 100644 --- a/src/cmd/internal/obj/arm64/anames.go +++ b/src/cmd/internal/obj/arm64/anames.go @@ -111,22 +111,6 @@ var Anames = []string{ "LDADDLD", "LDADDLH", "LDADDLW", - "LDANDAB", - "LDANDAD", - "LDANDAH", - "LDANDAW", - "LDANDALB", - "LDANDALD", - "LDANDALH", - "LDANDALW", - "LDANDB", - "LDANDD", - "LDANDH", - "LDANDW", - "LDANDLB", - "LDANDLD", - "LDANDLH", - "LDANDLW", "LDAR", "LDARB", "LDARH", @@ -137,6 +121,22 @@ var Anames = []string{ "LDAXRB", "LDAXRH", "LDAXRW", + "LDCLRAB", + "LDCLRAD", + "LDCLRAH", + "LDCLRAW", + "LDCLRALB", + "LDCLRALD", + "LDCLRALH", + "LDCLRALW", + "LDCLRB", + "LDCLRD", + "LDCLRH", + "LDCLRW", + "LDCLRLB", + "LDCLRLD", + "LDCLRLH", + "LDCLRLW", "LDEORAB", "LDEORAD", "LDEORAH", @@ -337,6 +337,20 @@ var Anames = []string{ "SWPLW", "SWPLH", "SWPLB", + "CASD", + "CASW", + "CASH", + "CASB", + "CASAD", + "CASAW", + "CASLD", + "CASLW", + "CASALD", + "CASALW", + "CASALH", + "CASALB", + "CASPD", + "CASPW", "BEQ", "BNE", "BCS", @@ -379,8 +393,12 @@ var Anames = []string{ "FDIVS", "FLDPD", "FLDPS", + "FMOVQ", "FMOVD", "FMOVS", + "VMOVQ", + "VMOVD", + "VMOVS", "FMULD", "FMULS", "FNEGD", @@ -460,9 +478,12 @@ var Anames = []string{ "VADD", "VADDP", "VAND", + "VBIF", + "VBCAX", "VCMEQ", "VCNT", "VEOR", + "VEOR3", "VMOV", "VLD1", "VLD2", @@ -491,11 +512,26 @@ var Anames = []string{ "VPMULL2", "VEXT", "VRBIT", + "VRAX1", "VUSHR", + "VUSHLL", + "VUSHLL2", + "VUXTL", + "VUXTL2", + "VUZP1", + "VUZP2", "VSHL", "VSRI", + "VSLI", + "VBSL", + "VBIT", "VTBL", + "VXAR", "VZIP1", "VZIP2", + "VCMTST", + "VUADDW2", + "VUADDW", + "VUSRA", "LAST", } diff --git a/src/cmd/internal/obj/arm64/anames7.go b/src/cmd/internal/obj/arm64/anames7.go index e1703fc4ab..f7e99517ce 100644 --- a/src/cmd/internal/obj/arm64/anames7.go +++ b/src/cmd/internal/obj/arm64/anames7.go @@ -36,6 +36,7 @@ var cnames7 = []string{ "FCON", "VCONADDR", "AACON", + "AACON2", "LACON", "AECON", "SBRA", @@ -50,16 +51,21 @@ var cnames7 = []string{ "PSAUTO_4", "PSAUTO", "PPAUTO", + "UAUTO4K_16", "UAUTO4K_8", "UAUTO4K_4", "UAUTO4K_2", "UAUTO4K", + "UAUTO8K_16", "UAUTO8K_8", "UAUTO8K_4", "UAUTO8K", + "UAUTO16K_16", "UAUTO16K_8", "UAUTO16K", + "UAUTO32K_8", "UAUTO32K", + "UAUTO64K", "LAUTO", "SEXT1", "SEXT2", @@ -77,16 +83,21 @@ var cnames7 = []string{ "PSOREG_4", "PSOREG", "PPOREG", + "UOREG4K_16", "UOREG4K_8", "UOREG4K_4", "UOREG4K_2", "UOREG4K", + "UOREG8K_16", "UOREG8K_8", "UOREG8K_4", "UOREG8K", + "UOREG16K_16", "UOREG16K_8", "UOREG16K", + "UOREG32K_16", "UOREG32K", + "UOREG64K", "LOREG", "ADDR", "GOTADDR", diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 0b90e31392..1a359f1921 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -80,12 +80,17 @@ type Optab struct { } func IsAtomicInstruction(as obj.As) bool { - _, ok := atomicInstructions[as] - return ok + if _, ok := atomicLDADD[as]; ok { + return true + } + if _, ok := atomicSWP[as]; ok { + return true + } + return false } // known field values of an instruction. -var atomicInstructions = map[obj.As]uint32{ +var atomicLDADD = map[obj.As]uint32{ ALDADDAD: 3<<30 | 0x1c5<<21 | 0x00<<10, ALDADDAW: 2<<30 | 0x1c5<<21 | 0x00<<10, ALDADDAH: 1<<30 | 0x1c5<<21 | 0x00<<10, @@ -102,22 +107,22 @@ var atomicInstructions = map[obj.As]uint32{ ALDADDLW: 2<<30 | 0x1c3<<21 | 0x00<<10, ALDADDLH: 1<<30 | 0x1c3<<21 | 0x00<<10, ALDADDLB: 0<<30 | 0x1c3<<21 | 0x00<<10, - ALDANDAD: 3<<30 | 0x1c5<<21 | 0x04<<10, - ALDANDAW: 2<<30 | 0x1c5<<21 | 0x04<<10, - ALDANDAH: 1<<30 | 0x1c5<<21 | 0x04<<10, - ALDANDAB: 0<<30 | 0x1c5<<21 | 0x04<<10, - ALDANDALD: 3<<30 | 0x1c7<<21 | 0x04<<10, - ALDANDALW: 2<<30 | 0x1c7<<21 | 0x04<<10, - ALDANDALH: 1<<30 | 0x1c7<<21 | 0x04<<10, - ALDANDALB: 0<<30 | 0x1c7<<21 | 0x04<<10, - ALDANDD: 3<<30 | 0x1c1<<21 | 0x04<<10, - ALDANDW: 2<<30 | 0x1c1<<21 | 0x04<<10, - ALDANDH: 1<<30 | 0x1c1<<21 | 0x04<<10, - ALDANDB: 0<<30 | 0x1c1<<21 | 0x04<<10, - ALDANDLD: 3<<30 | 0x1c3<<21 | 0x04<<10, - ALDANDLW: 2<<30 | 0x1c3<<21 | 0x04<<10, - ALDANDLH: 1<<30 | 0x1c3<<21 | 0x04<<10, - ALDANDLB: 0<<30 | 0x1c3<<21 | 0x04<<10, + ALDCLRAD: 3<<30 | 0x1c5<<21 | 0x04<<10, + ALDCLRAW: 2<<30 | 0x1c5<<21 | 0x04<<10, + ALDCLRAH: 1<<30 | 0x1c5<<21 | 0x04<<10, + ALDCLRAB: 0<<30 | 0x1c5<<21 | 0x04<<10, + ALDCLRALD: 3<<30 | 0x1c7<<21 | 0x04<<10, + ALDCLRALW: 2<<30 | 0x1c7<<21 | 0x04<<10, + ALDCLRALH: 1<<30 | 0x1c7<<21 | 0x04<<10, + ALDCLRALB: 0<<30 | 0x1c7<<21 | 0x04<<10, + ALDCLRD: 3<<30 | 0x1c1<<21 | 0x04<<10, + ALDCLRW: 2<<30 | 0x1c1<<21 | 0x04<<10, + ALDCLRH: 1<<30 | 0x1c1<<21 | 0x04<<10, + ALDCLRB: 0<<30 | 0x1c1<<21 | 0x04<<10, + ALDCLRLD: 3<<30 | 0x1c3<<21 | 0x04<<10, + ALDCLRLW: 2<<30 | 0x1c3<<21 | 0x04<<10, + ALDCLRLH: 1<<30 | 0x1c3<<21 | 0x04<<10, + ALDCLRLB: 0<<30 | 0x1c3<<21 | 0x04<<10, ALDEORAD: 3<<30 | 0x1c5<<21 | 0x08<<10, ALDEORAW: 2<<30 | 0x1c5<<21 | 0x08<<10, ALDEORAH: 1<<30 | 0x1c5<<21 | 0x08<<10, @@ -150,22 +155,41 @@ var atomicInstructions = map[obj.As]uint32{ ALDORLW: 2<<30 | 0x1c3<<21 | 0x0c<<10, ALDORLH: 1<<30 | 0x1c3<<21 | 0x0c<<10, ALDORLB: 0<<30 | 0x1c3<<21 | 0x0c<<10, - ASWPAD: 3<<30 | 0x1c5<<21 | 0x20<<10, - ASWPAW: 2<<30 | 0x1c5<<21 | 0x20<<10, - ASWPAH: 1<<30 | 0x1c5<<21 | 0x20<<10, - ASWPAB: 0<<30 | 0x1c5<<21 | 0x20<<10, - ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10, - ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10, - ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10, - ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10, - ASWPD: 3<<30 | 0x1c1<<21 | 0x20<<10, - ASWPW: 2<<30 | 0x1c1<<21 | 0x20<<10, - ASWPH: 1<<30 | 0x1c1<<21 | 0x20<<10, - ASWPB: 0<<30 | 0x1c1<<21 | 0x20<<10, - ASWPLD: 3<<30 | 0x1c3<<21 | 0x20<<10, - ASWPLW: 2<<30 | 0x1c3<<21 | 0x20<<10, - ASWPLH: 1<<30 | 0x1c3<<21 | 0x20<<10, - ASWPLB: 0<<30 | 0x1c3<<21 | 0x20<<10, +} + +var atomicSWP = map[obj.As]uint32{ + ASWPAD: 3<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAW: 2<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAH: 1<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAB: 0<<30 | 0x1c5<<21 | 0x20<<10, + ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10, + ASWPD: 3<<30 | 0x1c1<<21 | 0x20<<10, + ASWPW: 2<<30 | 0x1c1<<21 | 0x20<<10, + ASWPH: 1<<30 | 0x1c1<<21 | 0x20<<10, + ASWPB: 0<<30 | 0x1c1<<21 | 0x20<<10, + ASWPLD: 3<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLW: 2<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLH: 1<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLB: 0<<30 | 0x1c3<<21 | 0x20<<10, + ACASD: 3<<30 | 0x45<<21 | 0x1f<<10, + ACASW: 2<<30 | 0x45<<21 | 0x1f<<10, + ACASH: 1<<30 | 0x45<<21 | 0x1f<<10, + ACASB: 0<<30 | 0x45<<21 | 0x1f<<10, + ACASAD: 3<<30 | 0x47<<21 | 0x1f<<10, + ACASAW: 2<<30 | 0x47<<21 | 0x1f<<10, + ACASLD: 3<<30 | 0x45<<21 | 0x3f<<10, + ACASLW: 2<<30 | 0x45<<21 | 0x3f<<10, + ACASALD: 3<<30 | 0x47<<21 | 0x3f<<10, + ACASALW: 2<<30 | 0x47<<21 | 0x3f<<10, + ACASALH: 1<<30 | 0x47<<21 | 0x3f<<10, + ACASALB: 0<<30 | 0x47<<21 | 0x3f<<10, +} +var atomicCASP = map[obj.As]uint32{ + ACASPD: 1<<30 | 0x41<<21 | 0x1f<<10, + ACASPW: 0<<30 | 0x41<<21 | 0x1f<<10, } var oprange [ALAST & obj.AMask][]Optab @@ -205,12 +229,8 @@ func SYSHINT(x uint32) uint32 { return SYSOP(0, 0, 3, 2, 0, x, 0x1F) } -func LDSTR12U(sz uint32, v uint32, opc uint32) uint32 { - return sz<<30 | 7<<27 | v<<26 | 1<<24 | opc<<22 -} - -func LDSTR9S(sz uint32, v uint32, opc uint32) uint32 { - return sz<<30 | 7<<27 | v<<26 | 0<<24 | opc<<22 +func LDSTR(sz uint32, v uint32, opc uint32) uint32 { + return sz<<30 | 7<<27 | v<<26 | opc<<22 } func LD2STR(o uint32) uint32 { @@ -260,8 +280,9 @@ func MOVCONST(d int64, s int, rt int) uint32 { const ( // Optab.flag LFROM = 1 << 0 // p.From uses constant pool - LTO = 1 << 1 // p.To uses constant pool - NOTUSETMP = 1 << 2 // p expands to multiple instructions, but does NOT use REGTMP + LFROM3 = 1 << 1 // p.From3 uses constant pool + LTO = 1 << 2 // p.To uses constant pool + NOTUSETMP = 1 << 3 // p expands to multiple instructions, but does NOT use REGTMP ) var optab = []Optab{ @@ -391,7 +412,16 @@ var optab = []Optab{ {AMOVD, C_VCON, C_NONE, C_NONE, C_REG, 12, 16, 0, NOTUSETMP, 0}, {AMOVK, C_VCON, C_NONE, C_NONE, C_REG, 33, 4, 0, 0, 0}, - {AMOVD, C_AACON, C_NONE, C_NONE, C_REG, 4, 4, REGFROM, 0, 0}, + {AMOVD, C_AACON, C_NONE, C_NONE, C_RSP, 4, 4, REGFROM, 0, 0}, + {AMOVD, C_AACON2, C_NONE, C_NONE, C_RSP, 4, 8, REGFROM, 0, 0}, + + /* load long effective stack address (load int32 offset and add) */ + {AMOVD, C_LACON, C_NONE, C_NONE, C_RSP, 34, 8, REGSP, LFROM, 0}, + + // Move a large constant to a vector register. + {AVMOVQ, C_VCON, C_NONE, C_VCON, C_VREG, 101, 4, 0, LFROM | LFROM3, 0}, + {AVMOVD, C_VCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0}, + {AVMOVS, C_LCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0}, /* jump operations */ {AB, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, @@ -403,12 +433,14 @@ var optab = []Optab{ {obj.ARET, C_NONE, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0}, {obj.ARET, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0}, {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 7, 4, 0, 0, 0}, - {AADRP, C_SBRA, C_NONE, C_NONE, C_REG, 60, 4, 0, 0, 0}, - {AADR, C_SBRA, C_NONE, C_NONE, C_REG, 61, 4, 0, 0, 0}, {ACBZ, C_REG, C_NONE, C_NONE, C_SBRA, 39, 4, 0, 0, 0}, {ATBZ, C_VCON, C_REG, C_NONE, C_SBRA, 40, 4, 0, 0, 0}, {AERET, C_NONE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0}, + // get a PC-relative address + {AADRP, C_SBRA, C_NONE, C_NONE, C_REG, 60, 4, 0, 0, 0}, + {AADR, C_SBRA, C_NONE, C_NONE, C_REG, 61, 4, 0, 0, 0}, + {ACLREX, C_NONE, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0}, {ACLREX, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0}, {ABFM, C_VCON, C_REG, C_VCON, C_REG, 42, 4, 0, 0, 0}, @@ -473,6 +505,9 @@ var optab = []Optab{ {AVTBL, C_ARNG, C_NONE, C_LIST, C_ARNG, 100, 4, 0, 0, 0}, {AVUSHR, C_VCON, C_ARNG, C_NONE, C_ARNG, 95, 4, 0, 0, 0}, {AVZIP1, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0}, + {AVUSHLL, C_VCON, C_ARNG, C_NONE, C_ARNG, 102, 4, 0, 0, 0}, + {AVUXTL, C_ARNG, C_NONE, C_NONE, C_ARNG, 102, 4, 0, 0, 0}, + {AVUADDW, C_ARNG, C_ARNG, C_NONE, C_ARNG, 105, 4, 0, 0, 0}, /* conditional operations */ {ACSEL, C_COND, C_REG, C_REG, C_REG, 18, 4, 0, 0, 0}, @@ -499,6 +534,8 @@ var optab = []Optab{ {AFMOVS, C_FREG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UAUTO64K, 20, 4, REGSP, 0, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_UOREG64K, 20, 4, 0, 0, 0}, /* unscaled 9-bit signed displacement store */ {AMOVB, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, @@ -516,6 +553,8 @@ var optab = []Optab{ {AFMOVS, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0}, /* scaled 12-bit unsigned displacement load */ {AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, @@ -533,6 +572,8 @@ var optab = []Optab{ {AFMOVS, C_UOREG16K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, {AFMOVD, C_UAUTO32K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, {AFMOVD, C_UOREG32K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, + {AFMOVQ, C_UAUTO64K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, + {AFMOVQ, C_UOREG64K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, /* unscaled 9-bit signed displacement load */ {AMOVB, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0}, @@ -550,6 +591,8 @@ var optab = []Optab{ {AFMOVS, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, {AFMOVD, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, {AFMOVD, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, + {AFMOVQ, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0}, + {AFMOVQ, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0}, /* long displacement store */ {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, @@ -567,6 +610,8 @@ var optab = []Optab{ {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0}, /* long displacement load */ {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0}, @@ -584,9 +629,8 @@ var optab = []Optab{ {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, - - /* load long effective stack address (load int32 offset and add) */ - {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0}, + {AFMOVQ, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0}, + {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0}, /* pre/post-indexed load (unscaled, signed 9-bit offset) */ {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, @@ -596,6 +640,7 @@ var optab = []Optab{ {AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST}, {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, + {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST}, {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, @@ -604,6 +649,7 @@ var optab = []Optab{ {AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE}, {AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, + {AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE}, /* pre/post-indexed store (unscaled, signed 9-bit offset) */ {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, @@ -613,6 +659,7 @@ var optab = []Optab{ {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST}, {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, @@ -621,6 +668,7 @@ var optab = []Optab{ {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, {AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, + {AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE}, /* load with shifted or extended register offset */ {AMOVD, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0}, @@ -770,8 +818,10 @@ var optab = []Optab{ {ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST}, {ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0}, - {ASWPD, C_REG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0}, // RegTo2=C_REG - {ASWPD, C_REG, C_NONE, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0}, // RegTo2=C_REG + {ASWPD, C_REG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0}, // RegTo2=C_REG + {ASWPD, C_REG, C_NONE, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0}, // RegTo2=C_REG + {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZOREG, 106, 4, 0, 0, 0}, // RegTo2=C_REGREG + {ACASPD, C_PAIR, C_NONE, C_NONE, C_ZAUTO, 106, 4, REGSP, 0, 0}, // RegTo2=C_REGREG {ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0}, {ALDXR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0}, {ALDAXR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0}, @@ -832,6 +882,8 @@ var optab = []Optab{ {ASHA256H, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, {AVREV32, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0}, {AVPMULL, C_ARNG, C_ARNG, C_NONE, C_ARNG, 93, 4, 0, 0, 0}, + {AVEOR3, C_ARNG, C_ARNG, C_ARNG, C_ARNG, 103, 4, 0, 0, 0}, + {AVXAR, C_VCON, C_ARNG, C_ARNG, C_ARNG, 104, 4, 0, 0, 0}, {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0}, {obj.APCDATA, C_VCON, C_NONE, C_NONE, C_VCON, 0, 0, 0, 0, 0}, @@ -900,7 +952,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ctxt.Retpoline = false // don't keep printing } - p := cursym.Func.Text + p := cursym.Func().Text if p == nil || p.Link == nil { // handle external functions and ELF section symbols return } @@ -930,8 +982,8 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { alignedValue := p.From.Offset m = pcAlignPadLength(pc, alignedValue, ctxt) // Update the current text symbol alignment value. - if int32(alignedValue) > cursym.Func.Align { - cursym.Func.Align = int32(alignedValue) + if int32(alignedValue) > cursym.Func().Align { + cursym.Func().Align = int32(alignedValue) } break case obj.ANOP, obj.AFUNCDATA, obj.APCDATA: @@ -940,13 +992,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { c.ctxt.Diag("zero-width instruction\n%v", p) } } - switch o.flag & (LFROM | LTO) { - case LFROM: + if o.flag&LFROM != 0 { c.addpool(p, &p.From) - - case LTO: + } + if o.flag&LFROM3 != 0 { + c.addpool(p, p.GetFrom3()) + } + if o.flag<O != 0 { c.addpool(p, &p.To) - break } if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */ @@ -969,7 +1022,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { for bflag != 0 { bflag = 0 pc = 0 - for p = c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p = c.cursym.Func().Text.Link; p != nil; p = p.Link { if p.As == ADWORD && (pc&7) != 0 { pc += 4 } @@ -1033,7 +1086,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { psz := int32(0) var i int var out [6]uint32 - for p := c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { c.pc = p.Pc o = c.oplook(p) @@ -1074,7 +1127,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // We use REGTMP as a scratch register during call injection, // so instruction sequences that use REGTMP are unsafe to // preempt asynchronously. - obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, c.isRestartable) + obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable) } // isUnsafePoint returns whether p is an unsafe point. @@ -1164,8 +1217,8 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { sz := 4 if a.Type == obj.TYPE_CONST { - if lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit)) { - // out of range -0x80000000 ~ 0xffffffff, must store 64-bit + if (lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit))) || p.As == AVMOVQ || p.As == AVMOVD { + // out of range -0x80000000 ~ 0xffffffff or VMOVQ or VMOVD operand, must store 64-bit. t.As = ADWORD sz = 8 } // else store 32-bit @@ -1197,37 +1250,49 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { C_PSAUTO, C_PSAUTO_8, C_PSAUTO_4, + C_PPAUTO_16, C_PPAUTO, + C_UAUTO4K_16, C_UAUTO4K_8, C_UAUTO4K_4, C_UAUTO4K_2, C_UAUTO4K, + C_UAUTO8K_16, C_UAUTO8K_8, C_UAUTO8K_4, C_UAUTO8K, + C_UAUTO16K_16, C_UAUTO16K_8, C_UAUTO16K, + C_UAUTO32K_16, C_UAUTO32K, + C_UAUTO64K, C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO, C_NAUTO4K, C_LAUTO, - C_PPOREG, C_PSOREG, - C_PSOREG_4, C_PSOREG_8, + C_PSOREG_4, + C_PPOREG_16, + C_PPOREG, + C_UOREG4K_16, C_UOREG4K_8, C_UOREG4K_4, C_UOREG4K_2, C_UOREG4K, + C_UOREG8K_16, C_UOREG8K_8, C_UOREG8K_4, C_UOREG8K, + C_UOREG16K_16, C_UOREG16K_8, C_UOREG16K, + C_UOREG32K_16, C_UOREG32K, + C_UOREG64K, C_NSOREG_8, C_NSOREG_4, C_NSOREG, @@ -1352,6 +1417,10 @@ func isaddcon(v int64) bool { return v <= 0xFFF } +func isaddcon2(v int64) bool { + return 0 <= v && v <= 0xFFFFFF +} + // isbitcon reports whether a constant can be encoded into a logical instruction. // bitcon has a binary form of repetition of a bit sequence of length 2, 4, 8, 16, 32, or 64, // which itself is a rotate (w.r.t. the length of the unit) of a sequence of ones. @@ -1518,10 +1587,18 @@ func autoclass(l int64) int { } return C_PSAUTO } - if l <= 504 && l&7 == 0 { - return C_PPAUTO + if l <= 504 { + if l&15 == 0 { + return C_PPAUTO_16 + } + if l&7 == 0 { + return C_PPAUTO + } } if l <= 4095 { + if l&15 == 0 { + return C_UAUTO4K_16 + } if l&7 == 0 { return C_UAUTO4K_8 } @@ -1534,6 +1611,9 @@ func autoclass(l int64) int { return C_UAUTO4K } if l <= 8190 { + if l&15 == 0 { + return C_UAUTO8K_16 + } if l&7 == 0 { return C_UAUTO8K_8 } @@ -1545,6 +1625,9 @@ func autoclass(l int64) int { } } if l <= 16380 { + if l&15 == 0 { + return C_UAUTO16K_16 + } if l&7 == 0 { return C_UAUTO16K_8 } @@ -1552,8 +1635,16 @@ func autoclass(l int64) int { return C_UAUTO16K } } - if l <= 32760 && (l&7) == 0 { - return C_UAUTO32K + if l <= 32760 { + if l&15 == 0 { + return C_UAUTO32K_16 + } + if l&7 == 0 { + return C_UAUTO32K + } + } + if l <= 65520 && (l&15) == 0 { + return C_UAUTO64K } return C_LAUTO } @@ -1581,6 +1672,8 @@ func (c *ctxt7) offsetshift(p *obj.Prog, v int64, cls int) int64 { s = 2 case C_UAUTO32K, C_UOREG32K: s = 3 + case C_UAUTO64K, C_UOREG64K: + s = 4 default: c.ctxt.Diag("bad class: %v\n%v", DRconv(cls), p) } @@ -1880,10 +1973,14 @@ func (c *ctxt7) aclass(a *obj.Addr) int { default: return C_GOK } - - if isaddcon(c.instoffset) { + cf := c.instoffset + if isaddcon(cf) || isaddcon(-cf) { return C_AACON } + if isaddcon2(cf) { + return C_AACON2 + } + return C_LACON case obj.TYPE_BRANCH: @@ -1940,7 +2037,7 @@ func (c *ctxt7) oplook(p *obj.Prog) *Optab { a1-- a3 := C_NONE + 1 - if p.GetFrom3() != nil { + if p.GetFrom3() != nil && p.RestArgs[0].Pos == 0 { a3 = int(p.GetFrom3().Class) if a3 == 0 { a3 = c.aclass(p.GetFrom3()) + 1 @@ -2037,7 +2134,7 @@ func cmp(a int, b int) bool { return cmp(C_LCON, b) case C_LACON: - if b == C_AACON { + if b == C_AACON || b == C_AACON2 { return true } @@ -2108,46 +2205,66 @@ func cmp(a int, b int) bool { case C_PPAUTO: switch b { - case C_ZAUTO, C_PSAUTO_8: + case C_ZAUTO, C_PSAUTO_8, C_PPAUTO_16: return true } case C_UAUTO4K: switch b { case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, - C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8: + C_PPAUTO, C_PPAUTO_16, + C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16: return true } case C_UAUTO8K: switch b { - case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, - C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8: + case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, + C_PPAUTO, C_PPAUTO_16, + C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, + C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16: return true } case C_UAUTO16K: switch b { - case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, - C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO16K_8: + case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, + C_PPAUTO, C_PPAUTO_16, + C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, + C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16, + C_UAUTO16K_8, C_UAUTO16K_16: return true } case C_UAUTO32K: switch b { case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, - C_PPAUTO, C_UAUTO4K_8, C_UAUTO8K_8, C_UAUTO16K_8: + C_PPAUTO, C_PPAUTO_16, + C_UAUTO4K_8, C_UAUTO4K_16, + C_UAUTO8K_8, C_UAUTO8K_16, + C_UAUTO16K_8, C_UAUTO16K_16, + C_UAUTO32K_16: + return true + } + + case C_UAUTO64K: + switch b { + case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, + C_PPAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16, + C_UAUTO32K_16: return true } case C_LAUTO: switch b { - case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NPAUTO, - C_NAUTO4K, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, - C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, - C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, - C_UAUTO16K, C_UAUTO16K_8, - C_UAUTO32K: + case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NPAUTO, C_NAUTO4K, + C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, + C_PPAUTO, C_PPAUTO_16, + C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16, + C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16, + C_UAUTO16K, C_UAUTO16K_8, C_UAUTO16K_16, + C_UAUTO32K, C_UAUTO32K_16, + C_UAUTO64K: return true } @@ -2174,6 +2291,11 @@ func cmp(a int, b int) bool { return true } + case C_PSOREG_8: + if b == C_ZOREG { + return true + } + case C_PSOREG_4: switch b { case C_ZOREG, C_PSOREG_8: @@ -2188,48 +2310,66 @@ func cmp(a int, b int) bool { case C_PPOREG: switch b { - case C_ZOREG, C_PSOREG_8: + case C_ZOREG, C_PSOREG_8, C_PPOREG_16: return true } case C_UOREG4K: switch b { - case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, - C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8: + case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG, C_PPOREG_16, + C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16: return true } case C_UOREG8K: switch b { - case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, - C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, - C_UOREG8K_4, C_UOREG8K_8: + case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG, C_PPOREG_16, + C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, + C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16: return true } case C_UOREG16K: switch b { - case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, - C_PPOREG, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, - C_UOREG8K_8, C_UOREG16K_8: + case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG, C_PPOREG_16, + C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, + C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16, + C_UOREG16K_8, C_UOREG16K_16: return true } case C_UOREG32K: switch b { - case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, - C_PPOREG, C_UOREG4K_8, C_UOREG8K_8, C_UOREG16K_8: + case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG, C_PPOREG_16, + C_UOREG4K_8, C_UOREG4K_16, + C_UOREG8K_8, C_UOREG8K_16, + C_UOREG16K_8, C_UOREG16K_16, + C_UOREG32K_16: + return true + } + + case C_UOREG64K: + switch b { + case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16, + C_UOREG32K_16: return true } case C_LOREG: switch b { - case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NPOREG, - C_NOREG4K, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG, - C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, - C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, - C_UOREG16K, C_UOREG16K_8, - C_UOREG32K: + case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NPOREG, C_NOREG4K, + C_PSOREG, C_PSOREG_4, C_PSOREG_8, + C_PPOREG, C_PPOREG_16, + C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16, + C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16, + C_UOREG16K, C_UOREG16K_8, C_UOREG16K_16, + C_UOREG32K, C_UOREG32K_16, + C_UOREG64K: return true } @@ -2382,10 +2522,18 @@ func buildop(ctxt *obj.Link) { oprangeset(AMOVZW, t) case ASWPD: - for i := range atomicInstructions { + for i := range atomicLDADD { + oprangeset(i, t) + } + for i := range atomicSWP { + if i == ASWPD { + continue + } oprangeset(i, t) } + case ACASPD: + oprangeset(ACASPW, t) case ABEQ: oprangeset(ABNE, t) oprangeset(ABCS, t) @@ -2657,7 +2805,8 @@ func buildop(ctxt *obj.Link) { case AFCSELD: oprangeset(AFCSELS, t) - case AFMOVS, AFMOVD: + case AFMOVQ, AFMOVD, AFMOVS, + AVMOVQ, AVMOVD, AVMOVS: break case AFCVTZSD: @@ -2740,9 +2889,16 @@ func buildop(ctxt *obj.Link) { oprangeset(AVCMEQ, t) oprangeset(AVORR, t) oprangeset(AVEOR, t) + oprangeset(AVBSL, t) + oprangeset(AVBIT, t) + oprangeset(AVCMTST, t) + oprangeset(AVUZP1, t) + oprangeset(AVUZP2, t) + oprangeset(AVBIF, t) case AVADD: oprangeset(AVSUB, t) + oprangeset(AVRAX1, t) case AAESD: oprangeset(AAESE, t) @@ -2777,6 +2933,8 @@ func buildop(ctxt *obj.Link) { case AVUSHR: oprangeset(AVSHL, t) oprangeset(AVSRI, t) + oprangeset(AVSLI, t) + oprangeset(AVUSRA, t) case AVREV32: oprangeset(AVCNT, t) @@ -2787,6 +2945,12 @@ func buildop(ctxt *obj.Link) { case AVZIP1: oprangeset(AVZIP2, t) + case AVUXTL: + oprangeset(AVUXTL2, t) + + case AVUSHLL: + oprangeset(AVUSHLL2, t) + case AVLD1R: oprangeset(AVLD2, t) oprangeset(AVLD2R, t) @@ -2795,6 +2959,12 @@ func buildop(ctxt *obj.Link) { oprangeset(AVLD4, t) oprangeset(AVLD4R, t) + case AVEOR3: + oprangeset(AVBCAX, t) + + case AVUADDW: + oprangeset(AVUADDW2, t) + case ASHA1H, AVCNT, AVMOV, @@ -2807,7 +2977,8 @@ func buildop(ctxt *obj.Link) { AVDUP, AVMOVI, APRFM, - AVEXT: + AVEXT, + AVXAR: break case obj.ANOP, @@ -3041,11 +3212,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } o1 |= (uint32(r&31) << 5) | uint32(rt&31) - case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R */ - o1 = c.opirr(p, p.As) - + case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R; mov $addcon2, R */ rt := int(p.To.Reg) r := int(o.param) + if r == 0 { r = REGZERO } else if r == REGFROM { @@ -3054,13 +3224,23 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { if r == 0 { r = REGSP } + v := int32(c.regoff(&p.From)) - if (v & 0xFFF000) != 0 { - v >>= 12 - o1 |= 1 << 22 /* shift, by 12 */ + var op int32 + if v < 0 { + v = -v + op = int32(c.opirr(p, ASUB)) + } else { + op = int32(c.opirr(p, AADD)) } - o1 |= ((uint32(v) & 0xFFF) << 10) | (uint32(r&31) << 5) | uint32(rt&31) + if int(o.size) == 8 { + o1 = c.oaddi(p, op, v&0xfff000, r, REGTMP) + o2 = c.oaddi(p, op, v&0x000fff, REGTMP, rt) + break + } + + o1 = c.oaddi(p, op, v, r, rt) case 5: /* b s; bl s */ o1 = c.opbra(p, p.As) @@ -3079,12 +3259,13 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { case 6: /* b ,O(R); bl ,O(R) */ o1 = c.opbrr(p, p.As) - o1 |= uint32(p.To.Reg&31) << 5 - rel := obj.Addrel(c.cursym) - rel.Off = int32(c.pc) - rel.Siz = 0 - rel.Type = objabi.R_CALLIND + if p.As == obj.ACALL { + rel := obj.Addrel(c.cursym) + rel.Off = int32(c.pc) + rel.Siz = 0 + rel.Type = objabi.R_CALLIND + } case 7: /* beq s */ o1 = c.opbra(p, p.As) @@ -3343,10 +3524,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { r = int(o.param) } if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */ - o1 = c.olsr9s(p, int32(c.opstr9(p, p.As)), v, r, int(p.From.Reg)) + o1 = c.olsr9s(p, int32(c.opstr(p, p.As)), v, r, int(p.From.Reg)) } else { v = int32(c.offsetshift(p, int64(v), int(o.a4))) - o1 = c.olsr12u(p, int32(c.opstr12(p, p.As)), v, r, int(p.From.Reg)) + o1 = c.olsr12u(p, int32(c.opstr(p, p.As)), v, r, int(p.From.Reg)) } case 21: /* movT O(R),R -> ldrT */ @@ -3358,11 +3539,11 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { r = int(o.param) } if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */ - o1 = c.olsr9s(p, int32(c.opldr9(p, p.As)), v, r, int(p.To.Reg)) + o1 = c.olsr9s(p, int32(c.opldr(p, p.As)), v, r, int(p.To.Reg)) } else { v = int32(c.offsetshift(p, int64(v), int(o.a1))) //print("offset=%lld v=%ld a1=%d\n", instoffset, v, o->a1); - o1 = c.olsr12u(p, int32(c.opldr12(p, p.As)), v, r, int(p.To.Reg)) + o1 = c.olsr12u(p, int32(c.opldr(p, p.As)), v, r, int(p.To.Reg)) } case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */ @@ -3375,7 +3556,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { if v < -256 || v > 255 { c.ctxt.Diag("offset out of range [-255,254]: %v", p) } - o1 = c.opldrpp(p, p.As) + o1 = c.opldr(p, p.As) if o.scond == C_XPOST { o1 |= 1 << 10 } else { @@ -3393,7 +3574,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { if v < -256 || v > 255 { c.ctxt.Diag("offset out of range [-255,254]: %v", p) } - o1 = LD2STR(c.opldrpp(p, p.As)) + o1 = c.opstr(p, p.As) if o.scond == C_XPOST { o1 |= 1 << 10 } else { @@ -3545,7 +3726,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } o1 = c.oaddi(p, int32(c.opirr(p, AADD)), hi, r, REGTMP) - o2 = c.olsr12u(p, int32(c.opstr12(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg)) + o2 = c.olsr12u(p, int32(c.opstr(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg)) break storeusepool: @@ -3589,7 +3770,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } o1 = c.oaddi(p, int32(c.opirr(p, AADD)), hi, r, REGTMP) - o2 = c.olsr12u(p, int32(c.opldr12(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg)) + o2 = c.olsr12u(p, int32(c.opldr(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg)) break loadusepool: @@ -3847,17 +4028,27 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 |= uint32(p.From.Reg&31) << 5 o1 |= uint32(p.To.Reg & 31) - case 47: /* SWPx/LDADDx/LDANDx/LDEORx/LDORx Rs, (Rb), Rt */ + case 47: // SWPx/LDADDx/LDCLRx/LDEORx/LDORx/CASx Rs, (Rb), Rt rs := p.From.Reg rt := p.RegTo2 rb := p.To.Reg - fields := atomicInstructions[p.As] - // rt can't be sp. rt can't be r31 when field A is 0, A bit is the 23rd bit. - if rt == REG_RSP || (rt == REGZERO && (fields&(1<<23) == 0)) { + // rt can't be sp. + if rt == REG_RSP { c.ctxt.Diag("illegal destination register: %v\n", p) } - o1 |= fields | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) + if enc, ok := atomicLDADD[p.As]; ok { + // for LDADDx-like instructions, rt can't be r31 when field.enc A is 0, A bit is the 23rd bit. + if (rt == REGZERO) && (enc&(1<<23) == 0) { + c.ctxt.Diag("illegal destination register: %v\n", p) + } + o1 |= enc + } else if enc, ok := atomicSWP[p.As]; ok { + o1 |= enc + } else { + c.ctxt.Diag("invalid atomic instructions: %v\n", p) + } + o1 |= uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) case 48: /* ADD $C_ADDCON2, Rm, Rd */ // NOTE: this case does not use REGTMP. If it ever does, @@ -4078,7 +4269,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { rel.Sym = p.To.Sym rel.Add = p.To.Offset rel.Type = objabi.R_ADDRARM64 - o3 = c.olsr12u(p, int32(c.opstr12(p, p.As)), 0, REGTMP, int(p.From.Reg)) + o3 = c.olsr12u(p, int32(c.opstr(p, p.As)), 0, REGTMP, int(p.From.Reg)) case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */ o1 = ADR(1, 0, REGTMP) @@ -4089,7 +4280,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { rel.Sym = p.From.Sym rel.Add = p.From.Offset rel.Type = objabi.R_ADDRARM64 - o3 = c.olsr12u(p, int32(c.opldr12(p, p.As)), 0, REGTMP, int(p.To.Reg)) + o3 = c.olsr12u(p, int32(c.opldr(p, p.As)), 0, REGTMP, int(p.To.Reg)) case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */ v := int32(c.regoff(&p.From)) @@ -4142,7 +4333,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */ o1 = ADR(1, 0, REGTMP) - o2 = c.olsr12u(p, int32(c.opldr12(p, AMOVD)), 0, REGTMP, int(p.To.Reg)) + o2 = c.olsr12u(p, int32(c.opldr(p, AMOVD)), 0, REGTMP, int(p.To.Reg)) rel := obj.Addrel(c.cursym) rel.Off = int32(c.pc) rel.Siz = 8 @@ -4155,7 +4346,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */ o1 = ADR(1, 0, REGTMP) - o2 = c.olsr12u(p, int32(c.opldr12(p, AMOVD)), 0, REGTMP, int(p.To.Reg)) + o2 = c.olsr12u(p, int32(c.opldr(p, AMOVD)), 0, REGTMP, int(p.To.Reg)) rel := obj.Addrel(c.cursym) rel.Off = int32(c.pc) rel.Siz = 8 @@ -4163,7 +4354,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { rel.Add = 0 rel.Type = objabi.R_ARM64_GOTPCREL - case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls Vm.<T>, Vn.<T>, Vd.<T> */ + case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls/vbit/vbsl/vcmtst/vsub/vbif/vuzip1/vuzip2/vrax1 Vm.<T>, Vn.<T>, Vd.<T> */ af := int((p.From.Reg >> 5) & 15) af3 := int((p.Reg >> 5) & 15) at := int((p.To.Reg >> 5) & 15) @@ -4204,22 +4395,35 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { c.ctxt.Diag("invalid arrangement: %v", p) } - if (p.As == AVORR || p.As == AVAND || p.As == AVEOR) && - (af != ARNG_16B && af != ARNG_8B) { - c.ctxt.Diag("invalid arrangement: %v", p) - } else if (p.As == AVFMLA || p.As == AVFMLS) && - (af != ARNG_2D && af != ARNG_2S && af != ARNG_4S) { - c.ctxt.Diag("invalid arrangement: %v", p) - } else if p.As == AVORR { - size = 2 - } else if p.As == AVAND || p.As == AVEOR { + switch p.As { + case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF: + if af != ARNG_16B && af != ARNG_8B { + c.ctxt.Diag("invalid arrangement: %v", p) + } + case AVFMLA, AVFMLS: + if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S { + c.ctxt.Diag("invalid arrangement: %v", p) + } + } + switch p.As { + case AVAND, AVEOR: size = 0 - } else if p.As == AVFMLA || p.As == AVFMLS { + case AVBSL: + size = 1 + case AVORR, AVBIT, AVBIF: + size = 2 + case AVFMLA, AVFMLS: if af == ARNG_2D { size = 1 } else { size = 0 } + case AVRAX1: + if af != ARNG_2D { + c.ctxt.Diag("invalid arrangement: %v", p) + } + size = 0 + Q = 0 } o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) @@ -4703,7 +4907,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } } - o1 = c.opldrpp(p, p.As) + o1 = c.opirr(p, p.As) o1 |= (uint32(r&31) << 5) | (uint32((imm>>3)&0xfff) << 10) | (uint32(v & 31)) case 92: /* vmov Vn.<T>[index], Vd.<T>[index] */ @@ -4747,47 +4951,31 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } o1 |= (uint32(imm5&0x1f) << 16) | (uint32(imm4&0xf) << 11) | (uint32(rf&31) << 5) | uint32(rt&31) - case 93: /* vpmull{2} Vm.<T>, Vn.<T>, Vd */ - af := int((p.From.Reg >> 5) & 15) - at := int((p.To.Reg >> 5) & 15) - a := int((p.Reg >> 5) & 15) + case 93: /* vpmull{2} Vm.<Tb>, Vn.<Tb>, Vd.<Ta> */ + af := uint8((p.From.Reg >> 5) & 15) + at := uint8((p.To.Reg >> 5) & 15) + a := uint8((p.Reg >> 5) & 15) + if af != a { + c.ctxt.Diag("invalid arrangement: %v", p) + } var Q, size uint32 - if p.As == AVPMULL { - Q = 0 - } else { + if p.As == AVPMULL2 { Q = 1 } - - var fArng int - switch at { - case ARNG_8H: - if Q == 0 { - fArng = ARNG_8B - } else { - fArng = ARNG_16B - } + switch pack(Q, at, af) { + case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B): size = 0 - case ARNG_1Q: - if Q == 0 { - fArng = ARNG_1D - } else { - fArng = ARNG_2D - } + case pack(0, ARNG_1Q, ARNG_1D), pack(1, ARNG_1Q, ARNG_2D): size = 3 default: - c.ctxt.Diag("invalid arrangement on Vd.<T>: %v", p) - } - - if af != a || af != fArng { - c.ctxt.Diag("invalid arrangement: %v", p) + c.ctxt.Diag("operand mismatch: %v\n", p) } o1 = c.oprrr(p, p.As) rf := int((p.From.Reg) & 31) rt := int((p.To.Reg) & 31) r := int((p.Reg) & 31) - o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) case 94: /* vext $imm4, Vm.<T>, Vn.<T>, Vd.<T> */ @@ -4825,7 +5013,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 |= ((Q & 1) << 30) | (uint32(r&31) << 16) | (uint32(index&15) << 11) | (uint32(rf&31) << 5) | uint32(rt&31) - case 95: /* vushr $shift, Vn.<T>, Vd.<T> */ + case 95: /* vushr/vshl/vsri/vsli/vusra $shift, Vn.<T>, Vd.<T> */ at := int((p.To.Reg >> 5) & 15) af := int((p.Reg >> 5) & 15) shift := int(p.From.Offset) @@ -4862,14 +5050,13 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } imm := 0 - switch p.As { - case AVUSHR, AVSRI: + case AVUSHR, AVSRI, AVUSRA: imm = esize*2 - shift if imm < esize || imm > imax { c.ctxt.Diag("shift out of range: %v", p) } - case AVSHL: + case AVSHL, AVSLI: imm = esize + shift if imm > imax { c.ctxt.Diag("shift out of range: %v", p) @@ -4882,7 +5069,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { rt := int((p.To.Reg) & 31) rf := int((p.Reg) & 31) - o1 |= ((Q & 1) << 30) | (uint32(imm&127) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) + o1 |= ((Q & 1) << 30) | (uint32(imm&0x7f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31) case 96: /* vst1 Vt1.<T>[index], offset(Rn) */ af := int((p.From.Reg >> 5) & 15) @@ -5096,6 +5283,150 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 = q<<30 | 0xe<<24 | len<<13 o1 |= (uint32(rf&31) << 16) | uint32(offset&31)<<5 | uint32(rt&31) + case 101: // VMOVQ $vcon1, $vcon2, Vd or VMOVD|VMOVS $vcon, Vd -> FMOVQ/FMOVD/FMOVS pool(PC), Vd: load from constant pool. + o1 = c.omovlit(p.As, p, &p.From, int(p.To.Reg)) + + case 102: /* vushll, vushll2, vuxtl, vuxtl2 */ + o1 = c.opirr(p, p.As) + rf := p.Reg + af := uint8((p.Reg >> 5) & 15) + at := uint8((p.To.Reg >> 5) & 15) + shift := int(p.From.Offset) + if p.As == AVUXTL || p.As == AVUXTL2 { + rf = p.From.Reg + af = uint8((p.From.Reg >> 5) & 15) + shift = 0 + } + + Q := (o1 >> 30) & 1 + var immh, width uint8 + switch pack(Q, af, at) { + case pack(0, ARNG_8B, ARNG_8H): + immh, width = 1, 8 + case pack(1, ARNG_16B, ARNG_8H): + immh, width = 1, 8 + case pack(0, ARNG_4H, ARNG_4S): + immh, width = 2, 16 + case pack(1, ARNG_8H, ARNG_4S): + immh, width = 2, 16 + case pack(0, ARNG_2S, ARNG_2D): + immh, width = 4, 32 + case pack(1, ARNG_4S, ARNG_2D): + immh, width = 4, 32 + default: + c.ctxt.Diag("operand mismatch: %v\n", p) + } + if !(0 <= shift && shift <= int(width-1)) { + c.ctxt.Diag("shift amount out of range: %v\n", p) + } + o1 |= uint32(immh)<<19 | uint32(shift)<<16 | uint32(rf&31)<<5 | uint32(p.To.Reg&31) + + case 103: /* VEOR3/VBCAX Va.B16, Vm.B16, Vn.B16, Vd.B16 */ + ta := (p.From.Reg >> 5) & 15 + tm := (p.Reg >> 5) & 15 + td := (p.To.Reg >> 5) & 15 + tn := ((p.GetFrom3().Reg) >> 5) & 15 + + if ta != tm || ta != tn || ta != td || ta != ARNG_16B { + c.ctxt.Diag("invalid arrangement: %v", p) + break + } + + o1 = c.oprrr(p, p.As) + ra := int(p.From.Reg) + rm := int(p.Reg) + rn := int(p.GetFrom3().Reg) + rd := int(p.To.Reg) + o1 |= uint32(rm&31)<<16 | uint32(ra&31)<<10 | uint32(rn&31)<<5 | uint32(rd)&31 + + case 104: /* vxar $imm4, Vm.<T>, Vn.<T>, Vd.<T> */ + af := ((p.GetFrom3().Reg) >> 5) & 15 + at := (p.To.Reg >> 5) & 15 + a := (p.Reg >> 5) & 15 + index := int(p.From.Offset) + + if af != a || af != at { + c.ctxt.Diag("invalid arrangement: %v", p) + break + } + + if af != ARNG_2D { + c.ctxt.Diag("invalid arrangement, should be D2: %v", p) + break + } + + if index < 0 || index > 63 { + c.ctxt.Diag("illegal offset: %v", p) + } + + o1 = c.opirr(p, p.As) + rf := (p.GetFrom3().Reg) & 31 + rt := (p.To.Reg) & 31 + r := (p.Reg) & 31 + + o1 |= (uint32(r&31) << 16) | (uint32(index&63) << 10) | (uint32(rf&31) << 5) | uint32(rt&31) + + case 105: /* vuaddw{2} Vm.<Tb>, Vn.<Ta>, Vd.<Ta> */ + af := uint8((p.From.Reg >> 5) & 15) + at := uint8((p.To.Reg >> 5) & 15) + a := uint8((p.Reg >> 5) & 15) + if at != a { + c.ctxt.Diag("invalid arrangement: %v", p) + break + } + + var Q, size uint32 + if p.As == AVUADDW2 { + Q = 1 + } + switch pack(Q, at, af) { + case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B): + size = 0 + case pack(0, ARNG_4S, ARNG_4H), pack(1, ARNG_4S, ARNG_8H): + size = 1 + case pack(0, ARNG_2D, ARNG_2S), pack(1, ARNG_2D, ARNG_4S): + size = 2 + default: + c.ctxt.Diag("operand mismatch: %v\n", p) + } + + o1 = c.oprrr(p, p.As) + rf := int((p.From.Reg) & 31) + rt := int((p.To.Reg) & 31) + r := int((p.Reg) & 31) + o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31) + + case 106: // CASPx (Rs, Rs+1), (Rb), (Rt, Rt+1) + rs := p.From.Reg + rt := p.GetTo2().Reg + rb := p.To.Reg + rs1 := int16(p.From.Offset) + rt1 := int16(p.GetTo2().Offset) + + enc, ok := atomicCASP[p.As] + if !ok { + c.ctxt.Diag("invalid CASP-like atomic instructions: %v\n", p) + } + // for CASPx-like instructions, Rs<0> != 1 && Rt<0> != 1 + switch { + case rs&1 != 0: + c.ctxt.Diag("source register pair must start from even register: %v\n", p) + break + case rt&1 != 0: + c.ctxt.Diag("destination register pair must start from even register: %v\n", p) + break + case rs != rs1-1: + c.ctxt.Diag("source register pair must be contiguous: %v\n", p) + break + case rt != rt1-1: + c.ctxt.Diag("destination register pair must be contiguous: %v\n", p) + break + } + // rt can't be sp. + if rt == REG_RSP { + c.ctxt.Diag("illegal destination register: %v\n", p) + } + o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) } out[0] = o1 out[1] = o2 @@ -5662,12 +5993,18 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 { case AVADD: return 7<<25 | 1<<21 | 1<<15 | 1<<10 + case AVSUB: + return 0x17<<25 | 1<<21 | 1<<15 | 1<<10 + case AVADDP: return 7<<25 | 1<<21 | 1<<15 | 15<<10 case AVAND: return 7<<25 | 1<<21 | 7<<10 + case AVBCAX: + return 0xCE<<24 | 1<<21 + case AVCMEQ: return 1<<29 | 0x71<<21 | 0x23<<10 @@ -5683,12 +6020,18 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 { case AVEOR: return 1<<29 | 0x71<<21 | 7<<10 + case AVEOR3: + return 0xCE << 24 + case AVORR: return 7<<25 | 5<<21 | 7<<10 case AVREV16: return 3<<26 | 2<<24 | 1<<21 | 3<<11 + case AVRAX1: + return 0xCE<<24 | 3<<21 | 1<<15 | 3<<10 + case AVREV32: return 11<<26 | 2<<24 | 1<<21 | 1<<11 @@ -5724,6 +6067,27 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 { case AVLD2R, AVLD4R: return 0xD<<24 | 3<<21 + + case AVBIF: + return 1<<29 | 7<<25 | 7<<21 | 7<<10 + + case AVBIT: + return 1<<29 | 0x75<<21 | 7<<10 + + case AVBSL: + return 1<<29 | 0x73<<21 | 7<<10 + + case AVCMTST: + return 0xE<<24 | 1<<21 | 0x23<<10 + + case AVUZP1: + return 7<<25 | 3<<11 + + case AVUZP2: + return 7<<25 | 1<<14 | 3<<11 + + case AVUADDW, AVUADDW2: + return 0x17<<25 | 1<<21 | 1<<12 } c.ctxt.Diag("%v: bad rrr %d %v", p, a, a) @@ -5922,6 +6286,24 @@ func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 { case AVSRI: return 0x5E<<23 | 17<<10 + + case AVSLI: + return 0x5E<<23 | 21<<10 + + case AVUSHLL, AVUXTL: + return 1<<29 | 15<<24 | 0x29<<10 + + case AVUSHLL2, AVUXTL2: + return 3<<29 | 15<<24 | 0x29<<10 + + case AVXAR: + return 0xCE<<24 | 1<<23 + + case AVUSRA: + return 1<<29 | 15<<24 | 5<<10 + + case APRFM: + return 0xf9<<24 | 2<<22 } c.ctxt.Diag("%v: bad irr %v", p, a) @@ -6316,7 +6698,7 @@ func (c *ctxt7) opstore(p *obj.Prog, a obj.As) uint32 { } /* - * load/store register (unsigned immediate) C3.3.13 + * load/store register (scaled 12-bit unsigned immediate) C3.3.13 * these produce 64-bit values (when there's an option) */ func (c *ctxt7) olsr12u(p *obj.Prog, o int32, v int32, b int, r int) uint32 { @@ -6326,49 +6708,12 @@ func (c *ctxt7) olsr12u(p *obj.Prog, o int32, v int32, b int, r int) uint32 { o |= (v & 0xFFF) << 10 o |= int32(b&31) << 5 o |= int32(r & 31) + o |= 1 << 24 return uint32(o) } -func (c *ctxt7) opldr12(p *obj.Prog, a obj.As) uint32 { - switch a { - case AMOVD: - return LDSTR12U(3, 0, 1) /* imm12<<10 | Rn<<5 | Rt */ - - case AMOVW: - return LDSTR12U(2, 0, 2) - - case AMOVWU: - return LDSTR12U(2, 0, 1) - - case AMOVH: - return LDSTR12U(1, 0, 2) - - case AMOVHU: - return LDSTR12U(1, 0, 1) - - case AMOVB: - return LDSTR12U(0, 0, 2) - - case AMOVBU: - return LDSTR12U(0, 0, 1) - - case AFMOVS: - return LDSTR12U(2, 1, 1) - - case AFMOVD: - return LDSTR12U(3, 1, 1) - } - - c.ctxt.Diag("bad opldr12 %v\n%v", a, p) - return 0 -} - -func (c *ctxt7) opstr12(p *obj.Prog, a obj.As) uint32 { - return LD2STR(c.opldr12(p, a)) -} - /* - * load/store register (unscaled immediate) C3.3.12 + * load/store register (unscaled 9-bit signed immediate) C3.3.12 */ func (c *ctxt7) olsr9s(p *obj.Prog, o int32, v int32, b int, r int) uint32 { if v < -256 || v > 255 { @@ -6380,76 +6725,58 @@ func (c *ctxt7) olsr9s(p *obj.Prog, o int32, v int32, b int, r int) uint32 { return uint32(o) } -func (c *ctxt7) opldr9(p *obj.Prog, a obj.As) uint32 { - switch a { - case AMOVD: - return LDSTR9S(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */ - - case AMOVW: - return LDSTR9S(2, 0, 2) - - case AMOVWU: - return LDSTR9S(2, 0, 1) - - case AMOVH: - return LDSTR9S(1, 0, 2) - - case AMOVHU: - return LDSTR9S(1, 0, 1) - - case AMOVB: - return LDSTR9S(0, 0, 2) - - case AMOVBU: - return LDSTR9S(0, 0, 1) - - case AFMOVS: - return LDSTR9S(2, 1, 1) - - case AFMOVD: - return LDSTR9S(3, 1, 1) +// store(immediate) +// scaled 12-bit unsigned immediate offset. +// unscaled 9-bit signed immediate offset. +// pre/post-indexed store. +// and the 12-bit and 9-bit are distinguished in olsr12u and oslr9s. +func (c *ctxt7) opstr(p *obj.Prog, a obj.As) uint32 { + enc := c.opldr(p, a) + switch p.As { + case AFMOVQ: + enc = enc &^ (1 << 22) + default: + enc = LD2STR(enc) } - - c.ctxt.Diag("bad opldr9 %v\n%v", a, p) - return 0 -} - -func (c *ctxt7) opstr9(p *obj.Prog, a obj.As) uint32 { - return LD2STR(c.opldr9(p, a)) + return enc } -func (c *ctxt7) opldrpp(p *obj.Prog, a obj.As) uint32 { +// load(immediate) +// scaled 12-bit unsigned immediate offset. +// unscaled 9-bit signed immediate offset. +// pre/post-indexed load. +// and the 12-bit and 9-bit are distinguished in olsr12u and oslr9s. +func (c *ctxt7) opldr(p *obj.Prog, a obj.As) uint32 { switch a { case AMOVD: - return 3<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 /* simm9<<12 | Rn<<5 | Rt */ + return LDSTR(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */ case AMOVW: - return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 + return LDSTR(2, 0, 2) case AMOVWU: - return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 + return LDSTR(2, 0, 1) case AMOVH: - return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 + return LDSTR(1, 0, 2) case AMOVHU: - return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 + return LDSTR(1, 0, 1) case AMOVB: - return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22 + return LDSTR(0, 0, 2) case AMOVBU: - return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 + return LDSTR(0, 0, 1) case AFMOVS: - return 2<<30 | 7<<27 | 1<<26 | 0<<24 | 1<<22 + return LDSTR(2, 1, 1) case AFMOVD: - return 3<<30 | 7<<27 | 1<<26 | 0<<24 | 1<<22 - - case APRFM: - return 0xf9<<24 | 2<<22 + return LDSTR(3, 1, 1) + case AFMOVQ: + return LDSTR(0, 1, 3) } c.ctxt.Diag("bad opldr %v\n%v", a, p) @@ -6558,14 +6885,18 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 { } else { fp, w := 0, 0 switch as { - case AFMOVS: + case AFMOVS, AVMOVS: fp = 1 w = 0 /* 32-bit SIMD/FP */ - case AFMOVD: + case AFMOVD, AVMOVD: fp = 1 w = 1 /* 64-bit SIMD/FP */ + case AVMOVQ: + fp = 1 + w = 2 /* 128-bit SIMD/FP */ + case AMOVD: if p.Pool.As == ADWORD { w = 1 /* 64-bit */ @@ -6938,10 +7269,13 @@ func (c *ctxt7) maskOpvldvst(p *obj.Prog, o1 uint32) uint32 { */ func movesize(a obj.As) int { switch a { - case AMOVD: + case AFMOVQ: + return 4 + + case AMOVD, AFMOVD: return 3 - case AMOVW, AMOVWU: + case AMOVW, AMOVWU, AFMOVS: return 2 case AMOVH, AMOVHU: @@ -6950,12 +7284,6 @@ func movesize(a obj.As) int { case AMOVB, AMOVBU: return 0 - case AFMOVS: - return 2 - - case AFMOVD: - return 3 - default: return -1 } @@ -7020,3 +7348,8 @@ func (c *ctxt7) encRegShiftOrExt(a *obj.Addr, r int16) uint32 { return 0 } + +// pack returns the encoding of the "Q" field and two arrangement specifiers. +func pack(q uint32, arngA, arngB uint8) uint32 { + return uint32(q)<<16 | uint32(arngA)<<8 | uint32(arngB) +} diff --git a/src/cmd/internal/obj/arm64/doc.go b/src/cmd/internal/obj/arm64/doc.go index 7515217544..efd4577f56 100644 --- a/src/cmd/internal/obj/arm64/doc.go +++ b/src/cmd/internal/obj/arm64/doc.go @@ -86,6 +86,16 @@ In the following example, PCALIGN at the entry of the function Add will align it MOVD $1, R1 RET +7. Move large constants to vector registers. + +Go asm uses VMOVQ/VMOVD/VMOVS to move 128-bit, 64-bit and 32-bit constants into vector registers, respectively. +And for a 128-bit interger, it take two 64-bit operands, for the high and low parts separately. + + Examples: + VMOVS $0x11223344, V0 + VMOVD $0x1122334455667788, V1 + VMOVQ $0x1122334455667788, $8877665544332211, V2 // V2=0x11223344556677888877665544332211 + Special Cases. (1) umov is written as VMOV. diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go index 56da854f16..0baf51973a 100644 --- a/src/cmd/internal/obj/arm64/obj7.go +++ b/src/cmd/internal/obj/arm64/obj7.go @@ -166,7 +166,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { end := c.ctxt.EndUnsafePoint(bls, c.newprog, -1) var last *obj.Prog - for last = c.cursym.Func.Text; last.Link != nil; last = last.Link { + for last = c.cursym.Func().Text; last.Link != nil; last = last.Link { } // Now we are at the end of the function, but logically @@ -209,7 +209,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { switch { case c.cursym.CFunc(): morestack = "runtime.morestackc" - case !c.cursym.Func.Text.From.Sym.NeedCtxt(): + case !c.cursym.Func().Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = c.ctxt.Lookup(morestack) @@ -220,7 +220,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { jmp := obj.Appendp(pcdata, c.newprog) jmp.As = AB jmp.To.Type = obj.TYPE_BRANCH - jmp.To.SetTarget(c.cursym.Func.Text.Link) + jmp.To.SetTarget(c.cursym.Func().Text.Link) jmp.Spadj = +framesize return end @@ -441,13 +441,13 @@ func (c *ctxt7) rewriteToUseGot(p *obj.Prog) { } func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } c := ctxt7{ctxt: ctxt, newprog: newprog, cursym: cursym} - p := c.cursym.Func.Text + p := c.cursym.Func().Text textstksiz := p.To.Offset if textstksiz == -8 { // Historical way to mark NOFRAME. @@ -463,13 +463,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - c.cursym.Func.Args = p.To.Val.(int32) - c.cursym.Func.Locals = int32(textstksiz) + c.cursym.Func().Args = p.To.Val.(int32) + c.cursym.Func().Locals = int32(textstksiz) /* * find leaf subroutines */ - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { switch p.As { case obj.ATEXT: p.Mark |= LEAF @@ -477,18 +477,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { case ABL, obj.ADUFFZERO, obj.ADUFFCOPY: - c.cursym.Func.Text.Mark &^= LEAF + c.cursym.Func().Text.Mark &^= LEAF } } var q *obj.Prog var q1 *obj.Prog var retjmp *obj.LSym - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { o := p.As switch o { case obj.ATEXT: - c.cursym.Func.Text = p + c.cursym.Func().Text = p c.autosize = int32(textstksiz) if p.Mark&LEAF != 0 && c.autosize == 0 { @@ -514,7 +514,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { c.ctxt.Diag("%v: unaligned frame size %d - must be 16 aligned", p, c.autosize-8) } c.autosize += extrasize - c.cursym.Func.Locals += extrasize + c.cursym.Func().Locals += extrasize // low 32 bits for autosize // high 32 bits for extrasize @@ -524,14 +524,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Offset = 0 } - if c.autosize == 0 && c.cursym.Func.Text.Mark&LEAF == 0 { + if c.autosize == 0 && c.cursym.Func().Text.Mark&LEAF == 0 { if c.ctxt.Debugvlog { - c.ctxt.Logf("save suppressed in: %s\n", c.cursym.Func.Text.From.Sym.Name) + c.ctxt.Logf("save suppressed in: %s\n", c.cursym.Func().Text.From.Sym.Name) } - c.cursym.Func.Text.Mark |= LEAF + c.cursym.Func().Text.Mark |= LEAF } - if cursym.Func.Text.Mark&LEAF != 0 { + if cursym.Func().Text.Mark&LEAF != 0 { cursym.Set(obj.AttrLeaf, true) if p.From.Sym.NoFrame() { break @@ -589,7 +589,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q1.To.Reg = REGSP q1.Spadj = c.autosize - if c.ctxt.Headtype == objabi.Hdarwin { + if objabi.GOOS == "ios" { // iOS does not support SA_ONSTACK. We will run the signal handler // on the G stack. If we write below SP, it may be clobbered by // the signal handler. So we save LR after decrementing SP. @@ -641,7 +641,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q1.To.Reg = REGFP } - if c.cursym.Func.Text.From.Sym.Wrapper() { + if c.cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOV g_panic(g), R1 @@ -755,7 +755,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { retjmp = p.To.Sym p.To = obj.Addr{} - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { if c.autosize != 0 { p.As = AADD p.From.Type = obj.TYPE_CONST diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go index 9abb31b558..87c62e2981 100644 --- a/src/cmd/internal/obj/dwarf.go +++ b/src/cmd/internal/obj/dwarf.go @@ -46,12 +46,12 @@ func (ctxt *Link) generateDebugLinesSymbol(s, lines *LSym) { // we expect at the start of a new sequence. stmt := true line := int64(1) - pc := s.Func.Text.Pc + pc := s.Func().Text.Pc var lastpc int64 // last PC written to line table, not last PC in func name := "" prologue, wrotePrologue := false, false // Walk the progs, generating the DWARF table. - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { prologue = prologue || (p.Pos.Xlogue() == src.PosPrologueEnd) // If we're not at a real instruction, keep looping! if p.Pos.Line() == 0 || (p.Link != nil && p.Link.Pc == p.Pc) { @@ -103,8 +103,9 @@ func (ctxt *Link) generateDebugLinesSymbol(s, lines *LSym) { // text address before the end sequence op. If this isn't done, // GDB will assign a line number of zero the last row in the line // table, which we don't want. - lastlen := uint64(s.Size - (lastpc - s.Func.Text.Pc)) - putpclcdelta(ctxt, dctxt, lines, lastlen, 0) + lastlen := uint64(s.Size - (lastpc - s.Func().Text.Pc)) + dctxt.AddUint8(lines, dwarf.DW_LNS_advance_pc) + dwarf.Uleb128put(dctxt, lines, int64(lastlen)) dctxt.AddUint8(lines, 0) // start extended opcode dwarf.Uleb128put(dctxt, lines, 1) dctxt.AddUint8(lines, dwarf.DW_LNE_end_sequence) @@ -301,26 +302,27 @@ func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym, if s.Type != objabi.STEXT { ctxt.Diag("dwarfSym of non-TEXT %v", s) } - if s.Func.dwarfInfoSym == nil { - s.Func.dwarfInfoSym = &LSym{ + fn := s.Func() + if fn.dwarfInfoSym == nil { + fn.dwarfInfoSym = &LSym{ Type: objabi.SDWARFFCN, } if ctxt.Flag_locationlists { - s.Func.dwarfLocSym = &LSym{ + fn.dwarfLocSym = &LSym{ Type: objabi.SDWARFLOC, } } - s.Func.dwarfRangesSym = &LSym{ + fn.dwarfRangesSym = &LSym{ Type: objabi.SDWARFRANGE, } - s.Func.dwarfDebugLinesSym = &LSym{ + fn.dwarfDebugLinesSym = &LSym{ Type: objabi.SDWARFLINES, } if s.WasInlined() { - s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s) + fn.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s) } } - return s.Func.dwarfInfoSym, s.Func.dwarfLocSym, s.Func.dwarfRangesSym, s.Func.dwarfAbsFnSym, s.Func.dwarfDebugLinesSym + return fn.dwarfInfoSym, fn.dwarfLocSym, fn.dwarfRangesSym, fn.dwarfAbsFnSym, fn.dwarfDebugLinesSym } func (s *LSym) Length(dwarfContext interface{}) int64 { @@ -331,7 +333,7 @@ func (s *LSym) Length(dwarfContext interface{}) int64 { // first instruction (prog) of the specified function. This will // presumably be the file in which the function is defined. func (ctxt *Link) fileSymbol(fn *LSym) *LSym { - p := fn.Func.Text + p := fn.Func().Text if p != nil { f, _ := linkgetlineFromPos(ctxt, p.Pos) fsym := ctxt.Lookup(f) @@ -405,8 +407,8 @@ func (ctxt *Link) DwarfAbstractFunc(curfn interface{}, s *LSym, myimportpath str if absfn.Size != 0 { ctxt.Diag("internal error: DwarfAbstractFunc double process %v", s) } - if s.Func == nil { - s.Func = new(FuncInfo) + if s.Func() == nil { + s.NewFuncInfo() } scopes, _ := ctxt.DebugInfo(s, absfn, curfn) dwctxt := dwCtxt{ctxt} @@ -527,8 +529,8 @@ func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) { // wrapper generation as opposed to the main inlining phase) it's // possible that we didn't cache the abstract function sym for the // text symbol -- do so now if needed. See issue 38068. - if s.Func != nil && s.Func.dwarfAbsFnSym == nil { - s.Func.dwarfAbsFnSym = absfn + if fn := s.Func(); fn != nil && fn.dwarfAbsFnSym == nil { + fn.dwarfAbsFnSym = absfn } ft.precursor[s] = fnState{precursor: fn, absfn: absfn} diff --git a/src/cmd/internal/obj/ld.go b/src/cmd/internal/obj/ld.go index 4ba52c7785..5d6c000dc6 100644 --- a/src/cmd/internal/obj/ld.go +++ b/src/cmd/internal/obj/ld.go @@ -59,7 +59,7 @@ func mkfwd(sym *LSym) { } i := 0 - for p := sym.Func.Text; p != nil && p.Link != nil; p = p.Link { + for p := sym.Func().Text; p != nil && p.Link != nil; p = p.Link { i-- if i < 0 { i = LOG - 1 diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index 1d4217b5f5..8c8ff587ff 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -282,29 +282,42 @@ func (a *Addr) SetTarget(t *Prog) { // The other fields not yet mentioned are for use by the back ends and should // be left zeroed by creators of Prog lists. type Prog struct { - Ctxt *Link // linker context - Link *Prog // next Prog in linked list - From Addr // first source operand - RestArgs []Addr // can pack any operands that not fit into {Prog.From, Prog.To} - To Addr // destination operand (second is RegTo2 below) - Pool *Prog // constant pool entry, for arm,arm64 back ends - Forwd *Prog // for x86 back end - Rel *Prog // for x86, arm back ends - Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase - Pos src.XPos // source position of this instruction - Spadj int32 // effect of instruction on stack pointer (increment or decrement amount) - As As // assembler opcode - Reg int16 // 2nd source operand - RegTo2 int16 // 2nd destination operand - Mark uint16 // bitmask of arch-specific items - Optab uint16 // arch-specific opcode index - Scond uint8 // bits that describe instruction suffixes (e.g. ARM conditions) - Back uint8 // for x86 back end: backwards branch state - Ft uint8 // for x86 back end: type index of Prog.From - Tt uint8 // for x86 back end: type index of Prog.To - Isize uint8 // for x86 back end: size of the instruction in bytes + Ctxt *Link // linker context + Link *Prog // next Prog in linked list + From Addr // first source operand + RestArgs []AddrPos // can pack any operands that not fit into {Prog.From, Prog.To} + To Addr // destination operand (second is RegTo2 below) + Pool *Prog // constant pool entry, for arm,arm64 back ends + Forwd *Prog // for x86 back end + Rel *Prog // for x86, arm back ends + Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase + Pos src.XPos // source position of this instruction + Spadj int32 // effect of instruction on stack pointer (increment or decrement amount) + As As // assembler opcode + Reg int16 // 2nd source operand + RegTo2 int16 // 2nd destination operand + Mark uint16 // bitmask of arch-specific items + Optab uint16 // arch-specific opcode index + Scond uint8 // bits that describe instruction suffixes (e.g. ARM conditions) + Back uint8 // for x86 back end: backwards branch state + Ft uint8 // for x86 back end: type index of Prog.From + Tt uint8 // for x86 back end: type index of Prog.To + Isize uint8 // for x86 back end: size of the instruction in bytes } +// Pos indicates whether the oprand is the source or the destination. +type AddrPos struct { + Addr + Pos OperandPos +} + +type OperandPos int8 + +const ( + Source OperandPos = iota + Destination +) + // From3Type returns p.GetFrom3().Type, or TYPE_NONE when // p.GetFrom3() returns nil. // @@ -329,15 +342,36 @@ func (p *Prog) GetFrom3() *Addr { if p.RestArgs == nil { return nil } - return &p.RestArgs[0] + return &p.RestArgs[0].Addr } -// SetFrom3 assigns []Addr{a} to p.RestArgs. +// SetFrom3 assigns []Args{{a, 0}} to p.RestArgs. // In pair with Prog.GetFrom3 it can help in emulation of Prog.From3. // // Deprecated: for the same reasons as Prog.GetFrom3. func (p *Prog) SetFrom3(a Addr) { - p.RestArgs = []Addr{a} + p.RestArgs = []AddrPos{{a, Source}} +} + +// SetTo2 assings []Args{{a, 1}} to p.RestArgs when the second destination +// operand does not fit into prog.RegTo2. +func (p *Prog) SetTo2(a Addr) { + p.RestArgs = []AddrPos{{a, Destination}} +} + +// GetTo2 returns the second destination operand. +func (p *Prog) GetTo2() *Addr { + if p.RestArgs == nil { + return nil + } + return &p.RestArgs[0].Addr +} + +// SetRestArgs assigns more than one source operands to p.RestArgs. +func (p *Prog) SetRestArgs(args []Addr) { + for i := range args { + p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source}) + } } // An As denotes an assembler opcode. @@ -395,17 +429,16 @@ type LSym struct { Type objabi.SymKind Attribute - RefIdx int // Index of this symbol in the symbol reference list. Size int64 Gotype *LSym P []byte R []Reloc - Func *FuncInfo + Extra *interface{} // *FuncInfo or *FileInfo, if present Pkg string PkgIdx int32 - SymIdx int32 // TODO: replace RefIdx + SymIdx int32 } // A FuncInfo contains extra fields for STEXT symbols. @@ -427,13 +460,59 @@ type FuncInfo struct { GCArgs *LSym GCLocals *LSym - GCRegs *LSym // Only if !go115ReduceLiveness StackObjects *LSym OpenCodedDeferInfo *LSym FuncInfoSym *LSym } +// NewFuncInfo allocates and returns a FuncInfo for LSym. +func (s *LSym) NewFuncInfo() *FuncInfo { + if s.Extra != nil { + panic(fmt.Sprintf("invalid use of LSym - NewFuncInfo with Extra of type %T", *s.Extra)) + } + f := new(FuncInfo) + s.Extra = new(interface{}) + *s.Extra = f + return f +} + +// Func returns the *FuncInfo associated with s, or else nil. +func (s *LSym) Func() *FuncInfo { + if s.Extra == nil { + return nil + } + f, _ := (*s.Extra).(*FuncInfo) + return f +} + +// A FileInfo contains extra fields for SDATA symbols backed by files. +// (If LSym.Extra is a *FileInfo, LSym.P == nil.) +type FileInfo struct { + Name string // name of file to read into object file + Size int64 // length of file +} + +// NewFileInfo allocates and returns a FileInfo for LSym. +func (s *LSym) NewFileInfo() *FileInfo { + if s.Extra != nil { + panic(fmt.Sprintf("invalid use of LSym - NewFileInfo with Extra of type %T", *s.Extra)) + } + f := new(FileInfo) + s.Extra = new(interface{}) + *s.Extra = f + return f +} + +// File returns the *FileInfo associated with s, or else nil. +func (s *LSym) File() *FileInfo { + if s.Extra == nil { + return nil + } + f, _ := (*s.Extra).(*FileInfo) + return f +} + type InlMark struct { // When unwinding from an instruction in an inlined body, mark // where we should unwind to. @@ -482,6 +561,20 @@ const ( ABICount ) +// ParseABI converts from a string representation in 'abistr' to the +// corresponding ABI value. Second return value is TRUE if the +// abi string is recognized, FALSE otherwise. +func ParseABI(abistr string) (ABI, bool) { + switch abistr { + default: + return ABI0, false + case "ABI0": + return ABI0, true + case "ABIInternal": + return ABIInternal, true + } +} + // Attribute is a set of symbol attributes. type Attribute uint32 @@ -634,11 +727,12 @@ func (s *LSym) CanBeAnSSASym() { } type Pcln struct { - Pcsp Pcdata - Pcfile Pcdata - Pcline Pcdata - Pcinline Pcdata - Pcdata []Pcdata + // Aux symbols for pcln + Pcsp *LSym + Pcfile *LSym + Pcline *LSym + Pcinline *LSym + Pcdata []*LSym Funcdata []*LSym Funcdataoff []int64 UsedFiles map[goobj.CUFileIndex]struct{} // file indices used while generating pcfile @@ -660,10 +754,6 @@ type Auto struct { Gotype *LSym } -type Pcdata struct { - P []byte -} - // Link holds the context for writing object code from a compiler // to be linker input or for reading that input into the linker. type Link struct { diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go index 6107974745..fd29f9fa21 100644 --- a/src/cmd/internal/obj/mips/asm0.go +++ b/src/cmd/internal/obj/mips/asm0.go @@ -410,7 +410,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ctxt.Retpoline = false // don't keep printing } - p := cursym.Func.Text + p := cursym.Func().Text if p == nil || p.Link == nil { // handle external functions and ELF section symbols return } @@ -455,7 +455,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { for bflag != 0 { bflag = 0 pc = 0 - for p = c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p = c.cursym.Func().Text.Link; p != nil; p = p.Link { p.Pc = pc o = c.oplook(p) @@ -512,7 +512,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { bp := c.cursym.P var i int32 var out [4]uint32 - for p := c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { c.pc = p.Pc o = c.oplook(p) if int(o.size) > 4*len(out) { @@ -529,7 +529,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // We use REGTMP as a scratch register during call injection, // so instruction sequences that use REGTMP are unsafe to // preempt asynchronously. - obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, c.isRestartable) + obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable) } // isUnsafePoint returns whether p is an unsafe point. @@ -1302,7 +1302,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { } o1 = OP_JMP(c.opirr(p.As), uint32(v)) if p.To.Sym == nil { - p.To.Sym = c.cursym.Func.Text.From.Sym + p.To.Sym = c.cursym.Func().Text.From.Sym p.To.Offset = p.To.Target().Pc } rel := obj.Addrel(c.cursym) diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go index f19facc00c..135a8df3aa 100644 --- a/src/cmd/internal/obj/mips/obj0.go +++ b/src/cmd/internal/obj/mips/obj0.go @@ -133,11 +133,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // a switch for enabling/disabling instruction scheduling nosched := true - if c.cursym.Func.Text == nil || c.cursym.Func.Text.Link == nil { + if c.cursym.Func().Text == nil || c.cursym.Func().Text.Link == nil { return } - p := c.cursym.Func.Text + p := c.cursym.Func().Text textstksiz := p.To.Offset if textstksiz == -ctxt.FixedFrameSize() { // Historical way to mark NOFRAME. @@ -153,8 +153,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - c.cursym.Func.Args = p.To.Val.(int32) - c.cursym.Func.Locals = int32(textstksiz) + c.cursym.Func().Args = p.To.Val.(int32) + c.cursym.Func().Locals = int32(textstksiz) /* * find leaf subroutines @@ -162,7 +162,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { * expand BECOME pseudo */ - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { switch p.As { /* too hard, just leave alone */ case obj.ATEXT: @@ -203,7 +203,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { AJAL, obj.ADUFFZERO, obj.ADUFFCOPY: - c.cursym.Func.Text.Mark &^= LEAF + c.cursym.Func().Text.Mark &^= LEAF fallthrough case AJMP, @@ -267,7 +267,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { autosize := int32(0) var p1 *obj.Prog var p2 *obj.Prog - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { o := p.As switch o { case obj.ATEXT: @@ -288,19 +288,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { autosize += 4 } - if autosize == 0 && c.cursym.Func.Text.Mark&LEAF == 0 { - if c.cursym.Func.Text.From.Sym.NoSplit() { + if autosize == 0 && c.cursym.Func().Text.Mark&LEAF == 0 { + if c.cursym.Func().Text.From.Sym.NoSplit() { if ctxt.Debugvlog { ctxt.Logf("save suppressed in: %s\n", c.cursym.Name) } - c.cursym.Func.Text.Mark |= LEAF + c.cursym.Func().Text.Mark |= LEAF } } p.To.Offset = int64(autosize) - ctxt.FixedFrameSize() - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { c.cursym.Set(obj.AttrLeaf, true) if p.From.Sym.NoFrame() { break @@ -344,7 +344,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) } - if c.cursym.Func.Text.From.Sym.Wrapper() && c.cursym.Func.Text.Mark&LEAF == 0 { + if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOV g_panic(g), R1 @@ -438,7 +438,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Name = obj.NAME_NONE // clear fields as we may modify p to other instruction p.To.Sym = nil - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { if autosize == 0 { p.As = AJMP p.From = obj.Addr{} @@ -540,7 +540,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if c.ctxt.Arch.Family == sys.MIPS { // rewrite MOVD into two MOVF in 32-bit mode to avoid unaligned memory access - for p = c.cursym.Func.Text; p != nil; p = p1 { + for p = c.cursym.Func().Text; p != nil; p = p1 { p1 = p.Link if p.As != AMOVD { @@ -580,7 +580,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if nosched { // if we don't do instruction scheduling, simply add // NOP after each branch instruction. - for p = c.cursym.Func.Text; p != nil; p = p.Link { + for p = c.cursym.Func().Text; p != nil; p = p.Link { if p.Mark&BRANCH != 0 { c.addnop(p) } @@ -589,10 +589,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } // instruction scheduling - q = nil // p - 1 - q1 = c.cursym.Func.Text // top of block - o := 0 // count of instructions - for p = c.cursym.Func.Text; p != nil; p = p1 { + q = nil // p - 1 + q1 = c.cursym.Func().Text // top of block + o := 0 // count of instructions + for p = c.cursym.Func().Text; p != nil; p = p1 { p1 = p.Link o++ if p.Mark&NOSCHED != 0 { @@ -791,7 +791,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.To.Type = obj.TYPE_BRANCH if c.cursym.CFunc() { p.To.Sym = c.ctxt.Lookup("runtime.morestackc") - } else if !c.cursym.Func.Text.From.Sym.NeedCtxt() { + } else if !c.cursym.Func().Text.From.Sym.NeedCtxt() { p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt") } else { p.To.Sym = c.ctxt.Lookup("runtime.morestack") @@ -805,7 +805,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.As = AJMP p.To.Type = obj.TYPE_BRANCH - p.To.SetTarget(c.cursym.Func.Text.Link) + p.To.SetTarget(c.cursym.Func().Text.Link) p.Mark |= BRANCH // placeholder for q1's jump target diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 7bc4f4992e..bb58b4f0c2 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -16,6 +16,8 @@ import ( "encoding/binary" "fmt" "io" + "log" + "os" "path/filepath" "sort" "strings" @@ -147,14 +149,20 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { // Data indexes h.Offsets[goobj.BlkDataIdx] = w.Offset() - dataOff := uint32(0) + dataOff := int64(0) for _, list := range lists { for _, s := range list { - w.Uint32(dataOff) - dataOff += uint32(len(s.P)) + w.Uint32(uint32(dataOff)) + dataOff += int64(len(s.P)) + if file := s.File(); file != nil { + dataOff += int64(file.Size) + } } } - w.Uint32(dataOff) + if int64(uint32(dataOff)) != dataOff { + log.Fatalf("data too large") + } + w.Uint32(uint32(dataOff)) // Relocs h.Offsets[goobj.BlkReloc] = w.Offset() @@ -179,14 +187,21 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { for _, list := range lists { for _, s := range list { w.Bytes(s.P) + if file := s.File(); file != nil { + w.writeFile(ctxt, file) + } } } // Pcdata h.Offsets[goobj.BlkPcdata] = w.Offset() for _, s := range ctxt.Text { // iteration order must match genFuncInfoSyms - if s.Func != nil { - pc := &s.Func.Pcln + // Because of the phase order, it's possible that we try to write an invalid + // object file, and the Pcln variables haven't been filled in. As such, we + // need to check that Pcsp exists, and assume the other pcln variables exist + // as well. Tests like test/fixedbugs/issue22200.go demonstrate this issue. + if fn := s.Func(); fn != nil && fn.Pcln.Pcsp != nil { + pc := &fn.Pcln w.Bytes(pc.Pcsp.P) w.Bytes(pc.Pcfile.P) w.Bytes(pc.Pcline.P) @@ -214,6 +229,7 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { type writer struct { *goobj.Writer + filebuf []byte ctxt *Link pkgpath string // the package import path (escaped), "" if unknown pkglist []string // list of packages referenced, indexed by ctxt.pkgIdx @@ -228,6 +244,35 @@ func (w *writer) init() { } } +func (w *writer) writeFile(ctxt *Link, file *FileInfo) { + f, err := os.Open(file.Name) + if err != nil { + ctxt.Diag("%v", err) + return + } + defer f.Close() + if w.filebuf == nil { + w.filebuf = make([]byte, 1024) + } + buf := w.filebuf + written := int64(0) + for { + n, err := f.Read(buf) + w.Bytes(buf[:n]) + written += int64(n) + if err == io.EOF { + break + } + if err != nil { + ctxt.Diag("%v", err) + return + } + } + if written != file.Size { + ctxt.Diag("copy %s: unexpected length %d != %d", file.Name, written, file.Size) + } +} + func (w *writer) StringTable() { w.AddString("") for _, p := range w.ctxt.Imports { @@ -257,6 +302,10 @@ func (w *writer) StringTable() { } } +// cutoff is the maximum data section size permitted by the linker +// (see issue #9862). +const cutoff = int64(2e9) // 2 GB (or so; looks better in errors than 2^31) + func (w *writer) Sym(s *LSym) { abi := uint16(s.ABI()) if s.Static() { @@ -299,8 +348,8 @@ func (w *writer) Sym(s *LSym) { name = filepath.ToSlash(name) } var align uint32 - if s.Func != nil { - align = uint32(s.Func.Align) + if fn := s.Func(); fn != nil { + align = uint32(fn.Align) } if s.ContentAddressable() { // We generally assume data symbols are natually aligned, @@ -321,6 +370,9 @@ func (w *writer) Sym(s *LSym) { // don't bother setting align to 1. } } + if s.Size > cutoff { + w.ctxt.Diag("%s: symbol too large (%d bytes > %d bytes)", s.Name, s.Size, cutoff) + } var o goobj.Sym o.SetName(name, w.Writer) o.SetABI(abi) @@ -372,10 +424,29 @@ func contentHash64(s *LSym) goobj.Hash64Type { // hashed symbols. func (w *writer) contentHash(s *LSym) goobj.HashType { h := sha1.New() + var tmp [14]byte + + // Include the size of the symbol in the hash. + // This preserves the length of symbols, preventing the following two symbols + // from hashing the same: + // + // [2]int{1,2} ≠ [10]int{1,2,0,0,0...} + // + // In this case, if the smaller symbol is alive, the larger is not kept unless + // needed. + binary.LittleEndian.PutUint64(tmp[:8], uint64(s.Size)) + h.Write(tmp[:8]) + + // Don't dedup type symbols with others, as they are in a different + // section. + if strings.HasPrefix(s.Name, "type.") { + h.Write([]byte{'T'}) + } else { + h.Write([]byte{0}) + } // The compiler trims trailing zeros _sometimes_. We just do // it always. h.Write(bytes.TrimRight(s.P, "\x00")) - var tmp [14]byte for i := range s.R { r := &s.R[i] binary.LittleEndian.PutUint32(tmp[:4], uint32(r.Off)) @@ -447,25 +518,41 @@ func (w *writer) Aux(s *LSym) { if s.Gotype != nil { w.aux1(goobj.AuxGotype, s.Gotype) } - if s.Func != nil { - w.aux1(goobj.AuxFuncInfo, s.Func.FuncInfoSym) + if fn := s.Func(); fn != nil { + w.aux1(goobj.AuxFuncInfo, fn.FuncInfoSym) - for _, d := range s.Func.Pcln.Funcdata { + for _, d := range fn.Pcln.Funcdata { w.aux1(goobj.AuxFuncdata, d) } - if s.Func.dwarfInfoSym != nil && s.Func.dwarfInfoSym.Size != 0 { - w.aux1(goobj.AuxDwarfInfo, s.Func.dwarfInfoSym) + if fn.dwarfInfoSym != nil && fn.dwarfInfoSym.Size != 0 { + w.aux1(goobj.AuxDwarfInfo, fn.dwarfInfoSym) } - if s.Func.dwarfLocSym != nil && s.Func.dwarfLocSym.Size != 0 { - w.aux1(goobj.AuxDwarfLoc, s.Func.dwarfLocSym) + if fn.dwarfLocSym != nil && fn.dwarfLocSym.Size != 0 { + w.aux1(goobj.AuxDwarfLoc, fn.dwarfLocSym) } - if s.Func.dwarfRangesSym != nil && s.Func.dwarfRangesSym.Size != 0 { - w.aux1(goobj.AuxDwarfRanges, s.Func.dwarfRangesSym) + if fn.dwarfRangesSym != nil && fn.dwarfRangesSym.Size != 0 { + w.aux1(goobj.AuxDwarfRanges, fn.dwarfRangesSym) } - if s.Func.dwarfDebugLinesSym != nil && s.Func.dwarfDebugLinesSym.Size != 0 { - w.aux1(goobj.AuxDwarfLines, s.Func.dwarfDebugLinesSym) + if fn.dwarfDebugLinesSym != nil && fn.dwarfDebugLinesSym.Size != 0 { + w.aux1(goobj.AuxDwarfLines, fn.dwarfDebugLinesSym) } + if fn.Pcln.Pcsp != nil && fn.Pcln.Pcsp.Size != 0 { + w.aux1(goobj.AuxPcsp, fn.Pcln.Pcsp) + } + if fn.Pcln.Pcfile != nil && fn.Pcln.Pcfile.Size != 0 { + w.aux1(goobj.AuxPcfile, fn.Pcln.Pcfile) + } + if fn.Pcln.Pcline != nil && fn.Pcln.Pcline.Size != 0 { + w.aux1(goobj.AuxPcline, fn.Pcln.Pcline) + } + if fn.Pcln.Pcinline != nil && fn.Pcln.Pcinline.Size != 0 { + w.aux1(goobj.AuxPcinline, fn.Pcln.Pcinline) + } + for _, pcSym := range fn.Pcln.Pcdata { + w.aux1(goobj.AuxPcdata, pcSym) + } + } } @@ -532,21 +619,34 @@ func nAuxSym(s *LSym) int { if s.Gotype != nil { n++ } - if s.Func != nil { + if fn := s.Func(); fn != nil { // FuncInfo is an aux symbol, each Funcdata is an aux symbol - n += 1 + len(s.Func.Pcln.Funcdata) - if s.Func.dwarfInfoSym != nil && s.Func.dwarfInfoSym.Size != 0 { + n += 1 + len(fn.Pcln.Funcdata) + if fn.dwarfInfoSym != nil && fn.dwarfInfoSym.Size != 0 { + n++ + } + if fn.dwarfLocSym != nil && fn.dwarfLocSym.Size != 0 { + n++ + } + if fn.dwarfRangesSym != nil && fn.dwarfRangesSym.Size != 0 { n++ } - if s.Func.dwarfLocSym != nil && s.Func.dwarfLocSym.Size != 0 { + if fn.dwarfDebugLinesSym != nil && fn.dwarfDebugLinesSym.Size != 0 { n++ } - if s.Func.dwarfRangesSym != nil && s.Func.dwarfRangesSym.Size != 0 { + if fn.Pcln.Pcsp != nil && fn.Pcln.Pcsp.Size != 0 { n++ } - if s.Func.dwarfDebugLinesSym != nil && s.Func.dwarfDebugLinesSym.Size != 0 { + if fn.Pcln.Pcfile != nil && fn.Pcln.Pcfile.Size != 0 { n++ } + if fn.Pcln.Pcline != nil && fn.Pcln.Pcline.Size != 0 { + n++ + } + if fn.Pcln.Pcinline != nil && fn.Pcln.Pcinline.Size != 0 { + n++ + } + n += len(fn.Pcln.Pcdata) } return n } @@ -554,33 +654,38 @@ func nAuxSym(s *LSym) int { // generate symbols for FuncInfo. func genFuncInfoSyms(ctxt *Link) { infosyms := make([]*LSym, 0, len(ctxt.Text)) - var pcdataoff uint32 + hashedsyms := make([]*LSym, 0, 4*len(ctxt.Text)) + preparePcSym := func(s *LSym) *LSym { + if s == nil { + return s + } + s.PkgIdx = goobj.PkgIdxHashed + s.SymIdx = int32(len(hashedsyms) + len(ctxt.hasheddefs)) + s.Set(AttrIndexed, true) + hashedsyms = append(hashedsyms, s) + return s + } var b bytes.Buffer symidx := int32(len(ctxt.defs)) for _, s := range ctxt.Text { - if s.Func == nil { + fn := s.Func() + if fn == nil { continue } o := goobj.FuncInfo{ - Args: uint32(s.Func.Args), - Locals: uint32(s.Func.Locals), - FuncID: objabi.FuncID(s.Func.FuncID), + Args: uint32(fn.Args), + Locals: uint32(fn.Locals), + FuncID: objabi.FuncID(fn.FuncID), } - pc := &s.Func.Pcln - o.Pcsp = pcdataoff - pcdataoff += uint32(len(pc.Pcsp.P)) - o.Pcfile = pcdataoff - pcdataoff += uint32(len(pc.Pcfile.P)) - o.Pcline = pcdataoff - pcdataoff += uint32(len(pc.Pcline.P)) - o.Pcinline = pcdataoff - pcdataoff += uint32(len(pc.Pcinline.P)) - o.Pcdata = make([]uint32, len(pc.Pcdata)) - for i, pcd := range pc.Pcdata { - o.Pcdata[i] = pcdataoff - pcdataoff += uint32(len(pcd.P)) + pc := &fn.Pcln + o.Pcsp = makeSymRef(preparePcSym(pc.Pcsp)) + o.Pcfile = makeSymRef(preparePcSym(pc.Pcfile)) + o.Pcline = makeSymRef(preparePcSym(pc.Pcline)) + o.Pcinline = makeSymRef(preparePcSym(pc.Pcinline)) + o.Pcdata = make([]goobj.SymRef, len(pc.Pcdata)) + for i, pcSym := range pc.Pcdata { + o.Pcdata[i] = makeSymRef(preparePcSym(pcSym)) } - o.PcdataEnd = pcdataoff o.Funcdataoff = make([]uint32, len(pc.Funcdataoff)) for i, x := range pc.Funcdataoff { o.Funcdataoff[i] = uint32(x) @@ -614,10 +719,10 @@ func genFuncInfoSyms(ctxt *Link) { isym.Set(AttrIndexed, true) symidx++ infosyms = append(infosyms, isym) - s.Func.FuncInfoSym = isym + fn.FuncInfoSym = isym b.Reset() - dwsyms := []*LSym{s.Func.dwarfRangesSym, s.Func.dwarfLocSym, s.Func.dwarfDebugLinesSym, s.Func.dwarfInfoSym} + dwsyms := []*LSym{fn.dwarfRangesSym, fn.dwarfLocSym, fn.dwarfDebugLinesSym, fn.dwarfInfoSym} for _, s := range dwsyms { if s == nil || s.Size == 0 { continue @@ -630,9 +735,9 @@ func genFuncInfoSyms(ctxt *Link) { } } ctxt.defs = append(ctxt.defs, infosyms...) + ctxt.hasheddefs = append(ctxt.hasheddefs, hashedsyms...) } -// debugDumpAux is a dumper for selected aux symbols. func writeAuxSymDebug(ctxt *Link, par *LSym, aux *LSym) { // Most aux symbols (ex: funcdata) are not interesting-- // pick out just the DWARF ones for now. @@ -663,7 +768,11 @@ func (ctxt *Link) writeSymDebug(s *LSym) { } func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) { - fmt.Fprintf(ctxt.Bso, "%s ", name) + ver := "" + if ctxt.Debugasm > 1 { + ver = fmt.Sprintf("<%d>", s.ABI()) + } + fmt.Fprintf(ctxt.Bso, "%s%s ", name, ver) if s.Type != 0 { fmt.Fprintf(ctxt.Bso, "%v ", s.Type) } @@ -684,14 +793,15 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) { } fmt.Fprintf(ctxt.Bso, "size=%d", s.Size) if s.Type == objabi.STEXT { - fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x funcid=%#x", uint64(s.Func.Args), uint64(s.Func.Locals), uint64(s.Func.FuncID)) + fn := s.Func() + fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x funcid=%#x", uint64(fn.Args), uint64(fn.Locals), uint64(fn.FuncID)) if s.Leaf() { fmt.Fprintf(ctxt.Bso, " leaf") } } fmt.Fprintf(ctxt.Bso, "\n") if s.Type == objabi.STEXT { - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { fmt.Fprintf(ctxt.Bso, "\t%#04x ", uint(int(p.Pc))) if ctxt.Debugasm > 1 { io.WriteString(ctxt.Bso, p.String()) @@ -726,15 +836,19 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) { sort.Sort(relocByOff(s.R)) // generate stable output for _, r := range s.R { name := "" + ver := "" if r.Sym != nil { name = r.Sym.Name + if ctxt.Debugasm > 1 { + ver = fmt.Sprintf("<%d>", r.Sym.ABI()) + } } else if r.Type == objabi.R_TLS_LE { name = "TLS" } if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add)) + fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s%s+%x\n", int(r.Off), r.Siz, r.Type, name, ver, uint64(r.Add)) } else { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add) + fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s%s+%d\n", int(r.Off), r.Siz, r.Type, name, ver, r.Add) } } } diff --git a/src/cmd/internal/obj/objfile_test.go b/src/cmd/internal/obj/objfile_test.go index 155701fa4e..146627b62b 100644 --- a/src/cmd/internal/obj/objfile_test.go +++ b/src/cmd/internal/obj/objfile_test.go @@ -5,9 +5,16 @@ package obj import ( + "bytes" "cmd/internal/goobj" "cmd/internal/sys" + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" "testing" + "unsafe" ) var dummyArch = LinkArch{Arch: sys.ArchAMD64} @@ -85,3 +92,32 @@ func TestContentHash(t *testing.T) { } } } + +func TestSymbolTooLarge(t *testing.T) { // Issue 42054 + testenv.MustHaveGoBuild(t) + if unsafe.Sizeof(uintptr(0)) < 8 { + t.Skip("skip on 32-bit architectures") + } + + tmpdir, err := ioutil.TempDir("", "TestSymbolTooLarge") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "p.go") + err = ioutil.WriteFile(src, []byte("package p; var x [1<<32]byte"), 0666) + if err != nil { + t.Fatalf("failed to write source file: %v\n", err) + } + obj := filepath.Join(tmpdir, "p.o") + cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src) + out, err := cmd.CombinedOutput() + if err == nil { + t.Fatalf("did not fail\noutput: %s", out) + } + const want = "symbol too large" + if !bytes.Contains(out, []byte(want)) { + t.Errorf("unexpected error message: want: %q, got: %s", want, out) + } +} diff --git a/src/cmd/internal/obj/pass.go b/src/cmd/internal/obj/pass.go index 09d520b4e9..01657dd4f6 100644 --- a/src/cmd/internal/obj/pass.go +++ b/src/cmd/internal/obj/pass.go @@ -118,7 +118,7 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) { } func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) { - for p := sym.Func.Text; p != nil; p = p.Link { + for p := sym.Func().Text; p != nil; p = p.Link { checkaddr(ctxt, p, &p.From) if p.GetFrom3() != nil { checkaddr(ctxt, p, p.GetFrom3()) @@ -138,7 +138,7 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) { if p.To.Sym != nil { continue } - q := sym.Func.Text + q := sym.Func().Text for q != nil && p.To.Offset != q.Pc { if q.Forwd != nil && p.To.Offset >= q.Forwd.Pc { q = q.Forwd @@ -164,7 +164,7 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) { } // Collapse series of jumps to jumps. - for p := sym.Func.Text; p != nil; p = p.Link { + for p := sym.Func().Text; p != nil; p = p.Link { if p.To.Target() == nil { continue } diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go index bffeda041d..67c4f9a62b 100644 --- a/src/cmd/internal/obj/pcln.go +++ b/src/cmd/internal/obj/pcln.go @@ -6,6 +6,7 @@ package obj import ( "cmd/internal/goobj" + "cmd/internal/objabi" "encoding/binary" "log" ) @@ -14,16 +15,19 @@ import ( // returned by valfunc parameterized by arg. The invocation of valfunc to update the // current value is, for each p, // -// val = valfunc(func, val, p, 0, arg); -// record val as value at p->pc; -// val = valfunc(func, val, p, 1, arg); +// sym = valfunc(func, p, 0, arg); +// record sym.P as value at p->pc; +// sym = valfunc(func, p, 1, arg); // // where func is the function, val is the current value, p is the instruction being // considered, and arg can be used to further parameterize valfunc. -func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) { +func funcpctab(ctxt *Link, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) *LSym { dbg := desc == ctxt.Debugpcln - - dst.P = dst.P[:0] + dst := []byte{} + sym := &LSym{ + Type: objabi.SRODATA, + Attribute: AttrContentAddressable, + } if dbg { ctxt.Logf("funcpctab %s [valfunc=%s]\n", func_.Name, desc) @@ -31,19 +35,21 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* val := int32(-1) oldval := val - if func_.Func.Text == nil { - return + fn := func_.Func() + if fn.Text == nil { + // Return the emtpy symbol we've built so far. + return sym } - pc := func_.Func.Text.Pc + pc := fn.Text.Pc if dbg { - ctxt.Logf("%6x %6d %v\n", uint64(pc), val, func_.Func.Text) + ctxt.Logf("%6x %6d %v\n", uint64(pc), val, fn.Text) } buf := make([]byte, binary.MaxVarintLen32) started := false - for p := func_.Func.Text; p != nil; p = p.Link { + for p := fn.Text; p != nil; p = p.Link { // Update val. If it's not changing, keep going. val = valfunc(ctxt, func_, val, p, 0, arg) @@ -88,13 +94,13 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* if started { pcdelta := (p.Pc - pc) / int64(ctxt.Arch.MinLC) n := binary.PutUvarint(buf, uint64(pcdelta)) - dst.P = append(dst.P, buf[:n]...) + dst = append(dst, buf[:n]...) pc = p.Pc } delta := val - oldval n := binary.PutVarint(buf, int64(delta)) - dst.P = append(dst.P, buf[:n]...) + dst = append(dst, buf[:n]...) oldval = val started = true val = valfunc(ctxt, func_, val, p, 1, arg) @@ -102,25 +108,29 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* if started { if dbg { - ctxt.Logf("%6x done\n", uint64(func_.Func.Text.Pc+func_.Size)) + ctxt.Logf("%6x done\n", uint64(fn.Text.Pc+func_.Size)) } v := (func_.Size - pc) / int64(ctxt.Arch.MinLC) if v < 0 { ctxt.Diag("negative pc offset: %v", v) } n := binary.PutUvarint(buf, uint64(v)) - dst.P = append(dst.P, buf[:n]...) + dst = append(dst, buf[:n]...) // add terminating varint-encoded 0, which is just 0 - dst.P = append(dst.P, 0) + dst = append(dst, 0) } if dbg { - ctxt.Logf("wrote %d bytes to %p\n", len(dst.P), dst) - for _, p := range dst.P { + ctxt.Logf("wrote %d bytes to %p\n", len(dst), dst) + for _, p := range dst { ctxt.Logf(" %02x", p) } ctxt.Logf("\n") } + + sym.Size = int64(len(dst)) + sym.P = dst + return sym } // pctofileline computes either the file number (arg == 0) @@ -248,12 +258,12 @@ func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg i } func linkpcln(ctxt *Link, cursym *LSym) { - pcln := &cursym.Func.Pcln + pcln := &cursym.Func().Pcln pcln.UsedFiles = make(map[goobj.CUFileIndex]struct{}) npcdata := 0 nfuncdata := 0 - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { // Find the highest ID of any used PCDATA table. This ignores PCDATA table // that consist entirely of "-1", since that's the assumed default value. // From.Offset is table ID @@ -268,23 +278,23 @@ func linkpcln(ctxt *Link, cursym *LSym) { } } - pcln.Pcdata = make([]Pcdata, npcdata) - pcln.Pcdata = pcln.Pcdata[:npcdata] + pcln.Pcdata = make([]*LSym, npcdata) pcln.Funcdata = make([]*LSym, nfuncdata) pcln.Funcdataoff = make([]int64, nfuncdata) pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata] - funcpctab(ctxt, &pcln.Pcsp, cursym, "pctospadj", pctospadj, nil) - funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln) - funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil) + pcln.Pcsp = funcpctab(ctxt, cursym, "pctospadj", pctospadj, nil) + pcln.Pcfile = funcpctab(ctxt, cursym, "pctofile", pctofileline, pcln) + pcln.Pcline = funcpctab(ctxt, cursym, "pctoline", pctofileline, nil) // Check that all the Progs used as inline markers are still reachable. // See issue #40473. - inlMarkProgs := make(map[*Prog]struct{}, len(cursym.Func.InlMarks)) - for _, inlMark := range cursym.Func.InlMarks { + fn := cursym.Func() + inlMarkProgs := make(map[*Prog]struct{}, len(fn.InlMarks)) + for _, inlMark := range fn.InlMarks { inlMarkProgs[inlMark.p] = struct{}{} } - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := fn.Text; p != nil; p = p.Link { if _, ok := inlMarkProgs[p]; ok { delete(inlMarkProgs, p) } @@ -294,8 +304,8 @@ func linkpcln(ctxt *Link, cursym *LSym) { } pcinlineState := new(pcinlineState) - funcpctab(ctxt, &pcln.Pcinline, cursym, "pctoinline", pcinlineState.pctoinline, nil) - for _, inlMark := range cursym.Func.InlMarks { + pcln.Pcinline = funcpctab(ctxt, cursym, "pctoinline", pcinlineState.pctoinline, nil) + for _, inlMark := range fn.InlMarks { pcinlineState.setParentPC(ctxt, int(inlMark.id), int32(inlMark.p.Pc)) } pcln.InlTree = pcinlineState.localTree @@ -308,7 +318,7 @@ func linkpcln(ctxt *Link, cursym *LSym) { // tabulate which pc and func data we have. havepc := make([]uint32, (npcdata+31)/32) havefunc := make([]uint32, (nfuncdata+31)/32) - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := fn.Text; p != nil; p = p.Link { if p.As == AFUNCDATA { if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 { ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset) @@ -324,14 +334,19 @@ func linkpcln(ctxt *Link, cursym *LSym) { // pcdata. for i := 0; i < npcdata; i++ { if (havepc[i/32]>>uint(i%32))&1 == 0 { - continue + // use an empty symbol. + pcln.Pcdata[i] = &LSym{ + Type: objabi.SRODATA, + Attribute: AttrContentAddressable, + } + } else { + pcln.Pcdata[i] = funcpctab(ctxt, cursym, "pctopcdata", pctopcdata, interface{}(uint32(i))) } - funcpctab(ctxt, &pcln.Pcdata[i], cursym, "pctopcdata", pctopcdata, interface{}(uint32(i))) } // funcdata if nfuncdata > 0 { - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := fn.Text; p != nil; p = p.Link { if p.As != AFUNCDATA { continue } diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go index 6e33f29959..2b096996f7 100644 --- a/src/cmd/internal/obj/plist.go +++ b/src/cmd/internal/obj/plist.go @@ -81,7 +81,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string continue } found := false - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == objabi.FUNCDATA_ArgsPointerMaps { found = true break @@ -89,7 +89,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string } if !found { - p := Appendp(s.Func.Text, newprog) + p := Appendp(s.Func().Text, newprog) p.As = AFUNCDATA p.From.Type = TYPE_CONST p.From.Offset = objabi.FUNCDATA_ArgsPointerMaps @@ -120,15 +120,15 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) { // func _() { } return } - if s.Func != nil { + if s.Func() != nil { ctxt.Diag("InitTextSym double init for %s", s.Name) } - s.Func = new(FuncInfo) + s.NewFuncInfo() if s.OnList() { ctxt.Diag("symbol %s listed multiple times", s.Name) } name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1) - s.Func.FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0) + s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0) s.Set(AttrOnList, true) s.Set(AttrDuplicateOK, flag&DUPOK != 0) s.Set(AttrNoSplit, flag&NOSPLIT != 0) @@ -178,14 +178,14 @@ func (ctxt *Link) Globl(s *LSym, size int64, flag int) { // Prog generated. func (ctxt *Link) EmitEntryLiveness(s *LSym, p *Prog, newprog ProgAlloc) *Prog { pcdata := ctxt.EmitEntryStackMap(s, p, newprog) - pcdata = ctxt.EmitEntryRegMap(s, pcdata, newprog) + pcdata = ctxt.EmitEntryUnsafePoint(s, pcdata, newprog) return pcdata } // Similar to EmitEntryLiveness, but just emit stack map. func (ctxt *Link) EmitEntryStackMap(s *LSym, p *Prog, newprog ProgAlloc) *Prog { pcdata := Appendp(p, newprog) - pcdata.Pos = s.Func.Text.Pos + pcdata.Pos = s.Func().Text.Pos pcdata.As = APCDATA pcdata.From.Type = TYPE_CONST pcdata.From.Offset = objabi.PCDATA_StackMapIndex @@ -195,13 +195,13 @@ func (ctxt *Link) EmitEntryStackMap(s *LSym, p *Prog, newprog ProgAlloc) *Prog { return pcdata } -// Similar to EmitEntryLiveness, but just emit register map. -func (ctxt *Link) EmitEntryRegMap(s *LSym, p *Prog, newprog ProgAlloc) *Prog { +// Similar to EmitEntryLiveness, but just emit unsafe point map. +func (ctxt *Link) EmitEntryUnsafePoint(s *LSym, p *Prog, newprog ProgAlloc) *Prog { pcdata := Appendp(p, newprog) - pcdata.Pos = s.Func.Text.Pos + pcdata.Pos = s.Func().Text.Pos pcdata.As = APCDATA pcdata.From.Type = TYPE_CONST - pcdata.From.Offset = objabi.PCDATA_RegMapIndex + pcdata.From.Offset = objabi.PCDATA_UnsafePoint pcdata.To.Type = TYPE_CONST pcdata.To.Offset = -1 @@ -216,9 +216,9 @@ func (ctxt *Link) StartUnsafePoint(p *Prog, newprog ProgAlloc) *Prog { pcdata := Appendp(p, newprog) pcdata.As = APCDATA pcdata.From.Type = TYPE_CONST - pcdata.From.Offset = objabi.PCDATA_RegMapIndex + pcdata.From.Offset = objabi.PCDATA_UnsafePoint pcdata.To.Type = TYPE_CONST - pcdata.To.Offset = objabi.PCDATA_RegMapUnsafe + pcdata.To.Offset = objabi.PCDATA_UnsafePointUnsafe return pcdata } @@ -231,7 +231,7 @@ func (ctxt *Link) EndUnsafePoint(p *Prog, newprog ProgAlloc, oldval int64) *Prog pcdata := Appendp(p, newprog) pcdata.As = APCDATA pcdata.From.Type = TYPE_CONST - pcdata.From.Offset = objabi.PCDATA_RegMapIndex + pcdata.From.Offset = objabi.PCDATA_UnsafePoint pcdata.To.Type = TYPE_CONST pcdata.To.Offset = oldval @@ -257,11 +257,11 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is prevPcdata := int64(-1) // entry PC data value prevRestart := int64(0) for p := prev.Link; p != nil; p, prev = p.Link, p { - if p.As == APCDATA && p.From.Offset == objabi.PCDATA_RegMapIndex { + if p.As == APCDATA && p.From.Offset == objabi.PCDATA_UnsafePoint { prevPcdata = p.To.Offset continue } - if prevPcdata == objabi.PCDATA_RegMapUnsafe { + if prevPcdata == objabi.PCDATA_UnsafePointUnsafe { continue // already unsafe } if isUnsafePoint(p) { @@ -288,7 +288,7 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is q := Appendp(prev, newprog) q.As = APCDATA q.From.Type = TYPE_CONST - q.From.Offset = objabi.PCDATA_RegMapIndex + q.From.Offset = objabi.PCDATA_UnsafePoint q.To.Type = TYPE_CONST q.To.Offset = val q.Pc = p.Pc @@ -305,7 +305,7 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is p = Appendp(p, newprog) p.As = APCDATA p.From.Type = TYPE_CONST - p.From.Offset = objabi.PCDATA_RegMapIndex + p.From.Offset = objabi.PCDATA_UnsafePoint p.To.Type = TYPE_CONST p.To.Offset = prevPcdata p.Pc = p.Link.Pc diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go index 8b32692778..4c97302f83 100644 --- a/src/cmd/internal/obj/ppc64/a.out.go +++ b/src/cmd/internal/obj/ppc64/a.out.go @@ -575,6 +575,7 @@ const ( ARLWMICC ARLWNM ARLWNMCC + ACLRLSLWI ASLW ASLWCC ASRW @@ -716,6 +717,9 @@ const ( ARLDCLCC ARLDICL ARLDICLCC + ARLDIC + ARLDICCC + ACLRLSLDI AROTL AROTLW ASLBIA @@ -729,6 +733,8 @@ const ( ASRAD ASRADCC ASRDCC + AEXTSWSLI + AEXTSWSLICC ASTDCCC ATD diff --git a/src/cmd/internal/obj/ppc64/anames.go b/src/cmd/internal/obj/ppc64/anames.go index 287011877c..fca4b3e355 100644 --- a/src/cmd/internal/obj/ppc64/anames.go +++ b/src/cmd/internal/obj/ppc64/anames.go @@ -180,6 +180,7 @@ var Anames = []string{ "RLWMICC", "RLWNM", "RLWNMCC", + "CLRLSLWI", "SLW", "SLWCC", "SRW", @@ -312,6 +313,9 @@ var Anames = []string{ "RLDCLCC", "RLDICL", "RLDICLCC", + "RLDIC", + "RLDICCC", + "CLRLSLDI", "ROTL", "ROTLW", "SLBIA", @@ -325,6 +329,8 @@ var Anames = []string{ "SRAD", "SRADCC", "SRDCC", + "EXTSWSLI", + "EXTSWSLICC", "STDCCC", "TD", "DWORD", diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 98b453de6c..41e263b2c0 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -160,6 +160,8 @@ var optab = []Optab{ {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0}, {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0}, + {AEXTSWSLI, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0}, + {AEXTSWSLI, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0}, {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0}, {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0}, {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0}, @@ -172,6 +174,7 @@ var optab = []Optab{ {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0}, {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0}, {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0}, + {ACLRLSLWI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0}, {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0}, {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0}, @@ -331,6 +334,7 @@ var optab = []Optab{ {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0}, {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0}, {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0}, + {ABR, C_NONE, C_NONE, C_SCON, C_LR, 18, 4, 0}, {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0}, {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0}, {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0}, @@ -661,8 +665,8 @@ func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int { // the function alignment is not changed which might // result in 16 byte alignment but that is still fine. // TODO: alignment on AIX - if ctxt.Headtype != objabi.Haix && cursym.Func.Align < 32 { - cursym.Func.Align = 32 + if ctxt.Headtype != objabi.Haix && cursym.Func().Align < 32 { + cursym.Func().Align = 32 } default: ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a) @@ -671,7 +675,7 @@ func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int { } func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { - p := cursym.Func.Text + p := cursym.Func().Text if p == nil || p.Link == nil { // handle external functions and ELF section symbols return } @@ -720,7 +724,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { for bflag != 0 { bflag = 0 pc = 0 - for p = c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p = c.cursym.Func().Text.Link; p != nil; p = p.Link { p.Pc = pc o = c.oplook(p) @@ -782,7 +786,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { bp := c.cursym.P var i int32 var out [6]uint32 - for p := c.cursym.Func.Text.Link; p != nil; p = p.Link { + for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { c.pc = p.Pc o = c.oplook(p) if int(o.size) > 4*len(out) { @@ -1277,6 +1281,9 @@ func buildop(ctxt *obj.Link) { case AREMD: opset(AREMDU, r0) + case AMULLW: + opset(AMULLD, r0) + case ADIVW: /* op Rb[,Ra],Rd */ opset(AMULHW, r0) @@ -1310,7 +1317,6 @@ func buildop(ctxt *obj.Link) { opset(AMULHDCC, r0) opset(AMULHDU, r0) opset(AMULHDUCC, r0) - opset(AMULLD, r0) opset(AMULLDCC, r0) opset(AMULLDVCC, r0) opset(AMULLDV, r0) @@ -1877,6 +1883,9 @@ func buildop(ctxt *obj.Link) { case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ opset(ASRAWCC, r0) + case AEXTSWSLI: + opset(AEXTSWSLICC, r0) + case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ opset(ASRADCC, r0) @@ -1922,6 +1931,9 @@ func buildop(ctxt *obj.Link) { opset(ARLDICLCC, r0) opset(ARLDICR, r0) opset(ARLDICRCC, r0) + opset(ARLDIC, r0) + opset(ARLDICCC, r0) + opset(ACLRLSLDI, r0) case AFMOVD: opset(AFMOVDCC, r0) @@ -1987,7 +1999,6 @@ func buildop(ctxt *obj.Link) { AMOVB, /* macro: move byte with sign extension */ AMOVBU, /* macro: move byte with sign extension & update */ AMOVFL, - AMULLW, /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */ ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */ ASTSW, @@ -2000,6 +2011,7 @@ func buildop(ctxt *obj.Link) { AADDEX, ACMPEQB, AECIWX, + ACLRLSLWI, obj.ANOP, obj.ATEXT, obj.AUNDEF, @@ -2149,7 +2161,7 @@ func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 { /* Z23-form, 3-register operands + CY field */ func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7 + return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<9 } /* X-form, 3-register operands + EH field */ @@ -2185,49 +2197,54 @@ func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 { return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5 } +func AOP_EXTSWSLI(op uint32, a uint32, s uint32, sh uint32) uint32 { + return op | (a&31)<<21 | (s&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 +} + func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 { return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6 } const ( /* each rhs is OPVCC(_, _, _, _) */ - OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0 - OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0 - OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0 - OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0 - OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0 - OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0 - OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0 - OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0 - OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0 - OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0 - OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0 - OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0 - OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0 - OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0 - OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0 - OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0 - OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0 - OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0 - OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0 - OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0 - OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0 - OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0 - OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0 - OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0 - OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0 - OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0 - OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0 - OP_OR = 31<<26 | 444<<1 | 0<<10 | 0 - OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0 - OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0 - OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0 - OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0 - OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0 - OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0 - OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0 - OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0 - OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0 + OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0 + OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0 + OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0 + OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0 + OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0 + OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0 + OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0 + OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0 + OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0 + OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0 + OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0 + OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0 + OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0 + OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0 + OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0 + OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0 + OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0 + OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0 + OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0 + OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0 + OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0 + OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0 + OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0 + OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0 + OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0 + OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0 + OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0 + OP_OR = 31<<26 | 444<<1 | 0<<10 | 0 + OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0 + OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0 + OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0 + OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0 + OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0 + OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0 + OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0 + OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0 + OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0 + OP_EXTSWSLI = 31<<26 | 445<<2 ) func oclass(a *obj.Addr) int { @@ -2734,13 +2751,31 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { case ARLDICR, ARLDICRCC: me := int(d) sh := c.regoff(&p.From) + if me < 0 || me > 63 || sh > 63 { + c.ctxt.Diag("Invalid me or sh for RLDICR: %x %x\n%v", int(d), sh, p) + } o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me)) - case ARLDICL, ARLDICLCC: + case ARLDICL, ARLDICLCC, ARLDIC, ARLDICCC: mb := int(d) sh := c.regoff(&p.From) + if mb < 0 || mb > 63 || sh > 63 { + c.ctxt.Diag("Invalid mb or sh for RLDIC, RLDICL: %x %x\n%v", mb, sh, p) + } o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb)) + case ACLRLSLDI: + // This is an extended mnemonic defined in the ISA section C.8.1 + // clrlsldi ra,rs,b,n --> rldic ra,rs,n,b-n + // It maps onto RLDIC so is directly generated here based on the operands from + // the clrlsldi. + n := int32(d) + b := c.regoff(&p.From) + if n > b || b > 63 { + c.ctxt.Diag("Invalid n or b for CLRLSLDI: %x %x\n%v", n, b, p) + } + o1 = AOP_RLDIC(OP_RLDIC, uint32(p.To.Reg), uint32(r), uint32(n), uint32(b)-uint32(n)) + default: c.ctxt.Diag("unexpected op in rldc case\n%v", p) a = 0 @@ -2810,6 +2845,7 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */ var v int32 + var bh uint32 = 0 if p.As == ABC || p.As == ABCL { v = c.regoff(&p.From) & 31 } else { @@ -2831,6 +2867,15 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { v = 0 } + // Insert optional branch hint for bclr[l]/bcctr[l] + if p.From3Type() != obj.TYPE_NONE { + bh = uint32(p.GetFrom3().Offset) + if bh == 2 || bh > 3 { + log.Fatalf("BH must be 0,1,3 for %v", p) + } + o1 |= bh << 11 + } + if p.As == ABL || p.As == ABCL { o1 |= 1 } @@ -2943,14 +2988,21 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { case AROTL: a = int(0) op = OP_RLDICL + case AEXTSWSLI: + a = int(v) default: c.ctxt.Diag("unexpected op in sldi case\n%v", p) a = 0 o1 = 0 } - o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a)) - if p.As == ASLDCC || p.As == ASRDCC { + if p.As == AEXTSWSLI || p.As == AEXTSWSLICC { + o1 = AOP_EXTSWSLI(OP_EXTSWSLI, uint32(r), uint32(p.To.Reg), uint32(v)) + + } else { + o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a)) + } + if p.As == ASLDCC || p.As == ASRDCC || p.As == AEXTSWSLICC { o1 |= 1 // Set the condition code bit } @@ -3354,17 +3406,28 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { case 62: /* rlwmi $sh,s,$mask,a */ v := c.regoff(&p.From) + switch p.As { + case ACLRLSLWI: + n := c.regoff(p.GetFrom3()) + // This is an extended mnemonic described in the ISA C.8.2 + // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n + // It maps onto rlwinm which is directly generated here. + if n > v || v >= 32 { + c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p) + } - var mask [2]uint8 - c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3()))) - o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v)) - o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 + o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n)) + default: + var mask [2]uint8 + c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3()))) + o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v)) + o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 + } case 63: /* rlwmi b,s,$mask,a */ var mask [2]uint8 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3()))) - - o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg)) + o1 = AOP_RRR(c.oprrr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg)) o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 case 64: /* mtfsf fr[, $m] {,fpcsr} */ @@ -4277,6 +4340,11 @@ func (c *ctxt9) oprrr(a obj.As) uint32 { case ARLDICRCC: return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr. + case ARLDIC: + return OPVCC(30, 0, 0, 0) | 4<<1 // rldic + case ARLDICCC: + return OPVCC(30, 0, 0, 1) | 4<<1 // rldic. + case ASYSCALL: return OPVCC(17, 1, 0, 0) @@ -4298,6 +4366,11 @@ func (c *ctxt9) oprrr(a obj.As) uint32 { case ASRADCC: return OPVCC(31, 794, 0, 1) + case AEXTSWSLI: + return OPVCC(31, 445, 0, 0) + case AEXTSWSLICC: + return OPVCC(31, 445, 0, 1) + case ASRW: return OPVCC(31, 536, 0, 0) case ASRWCC: @@ -4915,8 +4988,8 @@ func (c *ctxt9) opirr(a obj.As) uint32 { case ADARN: return OPVCC(31, 755, 0, 0) /* darn - v3.00 */ - case AMULLW: - return OPVCC(7, 0, 0, 0) + case AMULLW, AMULLD: + return OPVCC(7, 0, 0, 0) /* mulli works with MULLW or MULLD */ case AOR: return OPVCC(24, 0, 0, 0) @@ -4961,6 +5034,10 @@ func (c *ctxt9) opirr(a obj.As) uint32 { return OPVCC(31, (413 << 1), 0, 0) case ASRADCC: return OPVCC(31, (413 << 1), 0, 1) + case AEXTSWSLI: + return OPVCC(31, 445, 0, 0) + case AEXTSWSLICC: + return OPVCC(31, 445, 0, 1) case ASTSW: return OPVCC(31, 725, 0, 0) diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index c012762a18..fddf552156 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -32,6 +32,7 @@ package ppc64 import ( "cmd/internal/obj" "cmd/internal/objabi" + "cmd/internal/src" "cmd/internal/sys" ) @@ -402,13 +403,13 @@ func (c *ctxt9) rewriteToUseGot(p *obj.Prog) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // TODO(minux): add morestack short-cuts with small fixed frame-size. - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } c := ctxt9{ctxt: ctxt, cursym: cursym, newprog: newprog} - p := c.cursym.Func.Text + p := c.cursym.Func().Text textstksiz := p.To.Offset if textstksiz == -8 { // Compatibility hack. @@ -424,8 +425,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - c.cursym.Func.Args = p.To.Val.(int32) - c.cursym.Func.Locals = int32(textstksiz) + c.cursym.Func().Args = p.To.Val.(int32) + c.cursym.Func().Locals = int32(textstksiz) /* * find leaf subroutines @@ -435,7 +436,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { var q *obj.Prog var q1 *obj.Prog - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { switch p.As { /* too hard, just leave alone */ case obj.ATEXT: @@ -541,7 +542,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ABCL, obj.ADUFFZERO, obj.ADUFFCOPY: - c.cursym.Func.Text.Mark &^= LEAF + c.cursym.Func().Text.Mark &^= LEAF fallthrough case ABC, @@ -598,7 +599,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { autosize := int32(0) var p1 *obj.Prog var p2 *obj.Prog - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { o := p.As switch o { case obj.ATEXT: @@ -664,7 +665,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { rel.Type = objabi.R_ADDRPOWER_PCREL } - if !c.cursym.Func.Text.From.Sym.NoSplit() { + if !c.cursym.Func().Text.From.Sym.NoSplit() { q = c.stacksplit(q, autosize) // emit split check } @@ -672,6 +673,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // save the link register and update the stack, since that code is // called directly from C/C++ and can't clobber REGTMP (R31). if autosize != 0 && c.cursym.Name != "runtime.racecallbackthunk" { + var prologueEnd *obj.Prog // Save the link register and update the SP. MOVDU is used unless // the frame size is too large. The link register must be saved // even for non-empty leaf functions so that traceback works. @@ -685,6 +687,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Type = obj.TYPE_REG q.To.Reg = REGTMP + prologueEnd = q + q = obj.Appendp(q, c.newprog) q.As = AMOVDU q.Pos = p.Pos @@ -720,6 +724,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Offset = int64(-autosize) q.To.Reg = REGSP + prologueEnd = q + q = obj.Appendp(q, c.newprog) q.As = AADD q.Pos = p.Pos @@ -730,16 +736,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.Spadj = +autosize q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) - } - } else if c.cursym.Func.Text.Mark&LEAF == 0 { + prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd) + } else if c.cursym.Func().Text.Mark&LEAF == 0 { // A very few functions that do not return to their caller // (e.g. gogo) are not identified as leaves but still have // no frame. - c.cursym.Func.Text.Mark |= LEAF + c.cursym.Func().Text.Mark |= LEAF } - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { c.cursym.Set(obj.AttrLeaf, true) break } @@ -755,7 +761,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Offset = 24 } - if c.cursym.Func.Text.From.Sym.Wrapper() { + if c.cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVD g_panic(g), R3 @@ -853,7 +859,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { retTarget := p.To.Sym - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { if autosize == 0 || c.cursym.Name == "runtime.racecallbackthunk" { p.As = ABR p.From = obj.Addr{} @@ -1161,7 +1167,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { var morestacksym *obj.LSym if c.cursym.CFunc() { morestacksym = c.ctxt.Lookup("runtime.morestackc") - } else if !c.cursym.Func.Text.From.Sym.NeedCtxt() { + } else if !c.cursym.Func().Text.From.Sym.NeedCtxt() { morestacksym = c.ctxt.Lookup("runtime.morestack_noctxt") } else { morestacksym = c.ctxt.Lookup("runtime.morestack") diff --git a/src/cmd/internal/obj/riscv/cpu.go b/src/cmd/internal/obj/riscv/cpu.go index 482f9e0b6d..b1324b62a0 100644 --- a/src/cmd/internal/obj/riscv/cpu.go +++ b/src/cmd/internal/obj/riscv/cpu.go @@ -109,7 +109,7 @@ const ( REG_RA = REG_X1 // aka REG_LR REG_SP = REG_X2 REG_GP = REG_X3 // aka REG_SB - REG_TP = REG_X4 // aka REG_G + REG_TP = REG_X4 REG_T0 = REG_X5 REG_T1 = REG_X6 REG_T2 = REG_X7 @@ -132,17 +132,17 @@ const ( REG_S8 = REG_X24 REG_S9 = REG_X25 REG_S10 = REG_X26 - REG_S11 = REG_X27 + REG_S11 = REG_X27 // aka REG_G REG_T3 = REG_X28 REG_T4 = REG_X29 REG_T5 = REG_X30 REG_T6 = REG_X31 // aka REG_TMP // Go runtime register names. - REG_G = REG_TP // G pointer. - REG_CTXT = REG_S4 // Context for closures. - REG_LR = REG_RA // Link register. - REG_TMP = REG_T6 // Reserved for assembler use. + REG_G = REG_S11 // G pointer. + REG_CTXT = REG_S4 // Context for closures. + REG_LR = REG_RA // Link register. + REG_TMP = REG_T6 // Reserved for assembler use. // ABI names for floating point registers. REG_FT0 = REG_F0 diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 77d383b290..9257a6453a 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -33,7 +33,7 @@ func buildop(ctxt *obj.Link) {} // lr is the link register to use for the JALR. // p must be a CALL, JMP or RET. func jalrToSym(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, lr int16) *obj.Prog { - if p.As != obj.ACALL && p.As != obj.AJMP && p.As != obj.ARET { + if p.As != obj.ACALL && p.As != obj.AJMP && p.As != obj.ARET && p.As != obj.ADUFFZERO && p.As != obj.ADUFFCOPY { ctxt.Diag("unexpected Prog in jalrToSym: %v", p) return p } @@ -48,7 +48,7 @@ func jalrToSym(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, lr int16) *ob p.As = AAUIPC p.Mark |= NEED_PCREL_ITYPE_RELOC - p.RestArgs = []obj.Addr{obj.Addr{Type: obj.TYPE_CONST, Offset: to.Offset, Sym: to.Sym}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: to.Offset, Sym: to.Sym}) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} p.Reg = 0 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP} @@ -58,30 +58,14 @@ func jalrToSym(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, lr int16) *ob p.As = AJALR p.From.Type = obj.TYPE_REG p.From.Reg = lr - p.From.Sym = to.Sym p.Reg = 0 p.To.Type = obj.TYPE_REG p.To.Reg = REG_TMP - lowerJALR(p) + p.To.Sym = to.Sym return p } -// lowerJALR normalizes a JALR instruction. -func lowerJALR(p *obj.Prog) { - if p.As != AJALR { - panic("lowerJALR: not a JALR") - } - - // JALR gets parsed like JAL - the linkage pointer goes in From, - // and the target is in To. However, we need to assemble it as an - // I-type instruction, so place the linkage pointer in To, the - // target register in Reg, and the offset in From. - p.Reg = p.To.Reg - p.From, p.To = p.To, p.From - p.From.Type, p.From.Reg = obj.TYPE_CONST, obj.REG_NONE -} - // progedit is called individually for each *obj.Prog. It normalizes instruction // formats and eliminates as many pseudo-instructions as possible. func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { @@ -125,7 +109,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { switch p.As { case obj.AJMP: // Turn JMP into JAL ZERO or JALR ZERO. - // p.From is actually an _output_ for this instruction. p.From.Type = obj.TYPE_REG p.From.Reg = REG_ZERO @@ -136,7 +119,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { switch p.To.Name { case obj.NAME_NONE: p.As = AJALR - lowerJALR(p) case obj.NAME_EXTERN: // Handled in preprocess. default: @@ -154,14 +136,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { p.As = AJALR p.From.Type = obj.TYPE_REG p.From.Reg = REG_LR - lowerJALR(p) default: ctxt.Diag("unknown destination type %+v in CALL: %v", p.To.Type, p) } - case AJALR: - lowerJALR(p) - case obj.AUNDEF: p.As = AEBREAK @@ -256,7 +234,7 @@ func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) { p.As = AAUIPC p.Mark |= NEED_PCREL_ITYPE_RELOC - p.RestArgs = []obj.Addr{obj.Addr{Type: obj.TYPE_CONST, Offset: p.From.Offset, Sym: p.From.Sym}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: p.From.Offset, Sym: p.From.Sym}) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} p.Reg = 0 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: to.Reg} @@ -274,19 +252,7 @@ func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) { switch p.To.Type { case obj.TYPE_REG: switch p.As { - case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb - p.As = AADDI - p.Reg = p.From.Reg - p.From = obj.Addr{Type: obj.TYPE_CONST} - - case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb - p.As = AFSGNJS - p.Reg = p.From.Reg - - case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb - p.As = AFSGNJD - p.Reg = p.From.Reg - + case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD: default: ctxt.Diag("unsupported register-register move at %v", p) } @@ -309,7 +275,7 @@ func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) { p.As = AAUIPC p.Mark |= NEED_PCREL_STYPE_RELOC - p.RestArgs = []obj.Addr{obj.Addr{Type: obj.TYPE_CONST, Offset: p.To.Offset, Sym: p.To.Sym}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: p.To.Offset, Sym: p.To.Sym}) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} p.Reg = 0 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP} @@ -374,7 +340,7 @@ func rewriteMOV(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog) { p.As = AAUIPC p.Mark |= NEED_PCREL_ITYPE_RELOC - p.RestArgs = []obj.Addr{obj.Addr{Type: obj.TYPE_CONST, Offset: p.From.Offset, Sym: p.From.Sym}} + p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: p.From.Offset, Sym: p.From.Sym}) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} p.Reg = 0 p.To = to @@ -449,12 +415,12 @@ func InvertBranch(as obj.As) obj.As { // instruction. Must be called after progedit. func containsCall(sym *obj.LSym) bool { // CALLs are CALL or JAL(R) with link register LR. - for p := sym.Func.Text; p != nil; p = p.Link { + for p := sym.Func().Text; p != nil; p = p.Link { switch p.As { - case obj.ACALL: + case obj.ACALL, obj.ADUFFZERO, obj.ADUFFCOPY: return true case AJAL, AJALR: - if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_LR { + if p.From.Type == obj.TYPE_REG && p.From.Reg == REG_LR { return true } } @@ -521,12 +487,12 @@ func stackOffset(a *obj.Addr, stacksize int64) { // concrete, real RISC-V instructions or directive pseudo-ops like TEXT, // PCDATA, and FUNCDATA. func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } // Generate the prologue. - text := cursym.Func.Text + text := cursym.Func().Text if text.As != obj.ATEXT { ctxt.Diag("preprocess: found symbol that does not start with TEXT directive") return @@ -560,12 +526,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { stacksize += ctxt.FixedFrameSize() } - cursym.Func.Args = text.To.Val.(int32) - cursym.Func.Locals = int32(stacksize) + cursym.Func().Args = text.To.Val.(int32) + cursym.Func().Locals = int32(stacksize) prologue := text - if !cursym.Func.Text.From.Sym.NoSplit() { + if !cursym.Func().Text.From.Sym.NoSplit() { prologue = stacksplit(ctxt, prologue, cursym, newprog, stacksize) // emit split check } @@ -589,7 +555,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { prologue = ctxt.EndUnsafePoint(prologue, newprog, -1) } - if cursym.Func.Text.From.Sym.Wrapper() { + if cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOV g_panic(g), X11 @@ -669,13 +635,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } // Update stack-based offsets. - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { stackOffset(&p.From, stacksize) stackOffset(&p.To, stacksize) } // Additional instruction rewriting. - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case obj.AGETCALLERPC: if cursym.Leaf() { @@ -690,7 +656,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.From.Reg = REG_SP } - case obj.ACALL: + case obj.ACALL, obj.ADUFFZERO, obj.ADUFFCOPY: switch p.To.Type { case obj.TYPE_MEM: jalrToSym(ctxt, p, newprog, REG_LR) @@ -731,11 +697,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p = jalrToSym(ctxt, p, newprog, REG_ZERO) } else { p.As = AJALR - p.From.Type = obj.TYPE_CONST - p.From.Offset = 0 - p.Reg = REG_LR - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_ZERO + p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO} + p.Reg = 0 + p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR} } // "Add back" the stack removed in the previous instruction. @@ -757,7 +721,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // Rewrite MOV pseudo-instructions. This cannot be done in // progedit, as SP offsets need to be applied before we split // up some of the Addrs. - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD: rewriteMOV(ctxt, newprog, p) @@ -765,7 +729,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } // Split immediates larger than 12-bits. - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { // <opi> $imm, REG, TO case AADDI, AANDI, AORI, AXORI: @@ -882,9 +846,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // a fixed point will be reached). No attempt to handle functions > 2GiB. for { rescan := false - setPCs(cursym.Func.Text, 0) + setPCs(cursym.Func().Text, 0) - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ: if p.To.Type != obj.TYPE_BRANCH { @@ -917,9 +881,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // it is reserved by SSA. jmp := obj.Appendp(p, newprog) jmp.As = AJALR - jmp.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} - jmp.To = p.From - jmp.Reg = REG_TMP + jmp.From = p.From + jmp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP} // p.From is not generally valid, however will be // fixed up in the next loop. @@ -942,7 +905,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // Now that there are no long branches, resolve branch and jump targets. // At this point, instruction rewriting which changes the number of // instructions will break everything--don't do it! - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ, AJAL: switch p.To.Type { @@ -965,7 +928,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } // Validate all instructions - this provides nice error messages. - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { for _, ins := range instructionsForProg(p) { ins.validate(ctxt) } @@ -1093,7 +1056,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.To.Type = obj.TYPE_BRANCH if cursym.CFunc() { p.To.Sym = ctxt.Lookup("runtime.morestackc") - } else if !cursym.Func.Text.From.Sym.NeedCtxt() { + } else if !cursym.Func().Text.From.Sym.NeedCtxt() { p.To.Sym = ctxt.Lookup("runtime.morestack_noctxt") } else { p.To.Sym = ctxt.Lookup("runtime.morestack") @@ -1108,7 +1071,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.As = AJAL p.To = obj.Addr{Type: obj.TYPE_BRANCH} p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO} - p.To.SetTarget(cursym.Func.Text.Link) + p.To.SetTarget(cursym.Func().Text.Link) // placeholder for to_done's jump target p = obj.Appendp(p, newprog) @@ -1733,6 +1696,8 @@ var encodings = [ALAST & obj.AMask]encoding{ obj.APCDATA: pseudoOpEncoding, obj.ATEXT: pseudoOpEncoding, obj.ANOP: pseudoOpEncoding, + obj.ADUFFZERO: pseudoOpEncoding, + obj.ADUFFCOPY: pseudoOpEncoding, } // encodingForAs returns the encoding for an obj.As. @@ -1801,8 +1766,8 @@ func instructionsForProg(p *obj.Prog) []*instruction { inss := []*instruction{ins} switch ins.as { - case AJAL: - ins.rd, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE + case AJAL, AJALR: + ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.To.Reg), obj.REG_NONE ins.imm = p.To.Offset case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ: @@ -1812,15 +1777,15 @@ func instructionsForProg(p *obj.Prog) []*instruction { case ABGEZ: ins.as, ins.rs1, ins.rs2 = ABGE, REG_ZERO, uint32(p.From.Reg) case ABGT: - ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.Reg), uint32(p.From.Reg) + ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), uint32(p.Reg) case ABGTU: - ins.as, ins.rs1, ins.rs2 = ABLTU, uint32(p.Reg), uint32(p.From.Reg) + ins.as, ins.rs1, ins.rs2 = ABLTU, uint32(p.From.Reg), uint32(p.Reg) case ABGTZ: ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), REG_ZERO case ABLE: - ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.Reg), uint32(p.From.Reg) + ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), uint32(p.Reg) case ABLEU: - ins.as, ins.rs1, ins.rs2 = ABGEU, uint32(p.Reg), uint32(p.From.Reg) + ins.as, ins.rs1, ins.rs2 = ABGEU, uint32(p.From.Reg), uint32(p.Reg) case ABLEZ: ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), REG_ZERO case ABLTZ: @@ -1830,6 +1795,44 @@ func instructionsForProg(p *obj.Prog) []*instruction { } ins.imm = p.To.Offset + case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD: + // Handle register to register moves. + if p.From.Type != obj.TYPE_REG || p.To.Type != obj.TYPE_REG { + break + } + switch p.As { + case AMOV: // MOV Ra, Rb -> ADDI $0, Ra, Rb + ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0 + case AMOVW: // MOVW Ra, Rb -> ADDIW $0, Ra, Rb + ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0 + case AMOVBU: // MOVBU Ra, Rb -> ANDI $255, Ra, Rb + ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255 + case AMOVF: // MOVF Ra, Rb -> FSGNJS Ra, Ra, Rb + ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg) + case AMOVD: // MOVD Ra, Rb -> FSGNJD Ra, Ra, Rb + ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg) + case AMOVB, AMOVH: + // Use SLLI/SRAI to extend. + ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE + if p.As == AMOVB { + ins.imm = 56 + } else if p.As == AMOVH { + ins.imm = 48 + } + ins2 := &instruction{as: ASRAI, rd: ins.rd, rs1: ins.rd, imm: ins.imm} + inss = append(inss, ins2) + case AMOVHU, AMOVWU: + // Use SLLI/SRLI to extend. + ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE + if p.As == AMOVHU { + ins.imm = 48 + } else if p.As == AMOVWU { + ins.imm = 32 + } + ins2 := &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: ins.imm} + inss = append(inss, ins2) + } + case ALW, ALWU, ALH, ALHU, ALB, ALBU, ALD, AFLW, AFLD: if p.From.Type != obj.TYPE_MEM { p.Ctxt.Diag("%v requires memory for source", p) @@ -1884,13 +1887,13 @@ func instructionsForProg(p *obj.Prog) []*instruction { } else { ins.as = AFEQD } - ins = &instruction{ + ins2 := &instruction{ as: AXORI, // [bit] xor 1 = not [bit] rd: ins.rd, rs1: ins.rd, imm: 1, } - inss = append(inss, ins) + inss = append(inss, ins2) case AFSQRTS, AFSQRTD: // These instructions expect a zero (i.e. float register 0) @@ -1951,7 +1954,7 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } var symcode []uint32 - for p := cursym.Func.Text; p != nil; p = p.Link { + for p := cursym.Func().Text; p != nil; p = p.Link { switch p.As { case AJALR: if p.To.Sym != nil { @@ -1983,6 +1986,13 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ctxt.Diag("AUIPC needing PC-relative reloc missing symbol") break } + if addr.Sym.Type == objabi.STLSBSS { + if rt == objabi.R_RISCV_PCREL_ITYPE { + rt = objabi.R_RISCV_TLS_IE_ITYPE + } else if rt == objabi.R_RISCV_PCREL_STYPE { + rt = objabi.R_RISCV_TLS_IE_STYPE + } + } rel := obj.Addrel(cursym) rel.Off = int32(p.Pc) @@ -2006,7 +2016,7 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ctxt.Arch.ByteOrder.PutUint32(p, symcode[i]) } - obj.MarkUnsafePoints(ctxt, cursym.Func.Text, newprog, isUnsafePoint, nil) + obj.MarkUnsafePoints(ctxt, cursym.Func().Text, newprog, isUnsafePoint, nil) } func isUnsafePoint(p *obj.Prog) bool { diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go index 803ba8c77c..279aeb2c32 100644 --- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go +++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go @@ -11,6 +11,8 @@ import ( ) func testBEQZ(a int64) (r bool) +func testBGE(a, b int64) (r bool) +func testBGEU(a, b int64) (r bool) func testBGEZ(a int64) (r bool) func testBGT(a, b int64) (r bool) func testBGTU(a, b int64) (r bool) @@ -18,6 +20,8 @@ func testBGTZ(a int64) (r bool) func testBLE(a, b int64) (r bool) func testBLEU(a, b int64) (r bool) func testBLEZ(a int64) (r bool) +func testBLT(a, b int64) (r bool) +func testBLTU(a, b int64) (r bool) func testBLTZ(a int64) (r bool) func testBNEZ(a int64) (r bool) @@ -29,30 +33,75 @@ func TestBranchCondition(t *testing.T) { fn func(a, b int64) bool want bool }{ - {"BGT", 0, 1, testBGT, true}, + {"BGE", 0, 1, testBGE, false}, + {"BGE", 0, 0, testBGE, true}, + {"BGE", 0, -1, testBGE, true}, + {"BGE", -1, 0, testBGE, false}, + {"BGE", 1, 0, testBGE, true}, + {"BGEU", 0, 1, testBGEU, false}, + {"BGEU", 0, 0, testBGEU, true}, + {"BGEU", 0, -1, testBGEU, false}, + {"BGEU", -1, 0, testBGEU, true}, + {"BGEU", 1, 0, testBGEU, true}, + {"BGT", 0, 1, testBGT, false}, {"BGT", 0, 0, testBGT, false}, - {"BGT", 0, -1, testBGT, false}, - {"BGT", -1, 0, testBGT, true}, - {"BGT", 1, 0, testBGT, false}, - {"BGTU", 0, 1, testBGTU, true}, - {"BGTU", 0, -1, testBGTU, true}, - {"BGTU", -1, 0, testBGTU, false}, - {"BGTU", 1, 0, testBGTU, false}, - {"BLE", 0, 1, testBLE, false}, - {"BLE", 0, -1, testBLE, true}, + {"BGT", 0, -1, testBGT, true}, + {"BGT", -1, 0, testBGT, false}, + {"BGT", 1, 0, testBGT, true}, + {"BGTU", 0, 1, testBGTU, false}, + {"BGTU", 0, 0, testBGTU, false}, + {"BGTU", 0, -1, testBGTU, false}, + {"BGTU", -1, 0, testBGTU, true}, + {"BGTU", 1, 0, testBGTU, true}, + {"BLE", 0, 1, testBLE, true}, {"BLE", 0, 0, testBLE, true}, - {"BLE", -1, 0, testBLE, false}, - {"BLE", 1, 0, testBLE, true}, - {"BLEU", 0, 1, testBLEU, false}, - {"BLEU", 0, -1, testBLEU, false}, + {"BLE", 0, -1, testBLE, false}, + {"BLE", -1, 0, testBLE, true}, + {"BLE", 1, 0, testBLE, false}, + {"BLEU", 0, 1, testBLEU, true}, {"BLEU", 0, 0, testBLEU, true}, - {"BLEU", -1, 0, testBLEU, true}, - {"BLEU", 1, 0, testBLEU, true}, + {"BLEU", 0, -1, testBLEU, true}, + {"BLEU", -1, 0, testBLEU, false}, + {"BLEU", 1, 0, testBLEU, false}, + {"BLT", 0, 1, testBLT, true}, + {"BLT", 0, 0, testBLT, false}, + {"BLT", 0, -1, testBLT, false}, + {"BLT", -1, 0, testBLT, true}, + {"BLT", 1, 0, testBLT, false}, + {"BLTU", 0, 1, testBLTU, true}, + {"BLTU", 0, 0, testBLTU, false}, + {"BLTU", 0, -1, testBLTU, true}, + {"BLTU", -1, 0, testBLTU, false}, + {"BLTU", 1, 0, testBLTU, false}, } for _, test := range tests { t.Run(test.ins, func(t *testing.T) { + var fn func(a, b int64) bool + switch test.ins { + case "BGE": + fn = func(a, b int64) bool { return a >= b } + case "BGEU": + fn = func(a, b int64) bool { return uint64(a) >= uint64(b) } + case "BGT": + fn = func(a, b int64) bool { return a > b } + case "BGTU": + fn = func(a, b int64) bool { return uint64(a) > uint64(b) } + case "BLE": + fn = func(a, b int64) bool { return a <= b } + case "BLEU": + fn = func(a, b int64) bool { return uint64(a) <= uint64(b) } + case "BLT": + fn = func(a, b int64) bool { return a < b } + case "BLTU": + fn = func(a, b int64) bool { return uint64(a) < uint64(b) } + default: + t.Fatalf("Unknown instruction %q", test.ins) + } + if got := fn(test.a, test.b); got != test.want { + t.Errorf("Go %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want) + } if got := test.fn(test.a, test.b); got != test.want { - t.Errorf("%v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want) + t.Errorf("Assembly %v %v, %v = %v, want %v", test.ins, test.a, test.b, got, test.want) } }) } diff --git a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s index 6cff235848..8dd6f563af 100644 --- a/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s +++ b/src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s @@ -16,6 +16,28 @@ b: MOV X6, r+8(FP) RET +// func testBGE(a, b int64) (r bool) +TEXT ·testBGE(SB),NOSPLIT,$0-0 + MOV a+0(FP), X5 + MOV b+8(FP), X6 + MOV $1, X7 + BGE X5, X6, b + MOV $0, X7 +b: + MOV X7, r+16(FP) + RET + +// func testBGEU(a, b int64) (r bool) +TEXT ·testBGEU(SB),NOSPLIT,$0-0 + MOV a+0(FP), X5 + MOV b+8(FP), X6 + MOV $1, X7 + BGEU X5, X6, b + MOV $0, X7 +b: + MOV X7, r+16(FP) + RET + // func testBGEZ(a int64) (r bool) TEXT ·testBGEZ(SB),NOSPLIT,$0-0 MOV a+0(FP), X5 @@ -90,6 +112,28 @@ b: MOV X6, r+8(FP) RET +// func testBLT(a, b int64) (r bool) +TEXT ·testBLT(SB),NOSPLIT,$0-0 + MOV a+0(FP), X5 + MOV b+8(FP), X6 + MOV $1, X7 + BLT X5, X6, b + MOV $0, X7 +b: + MOV X7, r+16(FP) + RET + +// func testBLTU(a, b int64) (r bool) +TEXT ·testBLTU(SB),NOSPLIT,$0-0 + MOV a+0(FP), X5 + MOV b+8(FP), X6 + MOV $1, X7 + BLTU X5, X6, b + MOV $0, X7 +b: + MOV X7, r+16(FP) + RET + // func testBLTZ(a int64) (r bool) TEXT ·testBLTZ(SB),NOSPLIT,$0-0 MOV a+0(FP), X5 diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go index 68f01f1c5d..06921085c9 100644 --- a/src/cmd/internal/obj/s390x/asmz.go +++ b/src/cmd/internal/obj/s390x/asmz.go @@ -447,7 +447,7 @@ func spanz(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ctxt.Retpoline = false // don't keep printing } - p := cursym.Func.Text + p := cursym.Func().Text if p == nil || p.Link == nil { // handle external functions and ELF section symbols return } @@ -461,6 +461,7 @@ func spanz(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { buffer := make([]byte, 0) changed := true loop := 0 + nrelocs0 := len(c.cursym.R) for changed { if loop > 100 { c.ctxt.Diag("stuck in spanz loop") @@ -468,8 +469,11 @@ func spanz(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } changed = false buffer = buffer[:0] - c.cursym.R = make([]obj.Reloc, 0) - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for i := range c.cursym.R[nrelocs0:] { + c.cursym.R[nrelocs0+i] = obj.Reloc{} + } + c.cursym.R = c.cursym.R[:nrelocs0] // preserve marker relocations generated by the compiler + for p := c.cursym.Func().Text; p != nil; p = p.Link { pc := int64(len(buffer)) if pc != p.Pc { changed = true @@ -500,7 +504,7 @@ func spanz(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // We use REGTMP as a scratch register during call injection, // so instruction sequences that use REGTMP are unsafe to // preempt asynchronously. - obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, nil) + obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, nil) } // Return whether p is an unsafe point. @@ -714,7 +718,7 @@ func (c *ctxtz) oplook(p *obj.Prog) *Optab { p.From.Class = int8(c.aclass(&p.From) + 1) p.To.Class = int8(c.aclass(&p.To) + 1) for i := range p.RestArgs { - p.RestArgs[i].Class = int8(c.aclass(&p.RestArgs[i]) + 1) + p.RestArgs[i].Addr.Class = int8(c.aclass(&p.RestArgs[i].Addr) + 1) } // Mirrors the argument list in Optab. @@ -3696,7 +3700,7 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) { } case 80: // sync - zRR(op_BCR, uint32(NotEqual), 0, asm) + zRR(op_BCR, 14, 0, asm) // fast-BCR-serialization case 81: // float to fixed and fixed to float moves (no conversion) switch p.As { diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go index 625bb0f7b4..970cf827d6 100644 --- a/src/cmd/internal/obj/s390x/objz.go +++ b/src/cmd/internal/obj/s390x/objz.go @@ -205,13 +205,13 @@ func (c *ctxtz) rewriteToUseGot(p *obj.Prog) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { // TODO(minux): add morestack short-cuts with small fixed frame-size. - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } c := ctxtz{ctxt: ctxt, cursym: cursym, newprog: newprog} - p := c.cursym.Func.Text + p := c.cursym.Func().Text textstksiz := p.To.Offset if textstksiz == -8 { // Compatibility hack. @@ -227,8 +227,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - c.cursym.Func.Args = p.To.Val.(int32) - c.cursym.Func.Locals = int32(textstksiz) + c.cursym.Func().Args = p.To.Val.(int32) + c.cursym.Func().Locals = int32(textstksiz) /* * find leaf subroutines @@ -237,7 +237,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { */ var q *obj.Prog - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { switch p.As { case obj.ATEXT: q = p @@ -245,7 +245,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { case ABL, ABCL: q = p - c.cursym.Func.Text.Mark &^= LEAF + c.cursym.Func().Text.Mark &^= LEAF fallthrough case ABC, @@ -294,7 +294,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { var pPre *obj.Prog var pPreempt *obj.Prog wasSplit := false - for p := c.cursym.Func.Text; p != nil; p = p.Link { + for p := c.cursym.Func().Text; p != nil; p = p.Link { pLast = p switch p.As { case obj.ATEXT: @@ -356,19 +356,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.Spadj = autosize q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) - } else if c.cursym.Func.Text.Mark&LEAF == 0 { + } else if c.cursym.Func().Text.Mark&LEAF == 0 { // A very few functions that do not return to their caller // (e.g. gogo) are not identified as leaves but still have // no frame. - c.cursym.Func.Text.Mark |= LEAF + c.cursym.Func().Text.Mark |= LEAF } - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { c.cursym.Set(obj.AttrLeaf, true) break } - if c.cursym.Func.Text.From.Sym.Wrapper() { + if c.cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVD g_panic(g), R3 @@ -461,7 +461,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { case obj.ARET: retTarget := p.To.Sym - if c.cursym.Func.Text.Mark&LEAF != 0 { + if c.cursym.Func().Text.Mark&LEAF != 0 { if autosize == 0 { p.As = ABR p.From = obj.Addr{} @@ -497,8 +497,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.From.Type = obj.TYPE_MEM p.From.Reg = REGSP p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_LR + p.To = obj.Addr{ + Type: obj.TYPE_REG, + Reg: REG_LR, + } q = p @@ -696,7 +698,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, p.To.Type = obj.TYPE_BRANCH if c.cursym.CFunc() { p.To.Sym = c.ctxt.Lookup("runtime.morestackc") - } else if !c.cursym.Func.Text.From.Sym.NeedCtxt() { + } else if !c.cursym.Func().Text.From.Sym.NeedCtxt() { p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt") } else { p.To.Sym = c.ctxt.Lookup("runtime.morestack") @@ -709,7 +711,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, p.As = ABR p.To.Type = obj.TYPE_BRANCH - p.To.SetTarget(c.cursym.Func.Text.Link) + p.To.SetTarget(c.cursym.Func().Text.Link) return p } diff --git a/src/cmd/internal/obj/s390x/rotate.go b/src/cmd/internal/obj/s390x/rotate.go index fd2d5482db..7dbc45e648 100644 --- a/src/cmd/internal/obj/s390x/rotate.go +++ b/src/cmd/internal/obj/s390x/rotate.go @@ -4,6 +4,10 @@ package s390x +import ( + "math/bits" +) + // RotateParams represents the immediates required for a "rotate // then ... selected bits instruction". // @@ -24,12 +28,18 @@ package s390x // input left by. Note that this rotation is performed // before the masked region is used. type RotateParams struct { - Start uint8 // big-endian start bit index [0..63] - End uint8 // big-endian end bit index [0..63] - Amount uint8 // amount to rotate left + Start int8 // big-endian start bit index [0..63] + End int8 // big-endian end bit index [0..63] + Amount int8 // amount to rotate left } -func NewRotateParams(start, end, amount int64) RotateParams { +// NewRotateParams creates a set of parameters representing a +// rotation left by the amount provided and a selection of the bits +// between the provided start and end indexes (inclusive). +// +// The start and end indexes and the rotation amount must all +// be in the range 0-63 inclusive or this function will panic. +func NewRotateParams(start, end, amount int8) RotateParams { if start&^63 != 0 { panic("start out of bounds") } @@ -40,8 +50,66 @@ func NewRotateParams(start, end, amount int64) RotateParams { panic("amount out of bounds") } return RotateParams{ - Start: uint8(start), - End: uint8(end), - Amount: uint8(amount), + Start: start, + End: end, + Amount: amount, } } + +// RotateLeft generates a new set of parameters with the rotation amount +// increased by the given value. The selected bits are left unchanged. +func (r RotateParams) RotateLeft(amount int8) RotateParams { + r.Amount += amount + r.Amount &= 63 + return r +} + +// OutMask provides a mask representing the selected bits. +func (r RotateParams) OutMask() uint64 { + // Note: z must be unsigned for bootstrap compiler + z := uint8(63-r.End+r.Start) & 63 // number of zero bits in mask + return bits.RotateLeft64(^uint64(0)<<z, -int(r.Start)) +} + +// InMask provides a mask representing the selected bits relative +// to the source value (i.e. pre-rotation). +func (r RotateParams) InMask() uint64 { + return bits.RotateLeft64(r.OutMask(), -int(r.Amount)) +} + +// OutMerge tries to generate a new set of parameters representing +// the intersection between the selected bits and the provided mask. +// If the intersection is unrepresentable (0 or not contiguous) nil +// will be returned. +func (r RotateParams) OutMerge(mask uint64) *RotateParams { + mask &= r.OutMask() + if mask == 0 { + return nil + } + + // normalize the mask so that the set bits are left aligned + o := bits.LeadingZeros64(^mask) + mask = bits.RotateLeft64(mask, o) + z := bits.LeadingZeros64(mask) + mask = bits.RotateLeft64(mask, z) + + // check that the normalized mask is contiguous + l := bits.LeadingZeros64(^mask) + if l+bits.TrailingZeros64(mask) != 64 { + return nil + } + + // update start and end positions (rotation amount remains the same) + r.Start = int8(o+z) & 63 + r.End = (r.Start + int8(l) - 1) & 63 + return &r +} + +// InMerge tries to generate a new set of parameters representing +// the intersection between the selected bits and the provided mask +// as applied to the source value (i.e. pre-rotation). +// If the intersection is unrepresentable (0 or not contiguous) nil +// will be returned. +func (r RotateParams) InMerge(mask uint64) *RotateParams { + return r.OutMerge(bits.RotateLeft64(mask, int(r.Amount))) +} diff --git a/src/cmd/internal/obj/s390x/rotate_test.go b/src/cmd/internal/obj/s390x/rotate_test.go new file mode 100644 index 0000000000..fa5b5bdecd --- /dev/null +++ b/src/cmd/internal/obj/s390x/rotate_test.go @@ -0,0 +1,122 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package s390x + +import ( + "testing" +) + +func TestRotateParamsMask(t *testing.T) { + tests := []struct { + start, end, amount int8 + inMask, outMask uint64 + }{ + // start before end, no rotation + {start: 0, end: 63, amount: 0, inMask: ^uint64(0), outMask: ^uint64(0)}, + {start: 1, end: 63, amount: 0, inMask: ^uint64(0) >> 1, outMask: ^uint64(0) >> 1}, + {start: 0, end: 62, amount: 0, inMask: ^uint64(1), outMask: ^uint64(1)}, + {start: 1, end: 62, amount: 0, inMask: ^uint64(3) >> 1, outMask: ^uint64(3) >> 1}, + + // end before start, no rotation + {start: 63, end: 0, amount: 0, inMask: 1<<63 | 1, outMask: 1<<63 | 1}, + {start: 62, end: 0, amount: 0, inMask: 1<<63 | 3, outMask: 1<<63 | 3}, + {start: 63, end: 1, amount: 0, inMask: 3<<62 | 1, outMask: 3<<62 | 1}, + {start: 62, end: 1, amount: 0, inMask: 3<<62 | 3, outMask: 3<<62 | 3}, + + // rotation + {start: 32, end: 63, amount: 32, inMask: 0xffffffff00000000, outMask: 0x00000000ffffffff}, + {start: 48, end: 15, amount: 16, inMask: 0xffffffff00000000, outMask: 0xffff00000000ffff}, + {start: 0, end: 7, amount: -8 & 63, inMask: 0xff, outMask: 0xff << 56}, + } + for i, test := range tests { + r := NewRotateParams(test.start, test.end, test.amount) + if m := r.OutMask(); m != test.outMask { + t.Errorf("out mask %v: want %#x, got %#x", i, test.outMask, m) + } + if m := r.InMask(); m != test.inMask { + t.Errorf("in mask %v: want %#x, got %#x", i, test.inMask, m) + } + } +} + +func TestRotateParamsMerge(t *testing.T) { + tests := []struct { + // inputs + src RotateParams + mask uint64 + + // results + in *RotateParams + out *RotateParams + }{ + { + src: RotateParams{Start: 48, End: 15, Amount: 16}, + mask: 0xffffffffffffffff, + in: &RotateParams{Start: 48, End: 15, Amount: 16}, + out: &RotateParams{Start: 48, End: 15, Amount: 16}, + }, + { + src: RotateParams{Start: 16, End: 47, Amount: 0}, + mask: 0x00000000ffffffff, + in: &RotateParams{Start: 32, End: 47, Amount: 0}, + out: &RotateParams{Start: 32, End: 47, Amount: 0}, + }, + { + src: RotateParams{Start: 16, End: 47, Amount: 0}, + mask: 0xffff00000000ffff, + in: nil, + out: nil, + }, + { + src: RotateParams{Start: 0, End: 63, Amount: 0}, + mask: 0xf7f0000000000000, + in: nil, + out: nil, + }, + { + src: RotateParams{Start: 0, End: 63, Amount: 1}, + mask: 0x000000000000ff00, + in: &RotateParams{Start: 47, End: 54, Amount: 1}, + out: &RotateParams{Start: 48, End: 55, Amount: 1}, + }, + { + src: RotateParams{Start: 32, End: 63, Amount: 32}, + mask: 0xffff00000000ffff, + in: &RotateParams{Start: 32, End: 47, Amount: 32}, + out: &RotateParams{Start: 48, End: 63, Amount: 32}, + }, + { + src: RotateParams{Start: 0, End: 31, Amount: 32}, + mask: 0x8000000000000000, + in: nil, + out: &RotateParams{Start: 0, End: 0, Amount: 32}, + }, + { + src: RotateParams{Start: 0, End: 31, Amount: 32}, + mask: 0x0000000080000000, + in: &RotateParams{Start: 0, End: 0, Amount: 32}, + out: nil, + }, + } + + eq := func(x, y *RotateParams) bool { + if x == nil && y == nil { + return true + } + if x == nil || y == nil { + return false + } + return *x == *y + } + + for _, test := range tests { + if r := test.src.InMerge(test.mask); !eq(r, test.in) { + t.Errorf("%v merged with %#x (input): want %v, got %v", test.src, test.mask, test.in, r) + } + if r := test.src.OutMerge(test.mask); !eq(r, test.out) { + t.Errorf("%v merged with %#x (output): want %v, got %v", test.src, test.mask, test.out, r) + } + } +} diff --git a/src/cmd/internal/obj/sizeof_test.go b/src/cmd/internal/obj/sizeof_test.go index b5e170c694..69e60473f5 100644 --- a/src/cmd/internal/obj/sizeof_test.go +++ b/src/cmd/internal/obj/sizeof_test.go @@ -21,7 +21,7 @@ func TestSizeof(t *testing.T) { _64bit uintptr // size on 64bit platforms }{ {Addr{}, 32, 48}, - {LSym{}, 76, 128}, + {LSym{}, 72, 120}, {Prog{}, 132, 200}, } diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index d58877ee15..4515bdd0d3 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -38,6 +38,7 @@ import ( "log" "math" "sort" + "strings" ) func Linknew(arch *LinkArch) *Link { @@ -204,7 +205,9 @@ func (ctxt *Link) NumberSyms() { // if Pkgpath is unknown, cannot hash symbols with relocations, as it // may reference named symbols whose names are not fully expanded. if s.ContentAddressable() && (ctxt.Pkgpath != "" || len(s.R) == 0) { - if len(s.P) <= 8 && len(s.R) == 0 { // we can use short hash only for symbols without relocations + if s.Size <= 8 && len(s.R) == 0 && !strings.HasPrefix(s.Name, "type.") { + // We can use short hash only for symbols without relocations. + // Don't use short hash for type symbols, as they need special handling. s.PkgIdx = goobj.PkgIdxHashed64 s.SymIdx = hashed64idx if hashed64idx != int32(len(ctxt.hashed64defs)) { @@ -355,7 +358,8 @@ func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) { } func (ctxt *Link) traverseFuncAux(flag traverseFlag, fsym *LSym, fn func(parent *LSym, aux *LSym)) { - pc := &fsym.Func.Pcln + fninfo := fsym.Func() + pc := &fninfo.Pcln if flag&traverseAux == 0 { // NB: should it become necessary to walk aux sym reloc references // without walking the aux syms themselves, this can be changed. @@ -386,7 +390,8 @@ func (ctxt *Link) traverseFuncAux(flag traverseFlag, fsym *LSym, fn func(parent fn(fsym, filesym) } } - dwsyms := []*LSym{fsym.Func.dwarfRangesSym, fsym.Func.dwarfLocSym, fsym.Func.dwarfDebugLinesSym, fsym.Func.dwarfInfoSym} + + dwsyms := []*LSym{fninfo.dwarfRangesSym, fninfo.dwarfLocSym, fninfo.dwarfDebugLinesSym, fninfo.dwarfInfoSym} for _, dws := range dwsyms { if dws == nil || dws.Size == 0 { continue diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index a30ccf0564..b9bacb7a22 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -175,9 +175,11 @@ func (p *Prog) WriteInstructionString(w io.Writer) { sep = ", " } for i := range p.RestArgs { - io.WriteString(w, sep) - WriteDconv(w, p, &p.RestArgs[i]) - sep = ", " + if p.RestArgs[i].Pos == Source { + io.WriteString(w, sep) + WriteDconv(w, p, &p.RestArgs[i].Addr) + sep = ", " + } } if p.As == ATEXT { @@ -198,6 +200,13 @@ func (p *Prog) WriteInstructionString(w io.Writer) { if p.RegTo2 != REG_NONE { fmt.Fprintf(w, "%s%v", sep, Rconv(int(p.RegTo2))) } + for i := range p.RestArgs { + if p.RestArgs[i].Pos == Destination { + io.WriteString(w, sep) + WriteDconv(w, p, &p.RestArgs[i].Addr) + sep = ", " + } + } } func (ctxt *Link) NewProg() *Prog { @@ -210,13 +219,30 @@ func (ctxt *Link) CanReuseProgs() bool { return ctxt.Debugasm == 0 } +// Dconv accepts an argument 'a' within a prog 'p' and returns a string +// with a formatted version of the argument. func Dconv(p *Prog, a *Addr) string { buf := new(bytes.Buffer) - WriteDconv(buf, p, a) + writeDconv(buf, p, a, false) + return buf.String() +} + +// DconvDconvWithABIDetail accepts an argument 'a' within a prog 'p' +// and returns a string with a formatted version of the argument, in +// which text symbols are rendered with explicit ABI selectors. +func DconvWithABIDetail(p *Prog, a *Addr) string { + buf := new(bytes.Buffer) + writeDconv(buf, p, a, true) return buf.String() } +// WriteDconv accepts an argument 'a' within a prog 'p' +// and writes a formatted version of the arg to the writer. func WriteDconv(w io.Writer, p *Prog, a *Addr) { + writeDconv(w, p, a, false) +} + +func writeDconv(w io.Writer, p *Prog, a *Addr, abiDetail bool) { switch a.Type { default: fmt.Fprintf(w, "type=%d", a.Type) @@ -250,7 +276,7 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) { case TYPE_BRANCH: if a.Sym != nil { - fmt.Fprintf(w, "%s(SB)", a.Sym.Name) + fmt.Fprintf(w, "%s%s(SB)", a.Sym.Name, abiDecorate(a, abiDetail)) } else if a.Target() != nil { fmt.Fprint(w, a.Target().Pc) } else { @@ -259,7 +285,7 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) { case TYPE_INDIR: io.WriteString(w, "*") - a.WriteNameTo(w) + a.writeNameTo(w, abiDetail) case TYPE_MEM: a.WriteNameTo(w) @@ -299,7 +325,7 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) { case TYPE_ADDR: io.WriteString(w, "$") - a.WriteNameTo(w) + a.writeNameTo(w, abiDetail) case TYPE_SHIFT: v := int(a.Offset) @@ -335,6 +361,11 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) { } func (a *Addr) WriteNameTo(w io.Writer) { + a.writeNameTo(w, false) +} + +func (a *Addr) writeNameTo(w io.Writer, abiDetail bool) { + switch a.Name { default: fmt.Fprintf(w, "name=%d", a.Name) @@ -356,7 +387,7 @@ func (a *Addr) WriteNameTo(w io.Writer) { reg = Rconv(int(a.Reg)) } if a.Sym != nil { - fmt.Fprintf(w, "%s%s(%s)", a.Sym.Name, offConv(a.Offset), reg) + fmt.Fprintf(w, "%s%s%s(%s)", a.Sym.Name, abiDecorate(a, abiDetail), offConv(a.Offset), reg) } else { fmt.Fprintf(w, "%s(%s)", offConv(a.Offset), reg) } @@ -596,3 +627,10 @@ func Bool2int(b bool) int { } return i } + +func abiDecorate(a *Addr, abiDetail bool) string { + if !abiDetail || a.Sym == nil { + return "" + } + return fmt.Sprintf("<%s>", a.Sym.ABI()) +} diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go index 70e8e51e65..2e9890d86c 100644 --- a/src/cmd/internal/obj/wasm/wasmobj.go +++ b/src/cmd/internal/obj/wasm/wasmobj.go @@ -129,7 +129,6 @@ var ( morestackNoCtxt *obj.LSym gcWriteBarrier *obj.LSym sigpanic *obj.LSym - sigpanic0 *obj.LSym deferreturn *obj.LSym jmpdefer *obj.LSym ) @@ -142,9 +141,8 @@ const ( func instinit(ctxt *obj.Link) { morestack = ctxt.Lookup("runtime.morestack") morestackNoCtxt = ctxt.Lookup("runtime.morestack_noctxt") - gcWriteBarrier = ctxt.Lookup("runtime.gcWriteBarrier") + gcWriteBarrier = ctxt.LookupABI("runtime.gcWriteBarrier", obj.ABIInternal) sigpanic = ctxt.LookupABI("runtime.sigpanic", obj.ABIInternal) - sigpanic0 = ctxt.LookupABI("runtime.sigpanic", 0) // sigpanic called from assembly, which has ABI0 deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal) // jmpdefer is defined in assembly as ABI0, but what we're // looking for is the *call* to jmpdefer from the Go function @@ -182,14 +180,14 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { return p } - framesize := s.Func.Text.To.Offset + framesize := s.Func().Text.To.Offset if framesize < 0 { panic("bad framesize") } - s.Func.Args = s.Func.Text.To.Val.(int32) - s.Func.Locals = int32(framesize) + s.Func().Args = s.Func().Text.To.Val.(int32) + s.Func().Locals = int32(framesize) - if s.Func.Text.From.Sym.Wrapper() { + if s.Func().Text.From.Sym.Wrapper() { // if g._panic != nil && g._panic.argp == FP { // g._panic.argp = bottom-of-frame // } @@ -222,7 +220,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { Offset: 0, // panic.argp } - p := s.Func.Text + p := s.Func().Text p = appendp(p, AMOVD, gpanic, regAddr(REG_R0)) p = appendp(p, AGet, regAddr(REG_R0)) @@ -245,7 +243,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } if framesize > 0 { - p := s.Func.Text + p := s.Func().Text p = appendp(p, AGet, regAddr(REG_SP)) p = appendp(p, AI32Const, constAddr(framesize)) p = appendp(p, AI32Sub) @@ -260,8 +258,8 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { pc := int64(0) // pc is only incremented when necessary, this avoids bloat of the BrTable instruction var tableIdxs []uint64 tablePC := int64(0) - base := ctxt.PosTable.Pos(s.Func.Text.Pos).Base() - for p := s.Func.Text; p != nil; p = p.Link { + base := ctxt.PosTable.Pos(s.Func().Text.Pos).Base() + for p := s.Func().Text; p != nil; p = p.Link { prevBase := base base = ctxt.PosTable.Pos(p.Pos).Base() switch p.As { @@ -313,8 +311,8 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { tableIdxs = append(tableIdxs, uint64(numResumePoints)) s.Size = pc + 1 - if !s.Func.Text.From.Sym.NoSplit() { - p := s.Func.Text + if !s.Func().Text.From.Sym.NoSplit() { + p := s.Func().Text if framesize <= objabi.StackSmall { // small stack: SP <= stackguard @@ -352,7 +350,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { p = appendp(p, AIf) p = appendp(p, obj.ACALL, constAddr(0)) - if s.Func.Text.From.Sym.NeedCtxt() { + if s.Func().Text.From.Sym.NeedCtxt() { p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: morestack} } else { p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: morestackNoCtxt} @@ -365,7 +363,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { var entryPointLoopBranches []*obj.Prog var unwindExitBranches []*obj.Prog currentDepth := 0 - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { switch p.As { case ABlock, ALoop, AIf: currentDepth++ @@ -493,7 +491,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } // return value of call is on the top of the stack, indicating whether to unwind the WebAssembly stack - if call.As == ACALLNORESUME && call.To.Sym != sigpanic && call.To.Sym != sigpanic0 { // sigpanic unwinds the stack, but it never resumes + if call.As == ACALLNORESUME && call.To.Sym != sigpanic { // sigpanic unwinds the stack, but it never resumes // trying to unwind WebAssembly stack but call has no resume point, terminate with error p = appendp(p, AIf) p = appendp(p, obj.AUNDEF) @@ -562,7 +560,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } } - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { switch p.From.Name { case obj.NAME_AUTO: p.From.Offset += int64(framesize) @@ -712,7 +710,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } { - p := s.Func.Text + p := s.Func().Text if len(unwindExitBranches) > 0 { p = appendp(p, ABlock) // unwindExit, used to return 1 when unwinding the stack for _, b := range unwindExitBranches { @@ -749,7 +747,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { currentDepth = 0 blockDepths := make(map[*obj.Prog]int) - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { switch p.As { case ABlock, ALoop, AIf: currentDepth++ @@ -850,7 +848,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { hasLocalSP = true var regUsed [MAXREG - MINREG]bool - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { if p.From.Reg != 0 { regUsed[p.From.Reg-MINREG] = true } @@ -896,7 +894,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { updateLocalSP(w) } - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { switch p.As { case AGet: if p.From.Type != obj.TYPE_REG { @@ -1007,6 +1005,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { panic("bad name for Call") } r := obj.Addrel(s) + r.Siz = 1 // actually variable sized r.Off = int32(w.Len()) r.Type = objabi.R_CALL if p.Mark&WasmImport != 0 { @@ -1033,6 +1032,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { case AI32Const, AI64Const: if p.From.Name == obj.NAME_EXTERN { r := obj.Addrel(s) + r.Siz = 1 // actually variable sized r.Off = int32(w.Len()) r.Type = objabi.R_ADDR r.Sym = p.From.Sym diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index fb99c620ad..a6b85ac4a0 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -1851,9 +1851,9 @@ func spadjop(ctxt *obj.Link, l, q obj.As) obj.As { return q } -// If the environment variable GOAMD64=alignedjumps the assembler will ensure that -// no standalone or macro-fused jump will straddle or end on a 32 byte boundary -// by inserting NOPs before the jumps +// isJump returns whether p is a jump instruction. +// It is used to ensure that no standalone or macro-fused jump will straddle +// or end on a 32 byte boundary by inserting NOPs before the jumps. func isJump(p *obj.Prog) bool { return p.To.Target() != nil || p.As == obj.AJMP || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO @@ -1987,11 +1987,6 @@ func makePjcCtx(ctxt *obj.Link) padJumpsCtx { return padJumpsCtx(0) } - if objabi.GOAMD64 != "alignedjumps" { - return padJumpsCtx(0) - - } - return padJumpsCtx(32) } @@ -2050,7 +2045,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { ctxt.Diag("x86 tables not initialized, call x86.instinit first") } - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { if p.To.Type == obj.TYPE_BRANCH && p.To.Target() == nil { p.To.SetTarget(p) } @@ -2085,7 +2080,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { } var count int64 // rough count of number of instructions - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { count++ p.Back = branchShort // use short branches first time through if q := p.To.Target(); q != nil && (q.Back&branchShort != 0) { @@ -2100,19 +2095,20 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { var c int32 errors := ctxt.Errors var nops []nopPad // Padding for a particular assembly (reuse slice storage if multiple assemblies) + nrelocs0 := len(s.R) for { // This loop continues while there are reasons to re-assemble // whole block, like the presence of long forward jumps. reAssemble := false - for i := range s.R { - s.R[i] = obj.Reloc{} + for i := range s.R[nrelocs0:] { + s.R[nrelocs0+i] = obj.Reloc{} } - s.R = s.R[:0] + s.R = s.R[:nrelocs0] // preserve marker relocations generated by the compiler s.P = s.P[:0] c = 0 var pPrev *obj.Prog nops = nops[:0] - for p := s.Func.Text; p != nil; p = p.Link { + for p := s.Func().Text; p != nil; p = p.Link { c0 := c c = pjc.padJump(ctxt, s, p, c) @@ -2226,7 +2222,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { // the first instruction.) return p.From.Index == REG_TLS } - obj.MarkUnsafePoints(ctxt, s.Func.Text, newprog, useTLS, nil) + obj.MarkUnsafePoints(ctxt, s.Func().Text, newprog, useTLS, nil) } } @@ -4269,7 +4265,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) { args = append(args, ft) } for i := range p.RestArgs { - args = append(args, oclass(ctxt, p, &p.RestArgs[i])*Ymax) + args = append(args, oclass(ctxt, p, &p.RestArgs[i].Addr)*Ymax) } if tt != Ynone*Ymax { args = append(args, tt) @@ -5437,10 +5433,10 @@ func (ab *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) { // unpackOps4 extracts 4 operands from p. func unpackOps4(p *obj.Prog) (arg0, arg1, arg2, dst *obj.Addr) { - return &p.From, &p.RestArgs[0], &p.RestArgs[1], &p.To + return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.To } // unpackOps5 extracts 5 operands from p. func unpackOps5(p *obj.Prog) (arg0, arg1, arg2, arg3, dst *obj.Addr) { - return &p.From, &p.RestArgs[0], &p.RestArgs[1], &p.RestArgs[2], &p.To + return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.RestArgs[2].Addr, &p.To } diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 18a6afcd77..184fb4308b 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -324,9 +324,9 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { // flags and duffzero on 386 does not otherwise do so). var sym *obj.LSym if p.As == obj.ADUFFZERO { - sym = ctxt.Lookup("runtime.duffzero") + sym = ctxt.LookupABI("runtime.duffzero", obj.ABIInternal) } else { - sym = ctxt.Lookup("runtime.duffcopy") + sym = ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal) } offset := p.To.Offset p.As = mov @@ -563,11 +563,11 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { } func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { - if cursym.Func.Text == nil || cursym.Func.Text.Link == nil { + if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { return } - p := cursym.Func.Text + p := cursym.Func().Text autoffset := int32(p.To.Offset) if autoffset < 0 { autoffset = 0 @@ -602,12 +602,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } textarg := int64(p.To.Val.(int32)) - cursym.Func.Args = int32(textarg) - cursym.Func.Locals = int32(p.To.Offset) + cursym.Func().Args = int32(textarg) + cursym.Func().Locals = int32(p.To.Offset) // TODO(rsc): Remove. - if ctxt.Arch.Family == sys.I386 && cursym.Func.Locals < 0 { - cursym.Func.Locals = 0 + if ctxt.Arch.Family == sys.I386 && cursym.Func().Locals < 0 { + cursym.Func().Locals = 0 } // TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'. @@ -642,7 +642,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p = load_g_cx(ctxt, p, newprog) // load g into CX } - if !cursym.Func.Text.From.Sym.NoSplit() { + if !cursym.Func().Text.From.Sym.NoSplit() { p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check } @@ -690,7 +690,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Reg = REG_BP } - if cursym.Func.Text.From.Sym.Wrapper() { + if cursym.Func().Text.From.Sym.Wrapper() { // if g._panic != nil && g._panic.argp == FP { // g._panic.argp = bottom-of-frame // } @@ -808,7 +808,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } var deltasp int32 - for p = cursym.Func.Text; p != nil; p = p.Link { + for p = cursym.Func().Text; p != nil; p = p.Link { pcsize := ctxt.Arch.RegSize switch p.From.Name { case obj.NAME_AUTO: @@ -1103,7 +1103,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA end := ctxt.EndUnsafePoint(jls, newprog, -1) var last *obj.Prog - for last = cursym.Func.Text; last.Link != nil; last = last.Link { + for last = cursym.Func().Text; last.Link != nil; last = last.Link { } // Now we are at the end of the function, but logically @@ -1117,7 +1117,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA pcdata = ctxt.StartUnsafePoint(pcdata, newprog) call := obj.Appendp(pcdata, newprog) - call.Pos = cursym.Func.Text.Pos + call.Pos = cursym.Func().Text.Pos call.As = obj.ACALL call.To.Type = obj.TYPE_BRANCH call.To.Name = obj.NAME_EXTERN @@ -1125,7 +1125,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA switch { case cursym.CFunc(): morestack = "runtime.morestackc" - case !cursym.Func.Text.From.Sym.NeedCtxt(): + case !cursym.Func().Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = ctxt.Lookup(morestack) @@ -1144,7 +1144,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA jmp := obj.Appendp(pcdata, newprog) jmp.As = obj.AJMP jmp.To.Type = obj.TYPE_BRANCH - jmp.To.SetTarget(cursym.Func.Text.Link) + jmp.To.SetTarget(cursym.Func().Text.Link) jmp.Spadj = +framesize jls.To.SetTarget(call) diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go index 79ad2ccf74..3fd73f3c57 100644 --- a/src/cmd/internal/objabi/flag.go +++ b/src/cmd/internal/objabi/flag.go @@ -5,6 +5,7 @@ package objabi import ( + "bytes" "flag" "fmt" "io" @@ -59,6 +60,9 @@ func expandArgs(in []string) (out []string) { log.Fatal(err) } args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n") + for i, arg := range args { + args[i] = DecodeArg(arg) + } out = append(out, expandArgs(args)...) } else if out != nil { out = append(out, s) @@ -160,3 +164,38 @@ func (f fn1) Set(s string) error { } func (f fn1) String() string { return "" } + +// DecodeArg decodes an argument. +// +// This function is public for testing with the parallel encoder. +func DecodeArg(arg string) string { + // If no encoding, fastpath out. + if !strings.ContainsAny(arg, "\\\n") { + return arg + } + + // We can't use strings.Builder as this must work at bootstrap. + var b bytes.Buffer + var wasBS bool + for _, r := range arg { + if wasBS { + switch r { + case '\\': + b.WriteByte('\\') + case 'n': + b.WriteByte('\n') + default: + // This shouldn't happen. The only backslashes that reach here + // should encode '\n' and '\\' exclusively. + panic("badly formatted input") + } + } else if r == '\\' { + wasBS = true + continue + } else { + b.WriteRune(r) + } + wasBS = false + } + return b.String() +} diff --git a/src/cmd/internal/objabi/flag_test.go b/src/cmd/internal/objabi/flag_test.go new file mode 100644 index 0000000000..935b9c2193 --- /dev/null +++ b/src/cmd/internal/objabi/flag_test.go @@ -0,0 +1,26 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package objabi + +import "testing" + +func TestDecodeArg(t *testing.T) { + t.Parallel() + tests := []struct { + arg, want string + }{ + {"", ""}, + {"hello", "hello"}, + {"hello\\n", "hello\n"}, + {"hello\\nthere", "hello\nthere"}, + {"hello\\\\there", "hello\\there"}, + {"\\\\\\n", "\\\n"}, + } + for _, test := range tests { + if got := DecodeArg(test.arg); got != test.want { + t.Errorf("decodoeArg(%q) = %q, want %q", test.arg, got, test.want) + } + } +} diff --git a/src/cmd/internal/objabi/funcdata.go b/src/cmd/internal/objabi/funcdata.go index c9480bf2f0..faa2863325 100644 --- a/src/cmd/internal/objabi/funcdata.go +++ b/src/cmd/internal/objabi/funcdata.go @@ -11,17 +11,15 @@ package objabi // ../../../runtime/symtab.go. const ( - PCDATA_RegMapIndex = 0 // if !go115ReduceLiveness - PCDATA_UnsafePoint = 0 // if go115ReduceLiveness + PCDATA_UnsafePoint = 0 PCDATA_StackMapIndex = 1 PCDATA_InlTreeIndex = 2 FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_LocalsPointerMaps = 1 - FUNCDATA_RegPointerMaps = 2 // if !go115ReduceLiveness - FUNCDATA_StackObjects = 3 - FUNCDATA_InlTree = 4 - FUNCDATA_OpenCodedDeferInfo = 5 + FUNCDATA_StackObjects = 2 + FUNCDATA_InlTree = 3 + FUNCDATA_OpenCodedDeferInfo = 4 // ArgsSizeUnknown is set in Func.argsize to mark all functions // whose argument size is unknown (C vararg functions, and @@ -32,11 +30,6 @@ const ( // Special PCDATA values. const ( - // PCDATA_RegMapIndex values. - // - // Only if !go115ReduceLiveness. - PCDATA_RegMapUnsafe = PCDATA_UnsafePointUnsafe // Unsafe for async preemption - // PCDATA_UnsafePoint values. PCDATA_UnsafePointSafe = -1 // Safe for async preemption PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption diff --git a/src/cmd/internal/objabi/funcid.go b/src/cmd/internal/objabi/funcid.go index 6c9336f31c..1d098ee172 100644 --- a/src/cmd/internal/objabi/funcid.go +++ b/src/cmd/internal/objabi/funcid.go @@ -26,7 +26,7 @@ const ( FuncID_gcBgMarkWorker FuncID_systemstack_switch FuncID_systemstack - FuncID_cgocallback_gofunc + FuncID_cgocallback FuncID_gogo FuncID_externalthreadhandler FuncID_debugCallV1 @@ -70,8 +70,8 @@ func GetFuncID(name string, isWrapper bool) FuncID { return FuncID_systemstack_switch case "runtime.systemstack": return FuncID_systemstack - case "runtime.cgocallback_gofunc": - return FuncID_cgocallback_gofunc + case "runtime.cgocallback": + return FuncID_cgocallback case "runtime.gogo": return FuncID_gogo case "runtime.externalthreadhandler": diff --git a/src/cmd/internal/objabi/head.go b/src/cmd/internal/objabi/head.go index 95b8db3809..48ff292307 100644 --- a/src/cmd/internal/objabi/head.go +++ b/src/cmd/internal/objabi/head.go @@ -54,7 +54,7 @@ func (h *HeadType) Set(s string) error { switch s { case "aix": *h = Haix - case "darwin": + case "darwin", "ios": *h = Hdarwin case "dragonfly": *h = Hdragonfly diff --git a/src/cmd/internal/objabi/line.go b/src/cmd/internal/objabi/line.go index 178c8363d9..0733b65138 100644 --- a/src/cmd/internal/objabi/line.go +++ b/src/cmd/internal/objabi/line.go @@ -37,25 +37,36 @@ func AbsFile(dir, file, rewrites string) string { abs = filepath.Join(dir, file) } + abs, rewritten := ApplyRewrites(abs, rewrites) + if !rewritten && hasPathPrefix(abs, GOROOT) { + abs = "$GOROOT" + abs[len(GOROOT):] + } + + if abs == "" { + abs = "??" + } + return abs +} + +// ApplyRewrites returns the filename for file in the given directory, +// as rewritten by the rewrites argument. +// +// The rewrites argument is a ;-separated list of rewrites. +// Each rewrite is of the form "prefix" or "prefix=>replace", +// where prefix must match a leading sequence of path elements +// and is either removed entirely or replaced by the replacement. +func ApplyRewrites(file, rewrites string) (string, bool) { start := 0 for i := 0; i <= len(rewrites); i++ { if i == len(rewrites) || rewrites[i] == ';' { - if new, ok := applyRewrite(abs, rewrites[start:i]); ok { - abs = new - goto Rewritten + if new, ok := applyRewrite(file, rewrites[start:i]); ok { + return new, true } start = i + 1 } } - if hasPathPrefix(abs, GOROOT) { - abs = "$GOROOT" + abs[len(GOROOT):] - } -Rewritten: - if abs == "" { - abs = "??" - } - return abs + return file, false } // applyRewrite applies the rewrite to the path, diff --git a/src/cmd/internal/objabi/path.go b/src/cmd/internal/objabi/path.go index 2a42179a36..fd1c9981c6 100644 --- a/src/cmd/internal/objabi/path.go +++ b/src/cmd/internal/objabi/path.go @@ -39,3 +39,25 @@ func PathToPrefix(s string) string { return string(p) } + +// IsRuntimePackagePath examines 'pkgpath' and returns TRUE if it +// belongs to the collection of "runtime-related" packages, including +// "runtime" itself, "reflect", "syscall", and the +// "runtime/internal/*" packages. The compiler and/or assembler in +// some cases need to be aware of when they are building such a +// package, for example to enable features such as ABI selectors in +// assembly sources. +func IsRuntimePackagePath(pkgpath string) bool { + rval := false + switch pkgpath { + case "runtime": + rval = true + case "reflect": + rval = true + case "syscall": + rval = true + default: + rval = strings.HasPrefix(pkgpath, "runtime/internal") + } + return rval +} diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go index f029a3c396..649f690194 100644 --- a/src/cmd/internal/objabi/reloctype.go +++ b/src/cmd/internal/objabi/reloctype.go @@ -89,6 +89,17 @@ const ( // should be linked into the final binary, even if there are no other // direct references. (This is used for types reachable by reflection.) R_USETYPE + // R_USEIFACE marks a type is converted to an interface in the function this + // relocation is applied to. The target is a type descriptor. + // This is a marker relocation (0-sized), for the linker's reachabililty + // analysis. + R_USEIFACE + // R_USEIFACEMETHOD marks an interface method that is used in the function + // this relocation is applied to. The target is an interface type descriptor. + // The addend is the offset of the method in the type descriptor. + // This is a marker relocation (0-sized), for the linker's reachabililty + // analysis. + R_USEIFACEMETHOD // R_METHODOFF resolves to a 32-bit offset from the beginning of the section // holding the data being relocated to the referenced symbol. // It is a variant of R_ADDROFF used when linking from the uncommonType of a @@ -145,6 +156,9 @@ const ( // R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address. R_ARM64_LDST8 + // R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address. + R_ARM64_LDST16 + // R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address. R_ARM64_LDST32 @@ -212,6 +226,14 @@ const ( // AUIPC + S-type instruction pair. R_RISCV_PCREL_STYPE + // R_RISCV_TLS_IE_ITYPE resolves a 32-bit TLS initial-exec TOC offset + // address using an AUIPC + I-type instruction pair. + R_RISCV_TLS_IE_ITYPE + + // R_RISCV_TLS_IE_STYPE resolves a 32-bit TLS initial-exec TOC offset + // address using an AUIPC + S-type instruction pair. + R_RISCV_TLS_IE_STYPE + // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. // TODO(mundaym): remove once variants can be serialized - see issue 14218. R_PCRELDBL diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go index 83dfe71e07..658a44f8b8 100644 --- a/src/cmd/internal/objabi/reloctype_string.go +++ b/src/cmd/internal/objabi/reloctype_string.go @@ -4,9 +4,75 @@ package objabi import "strconv" -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[R_ADDR-1] + _ = x[R_ADDRPOWER-2] + _ = x[R_ADDRARM64-3] + _ = x[R_ADDRMIPS-4] + _ = x[R_ADDROFF-5] + _ = x[R_WEAKADDROFF-6] + _ = x[R_SIZE-7] + _ = x[R_CALL-8] + _ = x[R_CALLARM-9] + _ = x[R_CALLARM64-10] + _ = x[R_CALLIND-11] + _ = x[R_CALLPOWER-12] + _ = x[R_CALLMIPS-13] + _ = x[R_CALLRISCV-14] + _ = x[R_CONST-15] + _ = x[R_PCREL-16] + _ = x[R_TLS_LE-17] + _ = x[R_TLS_IE-18] + _ = x[R_GOTOFF-19] + _ = x[R_PLT0-20] + _ = x[R_PLT1-21] + _ = x[R_PLT2-22] + _ = x[R_USEFIELD-23] + _ = x[R_USETYPE-24] + _ = x[R_USEIFACE-25] + _ = x[R_USEIFACEMETHOD-26] + _ = x[R_METHODOFF-27] + _ = x[R_POWER_TOC-28] + _ = x[R_GOTPCREL-29] + _ = x[R_JMPMIPS-30] + _ = x[R_DWARFSECREF-31] + _ = x[R_DWARFFILEREF-32] + _ = x[R_ARM64_TLS_LE-33] + _ = x[R_ARM64_TLS_IE-34] + _ = x[R_ARM64_GOTPCREL-35] + _ = x[R_ARM64_GOT-36] + _ = x[R_ARM64_PCREL-37] + _ = x[R_ARM64_LDST8-38] + _ = x[R_ARM64_LDST16-39] + _ = x[R_ARM64_LDST32-40] + _ = x[R_ARM64_LDST64-41] + _ = x[R_ARM64_LDST128-42] + _ = x[R_POWER_TLS_LE-43] + _ = x[R_POWER_TLS_IE-44] + _ = x[R_POWER_TLS-45] + _ = x[R_ADDRPOWER_DS-46] + _ = x[R_ADDRPOWER_GOT-47] + _ = x[R_ADDRPOWER_PCREL-48] + _ = x[R_ADDRPOWER_TOCREL-49] + _ = x[R_ADDRPOWER_TOCREL_DS-50] + _ = x[R_RISCV_PCREL_ITYPE-51] + _ = x[R_RISCV_PCREL_STYPE-52] + _ = x[R_RISCV_TLS_IE_ITYPE-53] + _ = x[R_RISCV_TLS_IE_STYPE-54] + _ = x[R_PCRELDBL-55] + _ = x[R_ADDRMIPSU-56] + _ = x[R_ADDRMIPSTLS-57] + _ = x[R_ADDRCUOFF-58] + _ = x[R_WASMIMPORT-59] + _ = x[R_XCOFFREF-60] +} + +const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 572, 583, 596, 607, 619, 629} +var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709} func (i RelocType) String() string { i -= 1 diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go index d2d6fdbda8..a73ab479a1 100644 --- a/src/cmd/internal/objabi/util.go +++ b/src/cmd/internal/objabi/util.go @@ -25,7 +25,6 @@ var ( GOARCH = envOr("GOARCH", defaultGOARCH) GOOS = envOr("GOOS", defaultGOOS) GO386 = envOr("GO386", defaultGO386) - GOAMD64 = goamd64() GOARM = goarm() GOMIPS = gomips() GOMIPS64 = gomips64() @@ -37,17 +36,16 @@ var ( const ( ElfRelocOffset = 256 - MachoRelocOffset = 2048 // reserve enough space for ELF relocations - Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. + MachoRelocOffset = 2048 // reserve enough space for ELF relocations ) -// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. -func goamd64() string { - return Go115AMD64 -} - func goarm() int { - switch v := envOr("GOARM", defaultGOARM); v { + def := defaultGOARM + if GOOS == "android" && GOARCH == "arm" { + // Android arm devices always support GOARM=7. + def = "7" + } + switch v := envOr("GOARM", def); v { case "5": return 5 case "6": @@ -139,7 +137,7 @@ func init() { } // Note: must agree with runtime.framepointer_enabled. -var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin") +var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin" || GOOS == "ios") func addexp(s string) { // Could do general integer parsing here, but the runtime copy doesn't yet. diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go index af9ada3324..f19bec5dcb 100644 --- a/src/cmd/internal/objfile/goobj.go +++ b/src/cmd/internal/objfile/goobj.go @@ -234,7 +234,15 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) { if f.arch == nil { return "", 0, nil } - pcdataBase := r.PcdataBase() + getSymData := func(s goobj.SymRef) []byte { + if s.PkgIdx != goobj.PkgIdxHashed { + // We don't need the data for non-hashed symbols, yet. + panic("not supported") + } + i := uint32(s.SymIdx + uint32(r.NSym()+r.NHashed64def())) + return r.BytesAt(r.DataOff(i), r.DataSize(i)) + } + ndef := uint32(r.NSym() + r.NHashed64def() + r.NHasheddef() + r.NNonpkgdef()) for i := uint32(0); i < ndef; i++ { osym := r.Sym(i) @@ -259,15 +267,11 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) { } b := r.BytesAt(r.DataOff(isym), r.DataSize(isym)) var info *goobj.FuncInfo - lengths := info.ReadFuncInfoLengths(b) - off, end := info.ReadPcline(b) - pcline := r.BytesAt(pcdataBase+off, int(end-off)) + pcline := getSymData(info.ReadPcline(b)) line := int(pcValue(pcline, pc-addr, f.arch)) - off, end = info.ReadPcfile(b) - pcfile := r.BytesAt(pcdataBase+off, int(end-off)) + pcfile := getSymData(info.ReadPcfile(b)) fileID := pcValue(pcfile, pc-addr, f.arch) - globalFileID := info.ReadFile(b, lengths.FileOff, uint32(fileID)) - fileName := r.File(int(globalFileID)) + fileName := r.File(int(fileID)) // Note: we provide only the name in the Func structure. // We could provide more if needed. return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: osym.Name(r)}} diff --git a/src/cmd/internal/objfile/macho.go b/src/cmd/internal/objfile/macho.go index fdb7e76dfc..1d6963f7c4 100644 --- a/src/cmd/internal/objfile/macho.go +++ b/src/cmd/internal/objfile/macho.go @@ -60,7 +60,7 @@ func (f *machoFile) symbols() ([]Sym, error) { } else if int(s.Sect) <= len(f.macho.Sections) { sect := f.macho.Sections[s.Sect-1] switch sect.Seg { - case "__TEXT": + case "__TEXT", "__DATA_CONST": sym.Code = 'R' case "__DATA": sym.Code = 'D' diff --git a/src/cmd/internal/pkgpath/pkgpath.go b/src/cmd/internal/pkgpath/pkgpath.go new file mode 100644 index 0000000000..40a040a81a --- /dev/null +++ b/src/cmd/internal/pkgpath/pkgpath.go @@ -0,0 +1,174 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkgpath determines the package path used by gccgo/GoLLVM symbols. +// This package is not used for the gc compiler. +package pkgpath + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "os" + "os/exec" + "strings" +) + +// ToSymbolFunc returns a function that may be used to convert a +// package path into a string suitable for use as a symbol. +// cmd is the gccgo/GoLLVM compiler in use, and tmpdir is a temporary +// directory to pass to ioutil.TempFile. +// For example, this returns a function that converts "net/http" +// into a string like "net..z2fhttp". The actual string varies for +// different gccgo/GoLLVM versions, which is why this returns a function +// that does the conversion appropriate for the compiler in use. +func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) { + // To determine the scheme used by cmd, we compile a small + // file and examine the assembly code. Older versions of gccgo + // use a simple mangling scheme where there can be collisions + // between packages whose paths are different but mangle to + // the same string. More recent versions use a new mangler + // that avoids these collisions. + const filepat = "*_gccgo_manglechck.go" + f, err := ioutil.TempFile(tmpdir, filepat) + if err != nil { + return nil, err + } + gofilename := f.Name() + f.Close() + defer os.Remove(gofilename) + + if err := ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil { + return nil, err + } + + command := exec.Command(cmd, "-S", "-o", "-", gofilename) + buf, err := command.Output() + if err != nil { + return nil, err + } + + // Original mangling: go.l__ufer.Run + // Mangling v2: go.l..u00e4ufer.Run + // Mangling v3: go_0l_u00e4ufer.Run + if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) { + return toSymbolV3, nil + } else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) { + return toSymbolV2, nil + } else if bytes.Contains(buf, []byte("go.l__ufer.Run")) { + return toSymbolV1, nil + } else { + return nil, errors.New(cmd + ": unrecognized mangling scheme") + } +} + +// mangleCheckCode is the package we compile to determine the mangling scheme. +const mangleCheckCode = ` +package läufer +func Run(x int) int { + return 1 +} +` + +// toSymbolV1 converts a package path using the original mangling scheme. +func toSymbolV1(ppath string) string { + clean := func(r rune) rune { + switch { + case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', + '0' <= r && r <= '9': + return r + } + return '_' + } + return strings.Map(clean, ppath) +} + +// toSymbolV2 converts a package path using the second mangling scheme. +func toSymbolV2(ppath string) string { + // This has to build at boostrap time, so it has to build + // with Go 1.4, so we don't use strings.Builder. + bsl := make([]byte, 0, len(ppath)) + changed := false + for _, c := range ppath { + if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' { + bsl = append(bsl, byte(c)) + continue + } + var enc string + switch { + case c == '.': + enc = ".x2e" + case c < 0x80: + enc = fmt.Sprintf("..z%02x", c) + case c < 0x10000: + enc = fmt.Sprintf("..u%04x", c) + default: + enc = fmt.Sprintf("..U%08x", c) + } + bsl = append(bsl, enc...) + changed = true + } + if !changed { + return ppath + } + return string(bsl) +} + +// v3UnderscoreCodes maps from a character that supports an underscore +// encoding to the underscore encoding character. +var v3UnderscoreCodes = map[byte]byte{ + '_': '_', + '.': '0', + '/': '1', + '*': '2', + ',': '3', + '{': '4', + '}': '5', + '[': '6', + ']': '7', + '(': '8', + ')': '9', + '"': 'a', + ' ': 'b', + ';': 'c', +} + +// toSymbolV3 converts a package path using the third mangling scheme. +func toSymbolV3(ppath string) string { + // This has to build at boostrap time, so it has to build + // with Go 1.4, so we don't use strings.Builder. + bsl := make([]byte, 0, len(ppath)) + changed := false + for _, c := range ppath { + if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') { + bsl = append(bsl, byte(c)) + continue + } + + if c < 0x80 { + if u, ok := v3UnderscoreCodes[byte(c)]; ok { + bsl = append(bsl, '_', u) + changed = true + continue + } + } + + var enc string + switch { + case c < 0x80: + enc = fmt.Sprintf("_x%02x", c) + case c < 0x10000: + enc = fmt.Sprintf("_u%04x", c) + default: + enc = fmt.Sprintf("_U%08x", c) + } + bsl = append(bsl, enc...) + changed = true + } + if !changed { + return ppath + } + return string(bsl) +} diff --git a/src/cmd/internal/pkgpath/pkgpath_test.go b/src/cmd/internal/pkgpath/pkgpath_test.go new file mode 100644 index 0000000000..232e803a60 --- /dev/null +++ b/src/cmd/internal/pkgpath/pkgpath_test.go @@ -0,0 +1,141 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgpath + +import ( + "os" + "testing" +) + +const testEnvName = "GO_PKGPATH_TEST_COMPILER" + +// This init function supports TestToSymbolFunc. For simplicity, +// we use the test binary itself as a sample gccgo driver. +// We set an environment variable to specify how it should behave. +func init() { + switch os.Getenv(testEnvName) { + case "": + return + case "v1": + os.Stdout.WriteString(`.string "go.l__ufer.Run"`) + os.Exit(0) + case "v2": + os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`) + os.Exit(0) + case "v3": + os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`) + os.Exit(0) + case "error": + os.Stdout.WriteString(`unknown string`) + os.Exit(0) + } +} + +func TestToSymbolFunc(t *testing.T) { + const input = "pä世🜃" + tests := []struct { + env string + fail bool + mangled string + }{ + { + env: "v1", + mangled: "p___", + }, + { + env: "v2", + mangled: "p..u00e4..u4e16..U0001f703", + }, + { + env: "v3", + mangled: "p_u00e4_u4e16_U0001f703", + }, + { + env: "error", + fail: true, + }, + } + + cmd := os.Args[0] + tmpdir := t.TempDir() + + defer os.Unsetenv(testEnvName) + + for _, test := range tests { + t.Run(test.env, func(t *testing.T) { + os.Setenv(testEnvName, test.env) + + fn, err := ToSymbolFunc(cmd, tmpdir) + if err != nil { + if !test.fail { + t.Errorf("ToSymbolFunc(%q, %q): unexpected error %v", cmd, tmpdir, err) + } + } else if test.fail { + t.Errorf("ToSymbolFunc(%q, %q) succeeded but expected to fail", cmd, tmpdir) + } else if got, want := fn(input), test.mangled; got != want { + t.Errorf("ToSymbolFunc(%q, %q)(%q) = %q, want %q", cmd, tmpdir, input, got, want) + } + }) + } +} + +var symbolTests = []struct { + input, v1, v2, v3 string +}{ + { + "", + "", + "", + "", + }, + { + "bytes", + "bytes", + "bytes", + "bytes", + }, + { + "net/http", + "net_http", + "net..z2fhttp", + "net_1http", + }, + { + "golang.org/x/net/http", + "golang_org_x_net_http", + "golang.x2eorg..z2fx..z2fnet..z2fhttp", + "golang_0org_1x_1net_1http", + }, + { + "pä世.🜃", + "p____", + "p..u00e4..u4e16.x2e..U0001f703", + "p_u00e4_u4e16_0_U0001f703", + }, +} + +func TestV1(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV1(test.input), test.v1; got != want { + t.Errorf("toSymbolV1(%q) = %q, want %q", test.input, got, want) + } + } +} + +func TestV2(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV2(test.input), test.v2; got != want { + t.Errorf("toSymbolV2(%q) = %q, want %q", test.input, got, want) + } + } +} + +func TestV3(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV3(test.input), test.v3; got != want { + t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want) + } + } +} diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go index c27b3b986d..ef7c017bd4 100644 --- a/src/cmd/internal/sys/supported.go +++ b/src/cmd/internal/sys/supported.go @@ -13,7 +13,9 @@ func RaceDetectorSupported(goos, goarch string) bool { switch goos { case "linux": return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" - case "darwin", "freebsd", "netbsd", "windows": + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "windows": return goarch == "amd64" default: return false @@ -32,13 +34,14 @@ func MSanSupported(goos, goarch string) bool { } // MustLinkExternal reports whether goos/goarch requires external linking. +// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.) func MustLinkExternal(goos, goarch string) bool { switch goos { case "android": if goarch != "arm64" { return true } - case "darwin": + case "ios": if goarch == "arm64" { return true } @@ -69,7 +72,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", - "darwin/amd64", + "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/386": return true } @@ -83,10 +86,11 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { case "pie": switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", - "darwin/amd64", + "darwin/amd64", "darwin/arm64", + "ios/amd64", "ios/arm64", "aix/ppc64", "windows/386", "windows/amd64", "windows/arm": return true @@ -104,7 +108,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { switch platform { case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", "android/amd64", "android/arm", "android/arm64", "android/386", - "darwin/amd64", + "darwin/amd64", "darwin/arm64", "freebsd/amd64": return true } @@ -114,3 +118,14 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { return false } } + +func InternalLinkPIESupported(goos, goarch string) bool { + switch goos + "/" + goarch { + case "darwin/amd64", "darwin/arm64", + "linux/amd64", "linux/arm64", + "android/arm64", + "windows-amd64", "windows-386", "windows-arm": + return true + } + return false +} diff --git a/src/cmd/internal/sys/supported_test.go b/src/cmd/internal/sys/supported_test.go new file mode 100644 index 0000000000..1217814af5 --- /dev/null +++ b/src/cmd/internal/sys/supported_test.go @@ -0,0 +1,18 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sys + +import ( + "internal/testenv" + "runtime" + "testing" +) + +func TestMustLinkExternalMatchesTestenv(t *testing.T) { + // MustLinkExternal and testenv.CanInternalLink are the exact opposite. + if b := MustLinkExternal(runtime.GOOS, runtime.GOARCH); b != !testenv.CanInternalLink() { + t.Fatalf("MustLinkExternal() == %v, testenv.CanInternalLink() == %v, don't match", b, testenv.CanInternalLink()) + } +} diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go index 88480064dd..db710bed6a 100644 --- a/src/cmd/link/dwarf_test.go +++ b/src/cmd/link/dwarf_test.go @@ -195,14 +195,18 @@ func TestDWARFiOS(t *testing.T) { } // Check to see if the ios tools are installed. It's possible to have the command line tools // installed without the iOS sdk. - if output, err := exec.Command("xcodebuild -showsdks").CombinedOutput(); err != nil { + if output, err := exec.Command("xcodebuild", "-showsdks").CombinedOutput(); err != nil { t.Skipf("error running xcodebuild, required for iOS cross build: %v", err) } else if !strings.Contains(string(output), "iOS SDK") { t.Skipf("iOS SDK not detected.") } cc := "CC=" + runtime.GOROOT() + "/misc/ios/clangwrap.sh" // iOS doesn't allow unmapped segments, so iOS executables don't have DWARF. - testDWARF(t, "", false, cc, "CGO_ENABLED=1", "GOOS=darwin", "GOARCH=arm64") + t.Run("exe", func(t *testing.T) { + testDWARF(t, "", false, cc, "CGO_ENABLED=1", "GOOS=ios", "GOARCH=arm64") + }) // However, c-archive iOS objects have embedded DWARF. - testDWARF(t, "c-archive", true, cc, "CGO_ENABLED=1", "GOOS=darwin", "GOARCH=arm64") + t.Run("c-archive", func(t *testing.T) { + testDWARF(t, "c-archive", true, cc, "CGO_ENABLED=1", "GOOS=ios", "GOARCH=arm64") + }) } diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index e5a6ef51b0..2d09a6160a 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -76,9 +76,9 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade targType = ldr.SymType(targ) } - switch r.Type() { + switch rt := r.Type(); rt { default: - if r.Type() >= objabi.ElfRelocOffset { + if rt >= objabi.ElfRelocOffset { ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type())) return false } @@ -167,13 +167,24 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 0, objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0, objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0: - // TODO: What is the difference between all these? su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_ADDR) if targType == sym.SDYNIMPORT { ldr.Errorf(s, "unexpected reloc for dynamic symbol %s", ldr.SymName(targ)) } + if target.IsPIE() && target.IsInternal() { + // For internal linking PIE, this R_ADDR relocation cannot + // be resolved statically. We need to generate a dynamic + // relocation. Let the code below handle it. + if rt == objabi.MachoRelocOffset+ld.MACHO_X86_64_RELOC_UNSIGNED*2 { + break + } else { + // MACHO_X86_64_RELOC_SIGNED or MACHO_X86_64_RELOC_BRANCH + // Can this happen? The object is expected to be PIC. + ldr.Errorf(s, "unsupported relocation for PIE: %v", rt) + } + } return true case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1: @@ -223,7 +234,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade if targType != sym.SDYNIMPORT { ldr.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", ldr.SymName(targ)) } - ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_X86_64_GLOB_DAT)) + ld.AddGotSym(target, ldr, syms, targ, 0) su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_PCREL) su.SetRelocSym(rIdx, syms.GOT) @@ -343,7 +354,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rela := ldr.MakeSymbolUpdater(syms.Rela) rela.AddAddrPlus(target.Arch, s, int64(r.Off())) if r.Siz() == 8 { - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE))) + rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_X86_64_RELATIVE))) } else { ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) } @@ -355,28 +366,15 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade return true } - if target.IsDarwin() && ldr.SymSize(s) == int64(target.Arch.PtrSize) && r.Off() == 0 { + if target.IsDarwin() { // Mach-O relocations are a royal pain to lay out. - // They use a compact stateful bytecode representation - // that is too much bother to deal with. - // Instead, interpret the C declaration - // void *_Cvar_stderr = &stderr; - // as making _Cvar_stderr the name of a GOT entry - // for stderr. This is separate from the usual GOT entry, - // just in case the C code assigns to the variable, - // and of course it only works for single pointers, - // but we only need to support cgo and that's all it needs. - ld.Adddynsym(ldr, target, syms, targ) - - got := ldr.MakeSymbolUpdater(syms.GOT) - su := ldr.MakeSymbolUpdater(s) - su.SetType(got.Type()) - got.AddInteriorSym(s) - su.SetValue(got.Size()) - got.AddUint64(target.Arch, 0) - leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT) - leg.AddUint32(target.Arch, uint32(ldr.SymDynid(targ))) - su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym + // They use a compact stateful bytecode representation. + // Here we record what are needed and encode them later. + ld.MachoAddRebase(s, int64(r.Off())) + // Not mark r done here. So we still apply it statically, + // so in the file content we'll also have the right offset + // to the relocation target. So it can be examined statically + // (e.g. go version). return true } } @@ -415,11 +413,7 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, case objabi.R_CALL: if siz == 4 { if ldr.SymType(r.Xsym) == sym.SDYNIMPORT { - if ctxt.DynlinkingGo() { - out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32) - } else { - out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32) - } + out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32) } else { out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32) } @@ -622,31 +616,21 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rela.AddAddrPlus(target.Arch, got.Sym(), got.Size()-8) sDynid := ldr.SymDynid(s) - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(sDynid), uint32(elf.R_X86_64_JMP_SLOT))) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_X86_64_JMP_SLOT))) rela.AddUint64(target.Arch, 0) ldr.SetPlt(s, int32(plt.Size()-16)) } else if target.IsDarwin() { - // To do lazy symbol lookup right, we're supposed - // to tell the dynamic loader which library each - // symbol comes from and format the link info - // section just so. I'm too lazy (ha!) to do that - // so for now we'll just use non-lazy pointers, - // which don't need to be told which library to use. - // - // https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html - // has details about what we're avoiding. - - ld.AddGotSym(target, ldr, syms, s, uint32(elf.R_X86_64_GLOB_DAT)) - plt := ldr.MakeSymbolUpdater(syms.PLT) + ld.AddGotSym(target, ldr, syms, s, 0) sDynid := ldr.SymDynid(s) lep := ldr.MakeSymbolUpdater(syms.LinkEditPLT) lep.AddUint32(target.Arch, uint32(sDynid)) - // jmpq *got+size(IP) + plt := ldr.MakeSymbolUpdater(syms.PLT) ldr.SetPlt(s, int32(plt.Size())) + // jmpq *got+size(IP) plt.AddUint8(0xff) plt.AddUint8(0x25) plt.AddPCRelPlus(target.Arch, syms.GOT, int64(ldr.SymGot(s))) @@ -654,6 +638,7 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade ldr.Errorf(s, "addpltsym: unsupported binary format") } } + func tlsIEtoLE(P []byte, off, size int) { // Transform the PC-relative instruction into a constant load. // That is, diff --git a/src/cmd/link/internal/amd64/l.go b/src/cmd/link/internal/amd64/l.go index a9afb3a39f..c9ea90a9c8 100644 --- a/src/cmd/link/internal/amd64/l.go +++ b/src/cmd/link/internal/amd64/l.go @@ -33,7 +33,7 @@ package amd64 const ( maxAlign = 32 // max data alignment minAlign = 1 // min data alignment - funcAlign = 16 + funcAlign = 32 ) /* Used by ../internal/ld/dwarf.go */ diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go index 777f99dbe2..d09c90ea28 100644 --- a/src/cmd/link/internal/amd64/obj.go +++ b/src/cmd/link/internal/amd64/obj.go @@ -39,13 +39,8 @@ import ( func Init() (*sys.Arch, ld.Arch) { arch := sys.ArchAMD64 - fa := funcAlign - if objabi.GOAMD64 == "alignedjumps" { - fa = 32 - } - theArch := ld.Arch{ - Funcalign: fa, + Funcalign: funcAlign, Maxalign: maxAlign, Minalign: minAlign, Dwarfregsp: dwarfRegSP, diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 611c96ce35..755b472694 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -231,7 +231,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade ld.Adddynsym(ldr, target, syms, targ) rel := ldr.MakeSymbolUpdater(syms.Rel) rel.AddAddrPlus(target.Arch, s, int64(r.Off())) - rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(targ)), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_CONST) // write r->add during relocsym su.SetRelocSym(rIdx, 0) @@ -629,7 +629,7 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade // rel rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) - rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_ARM_JUMP_SLOT))) + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), uint32(elf.R_ARM_JUMP_SLOT))) } else { ldr.Errorf(s, "addpltsym: unsupported binary format") } diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 945b83822c..30819db4c6 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -71,13 +71,13 @@ func gentext(ctxt *ld.Link, ldr *loader.Loader) { } func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool { - targ := r.Sym() var targType sym.SymKind if targ != 0 { targType = ldr.SymType(targ) } + const pcrel = 1 switch r.Type() { default: if r.Type() >= objabi.ElfRelocOffset { @@ -177,6 +177,14 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade su.SetRelocType(rIdx, objabi.R_ARM64_LDST8) return true + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST16_ABS_LO12_NC): + if targType == sym.SDYNIMPORT { + ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) + } + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_ARM64_LDST16) + return true + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST32_ABS_LO12_NC): if targType == sym.SDYNIMPORT { ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) @@ -201,6 +209,75 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_ARM64_LDST128) return true + + // Handle relocations found in Mach-O object files. + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_UNSIGNED*2: + if targType == sym.SDYNIMPORT { + ldr.Errorf(s, "unexpected reloc for dynamic symbol %s", ldr.SymName(targ)) + } + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_ADDR) + if target.IsPIE() && target.IsInternal() { + // For internal linking PIE, this R_ADDR relocation cannot + // be resolved statically. We need to generate a dynamic + // relocation. Let the code below handle it. + break + } + return true + + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_BRANCH26*2 + pcrel: + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_CALLARM64) + if targType == sym.SDYNIMPORT { + addpltsym(target, ldr, syms, targ) + su.SetRelocSym(rIdx, syms.PLT) + su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ))) + } + return true + + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_PAGE21*2 + pcrel, + objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_PAGEOFF12*2: + if targType == sym.SDYNIMPORT { + ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) + } + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_ARM64_PCREL) + return true + + case objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGE21*2 + pcrel, + objabi.MachoRelocOffset + ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12*2: + if targType != sym.SDYNIMPORT { + // have symbol + // turn MOVD sym@GOT (adrp+ldr) into MOVD $sym (adrp+add) + data := ldr.Data(s) + off := r.Off() + if int(off+3) >= len(data) { + ldr.Errorf(s, "unexpected GOT_LOAD reloc for non-dynamic symbol %s", ldr.SymName(targ)) + return false + } + o := target.Arch.ByteOrder.Uint32(data[off:]) + su := ldr.MakeSymbolUpdater(s) + switch { + case (o>>24)&0x9f == 0x90: // adrp + // keep instruction unchanged, change relocation type below + case o>>24 == 0xf9: // ldr + // rewrite to add + o = (0x91 << 24) | (o & (1<<22 - 1)) + su.MakeWritable() + su.SetUint32(target.Arch, int64(off), o) + default: + ldr.Errorf(s, "unexpected GOT_LOAD reloc for non-dynamic symbol %s", ldr.SymName(targ)) + return false + } + su.SetRelocType(rIdx, objabi.R_ARM64_PCREL) + return true + } + ld.AddGotSym(target, ldr, syms, targ, 0) + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_ARM64_GOT) + su.SetRelocSym(rIdx, syms.GOT) + su.SetRelocAdd(rIdx, int64(ldr.SymGot(targ))) + return true } // Reread the reloc to incorporate any changes in type above. @@ -219,6 +296,16 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade // External linker will do this relocation. return true } + // Internal linking. + if r.Add() != 0 { + ldr.Errorf(s, "PLT call with non-zero addend (%v)", r.Add()) + } + // Build a PLT entry and change the relocation target to that entry. + addpltsym(target, ldr, syms, targ) + su := ldr.MakeSymbolUpdater(s) + su.SetRelocSym(rIdx, syms.PLT) + su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ))) + return true case objabi.R_ADDR: if ldr.SymType(s) == sym.STEXT && target.IsElf() { @@ -302,7 +389,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rela := ldr.MakeSymbolUpdater(syms.Rela) rela.AddAddrPlus(target.Arch, s, int64(r.Off())) if r.Siz() == 8 { - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE))) + rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_AARCH64_RELATIVE))) } else { ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) } @@ -313,6 +400,18 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade // (e.g. go version). return true } + + if target.IsDarwin() { + // Mach-O relocations are a royal pain to lay out. + // They use a compact stateful bytecode representation. + // Here we record what are needed and encode them later. + ld.MachoAddRebase(s, int64(r.Off())) + // Not mark r done here. So we still apply it statically, + // so in the file content we'll also have the right offset + // to the relocation target. So it can be examined statically + // (e.g. go version). + return true + } } return false } @@ -364,6 +463,9 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, return true } +// sign-extends from 24-bit. +func signext24(x int64) int64 { return x << 40 >> 40 } + func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool { var v uint32 @@ -371,7 +473,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy rt := r.Type siz := r.Size - if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 { + if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL { if ldr.SymDynid(rs) < 0 { ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs)) return false @@ -387,6 +489,10 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy } } + if r.Xadd != signext24(r.Xadd) { + ldr.Errorf(s, "relocation addend overflow: %s+0x%x", ldr.SymName(rs), r.Xadd) + } + switch rt { default: return false @@ -415,6 +521,22 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy } v |= 1 << 24 // pc-relative bit v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28 + case objabi.R_ARM64_GOTPCREL: + siz = 4 + // Two relocation entries: MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 MACHO_ARM64_RELOC_GOT_LOAD_PAGE21 + // if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND. + if r.Xadd != 0 { + out.Write32(uint32(sectoff + 4)) + out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff)) + } + out.Write32(uint32(sectoff + 4)) + out.Write32(v | (ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 << 28) | (2 << 25)) + if r.Xadd != 0 { + out.Write32(uint32(sectoff)) + out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff)) + } + v |= 1 << 24 // pc-relative bit + v |= ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGE21 << 28 } switch siz { @@ -457,7 +579,7 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade } nExtReloc = 2 // need two ELF/Mach-O relocations. see elfreloc1/machoreloc1 - if target.IsDarwin() && rt == objabi.R_ADDRARM64 && xadd != 0 { + if target.IsDarwin() && xadd != 0 { nExtReloc = 4 // need another two relocations for non-zero addend } @@ -633,14 +755,28 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade } o0 := (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5) return val | int64(o0), noExtReloc, isOk - } else if (val>>24)&0x91 == 0x91 { - // R_AARCH64_ADD_ABS_LO12_NC + } else if (val>>24)&0x9f == 0x91 { + // ELF R_AARCH64_ADD_ABS_LO12_NC or Mach-O ARM64_RELOC_PAGEOFF12 // patch instruction: add t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) o1 := uint32(t&0xfff) << 10 return val | int64(o1), noExtReloc, isOk + } else if (val>>24)&0x3b == 0x39 { + // Mach-O ARM64_RELOC_PAGEOFF12 + // patch ldr/str(b/h/w/d/q) (integer or vector) instructions, which have different scaling factors. + // Mach-O uses same relocation type for them. + shift := uint32(val) >> 30 + if shift == 0 && (val>>20)&0x048 == 0x048 { // 128-bit vector load + shift = 4 + } + t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) + if t&(1<<shift-1) != 0 { + ldr.Errorf(s, "invalid address: %x for relocation type: ARM64_RELOC_PAGEOFF12", t) + } + o1 := (uint32(t&0xfff) >> shift) << 10 + return val | int64(o1), noExtReloc, isOk } else { - ldr.Errorf(s, "unsupported instruction for %x R_PCRELARM64", val) + ldr.Errorf(s, "unsupported instruction for %x R_ARM64_PCREL", val) } case objabi.R_ARM64_LDST8: @@ -648,6 +784,14 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade o0 := uint32(t&0xfff) << 10 return val | int64(o0), noExtReloc, true + case objabi.R_ARM64_LDST16: + t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) + if t&1 != 0 { + ldr.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST16_ABS_LO12_NC", t) + } + o0 := (uint32(t&0xfff) >> 1) << 10 + return val | int64(o0), noExtReloc, true + case objabi.R_ARM64_LDST32: t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) if t&3 != 0 { @@ -792,10 +936,38 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rela.AddAddrPlus(target.Arch, gotplt.Sym(), gotplt.Size()-8) sDynid := ldr.SymDynid(s) - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(sDynid), uint32(elf.R_AARCH64_JUMP_SLOT))) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_AARCH64_JUMP_SLOT))) rela.AddUint64(target.Arch, 0) ldr.SetPlt(s, int32(plt.Size()-16)) + } else if target.IsDarwin() { + ld.AddGotSym(target, ldr, syms, s, 0) + + sDynid := ldr.SymDynid(s) + lep := ldr.MakeSymbolUpdater(syms.LinkEditPLT) + lep.AddUint32(target.Arch, uint32(sDynid)) + + plt := ldr.MakeSymbolUpdater(syms.PLT) + ldr.SetPlt(s, int32(plt.Size())) + + // adrp x16, GOT + plt.AddUint32(target.Arch, 0x90000010) + r, _ := plt.AddRel(objabi.R_ARM64_GOT) + r.SetOff(int32(plt.Size() - 4)) + r.SetSiz(4) + r.SetSym(syms.GOT) + r.SetAdd(int64(ldr.SymGot(s))) + + // ldr x17, [x16, <offset>] + plt.AddUint32(target.Arch, 0xf9400211) + r, _ = plt.AddRel(objabi.R_ARM64_GOT) + r.SetOff(int32(plt.Size() - 4)) + r.SetSiz(4) + r.SetSym(syms.GOT) + r.SetAdd(int64(ldr.SymGot(s))) + + // br x17 + plt.AddUint32(target.Arch, 0xd61f0220) } else { ldr.Errorf(s, "addpltsym: unsupported binary format") } diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go index a980cfee52..ab3dfd99f7 100644 --- a/src/cmd/link/internal/arm64/obj.go +++ b/src/cmd/link/internal/arm64/obj.go @@ -102,7 +102,7 @@ func archinit(ctxt *ld.Link) { case objabi.Hdarwin: /* apple MACH */ ld.HEADR = ld.INITIAL_MACHO_HEADR if *ld.FlagTextAddr == -1 { - *ld.FlagTextAddr = 4096 + int64(ld.HEADR) + *ld.FlagTextAddr = 1<<32 + int64(ld.HEADR) } if *ld.FlagRound == -1 { *ld.FlagRound = 16384 // 16K page alignment diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go index 52adbc3bab..e4fd591676 100644 --- a/src/cmd/link/internal/ld/ar.go +++ b/src/cmd/link/internal/ld/ar.go @@ -170,7 +170,7 @@ func readArmap(filename string, f *bio.Reader, arhdr ArHdr) archiveMap { // For Mach-O and PE/386 files we strip a leading // underscore from the symbol name. - if objabi.GOOS == "darwin" || (objabi.GOOS == "windows" && objabi.GOARCH == "386") { + if objabi.GOOS == "darwin" || objabi.GOOS == "ios" || (objabi.GOOS == "windows" && objabi.GOARCH == "386") { if name[0] == '_' && len(name) > 1 { name = name[1:] } diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go index 2373b500e3..d1e06239a5 100644 --- a/src/cmd/link/internal/ld/config.go +++ b/src/cmd/link/internal/ld/config.go @@ -35,11 +35,16 @@ func (mode *BuildMode) Set(s string) error { default: return fmt.Errorf("invalid buildmode: %q", s) case "exe": - *mode = BuildModeExe + switch objabi.GOOS + "/" + objabi.GOARCH { + case "darwin/arm64", "windows/arm": // On these platforms, everything is PIE + *mode = BuildModePIE + default: + *mode = BuildModeExe + } case "pie": switch objabi.GOOS { - case "aix", "android", "linux", "windows": - case "darwin", "freebsd": + case "aix", "android", "linux", "windows", "darwin", "ios": + case "freebsd": switch objabi.GOARCH { case "amd64": default: @@ -51,7 +56,7 @@ func (mode *BuildMode) Set(s string) error { *mode = BuildModePIE case "c-archive": switch objabi.GOOS { - case "aix", "darwin", "linux": + case "aix", "darwin", "ios", "linux": case "freebsd": switch objabi.GOARCH { case "amd64": @@ -95,7 +100,13 @@ func (mode *BuildMode) Set(s string) error { default: return badmode() } - case "darwin", "freebsd": + case "darwin": + switch objabi.GOARCH { + case "amd64", "arm64": + default: + return badmode() + } + case "freebsd": switch objabi.GOARCH { case "amd64": default: @@ -186,7 +197,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { // Internally linking cgo is incomplete on some architectures. // https://golang.org/issue/14449 // https://golang.org/issue/21961 - if iscgo && ctxt.Arch.InFamily(sys.MIPS64, sys.MIPS, sys.PPC64) { + if iscgo && ctxt.Arch.InFamily(sys.MIPS64, sys.MIPS, sys.PPC64, sys.RISCV64) { return true, objabi.GOARCH + " does not support internal cgo" } if iscgo && objabi.GOOS == "android" { @@ -210,6 +221,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { switch objabi.GOOS + "/" + objabi.GOARCH { case "linux/amd64", "linux/arm64", "android/arm64": case "windows/386", "windows/amd64", "windows/arm": + case "darwin/amd64", "darwin/arm64": default: // Internal linking does not support TLS_IE. return true, "buildmode=pie" @@ -263,8 +275,6 @@ func determineLinkMode(ctxt *Link) { } case LinkExternal: switch { - case objabi.GOARCH == "riscv64": - Exitf("external linking not supported for %s/riscv64", objabi.GOOS) case objabi.GOARCH == "ppc64" && objabi.GOOS != "aix": Exitf("external linking not supported for %s/ppc64", objabi.GOOS) } diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 8324a98a26..00130044ab 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -390,6 +390,12 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr) case objabi.R_WEAKADDROFF, objabi.R_METHODOFF: if !ldr.AttrReachable(rs) { + if rt == objabi.R_METHODOFF { + // Set it to a sentinel value. The runtime knows this is not pointing to + // anything valid. + o = -1 + break + } continue } fallthrough @@ -698,6 +704,9 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) { relocs := ctxt.loader.Relocs(s) for ri := 0; ri < relocs.Count(); ri++ { r := relocs.At(ri) + if r.IsMarker() { + continue // skip marker relocations + } targ := r.Sym() if targ == 0 { continue @@ -775,6 +784,9 @@ func dynrelocsym(ctxt *Link, s loader.Sym) { relocs := ldr.Relocs(s) for ri := 0; ri < relocs.Count(); ri++ { r := relocs.At(ri) + if r.IsMarker() { + continue // skip marker relocations + } if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal { // It's expected that some relocations will be done // later by relocsym (R_TLS_LE, R_ADDROFF), so @@ -930,7 +942,7 @@ func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym, break } if val < addr { - ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, val, ldr.SymType(s)) + ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%v sect=%v", addr, val, ldr.SymType(s), ldr.SymSect(s).Name) errorexit() } if addr < val { @@ -939,6 +951,9 @@ func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym, } P := out.WriteSym(ldr, s) st.relocsym(s, P) + if f, ok := ctxt.generatorSyms[s]; ok { + f(ctxt, s) + } addr += int64(len(P)) siz := ldr.SymSize(s) if addr < val+siz { @@ -1308,9 +1323,9 @@ func (state *dodataState) makeRelroForSharedLib(target *Link) { // relro Type before it reaches here. isRelro = true case sym.SFUNCTAB: - if target.IsAIX() && ldr.SymName(s) == "runtime.etypes" { + if ldr.SymName(s) == "runtime.etypes" { // runtime.etypes must be at the end of - // the relro datas. + // the relro data. isRelro = true } } @@ -1706,7 +1721,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) { ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect) bssGcEnd := state.datsize - int64(sect.Vaddr) - // Emit gcdata for bcc symbols now that symbol values have been assigned. + // Emit gcdata for bss symbols now that symbol values have been assigned. gcsToEmit := []struct { symName string symKind sym.SymKind @@ -1826,13 +1841,16 @@ func (state *dodataState) allocateDataSections(ctxt *Link) { const fallbackPerm = 04 relroSecPerm := fallbackPerm genrelrosecname := func(suffix string) string { + if suffix == "" { + return ".rodata" + } return suffix } seg := segro if ctxt.UseRelro() { segrelro := &Segrelrodata - if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix { + if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() { // Using a separate segment with an external // linker results in some programs moving // their data sections unexpectedly, which @@ -1845,9 +1863,12 @@ func (state *dodataState) allocateDataSections(ctxt *Link) { state.datsize = 0 } - genrelrosecname = func(suffix string) string { - return ".data.rel.ro" + suffix + if !ctxt.IsDarwin() { // We don't need the special names on darwin. + genrelrosecname = func(suffix string) string { + return ".data.rel.ro" + suffix + } } + relroReadOnly := []sym.SymKind{} for _, symnro := range sym.ReadOnly { symn := sym.RelROMap[symnro] @@ -1923,7 +1944,10 @@ func (state *dodataState) allocateDataSections(ctxt *Link) { ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect) ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect) ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect) - ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab_old", 0), sect) + ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect) + ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect) + ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect) + ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect) ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect) if ctxt.HeadType == objabi.Haix { xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB) @@ -2167,7 +2191,7 @@ func (ctxt *Link) textaddress() { ctxt.Textp[0] = text } - va := uint64(*FlagTextAddr) + va := uint64(Rnd(*FlagTextAddr, int64(Funcalign))) n := 1 sect.Vaddr = va ntramps := 0 @@ -2193,7 +2217,7 @@ func (ctxt *Link) textaddress() { // Set the address of the start/end symbols, if not already // (i.e. not darwin+dynlink or AIX+external, see above). ldr.SetSymValue(etext, int64(va)) - ldr.SetSymValue(text, *FlagTextAddr) + ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr)) } // merge tramps into Textp, keeping Textp in address order @@ -2507,7 +2531,10 @@ func (ctxt *Link) address() []*sym.Segment { ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr)) ctxt.defineInternal("runtime.pcheader", sym.SRODATA) ctxt.defineInternal("runtime.funcnametab", sym.SRODATA) - ctxt.defineInternal("runtime.pclntab_old", sym.SRODATA) + ctxt.defineInternal("runtime.cutab", sym.SRODATA) + ctxt.defineInternal("runtime.filetab", sym.SRODATA) + ctxt.defineInternal("runtime.pctab", sym.SRODATA) + ctxt.defineInternal("runtime.functab", sym.SRODATA) ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length)) ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr)) ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length)) diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index 0269429723..d8813fa936 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -62,6 +62,12 @@ func (d *deadcodePass) init() { } } names = append(names, *flagEntrySymbol) + if !d.ctxt.linkShared && d.ctxt.BuildMode != BuildModePlugin { + // runtime.buildVersion and runtime.modinfo are referenced in .go.buildinfo section + // (see function buildinfo in data.go). They should normally be reachable from the + // runtime. Just make it explicit, in case. + names = append(names, "runtime.buildVersion", "runtime.modinfo") + } if d.ctxt.BuildMode == BuildModePlugin { names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs") @@ -106,39 +112,67 @@ func (d *deadcodePass) flood() { if isgotype { usedInIface = d.ldr.AttrUsedInIface(symIdx) - p := d.ldr.Data(symIdx) - if len(p) != 0 && decodetypeKind(d.ctxt.Arch, p)&kindMask == kindInterface { - for _, sig := range d.decodeIfaceMethods(d.ldr, d.ctxt.Arch, symIdx, &relocs) { - if d.ctxt.Debugvlog > 1 { - d.ctxt.Logf("reached iface method: %v\n", sig) - } - d.ifaceMethod[sig] = true - } - } } methods = methods[:0] for i := 0; i < relocs.Count(); i++ { r := relocs.At(i) t := r.Type() - if t == objabi.R_WEAKADDROFF { + switch t { + case objabi.R_WEAKADDROFF: continue - } - if t == objabi.R_METHODOFF { + case objabi.R_METHODOFF: if i+2 >= relocs.Count() { panic("expect three consecutive R_METHODOFF relocs") } if usedInIface { methods = append(methods, methodref{src: symIdx, r: i}) + // The method descriptor is itself a type descriptor, and + // it can be used to reach other types, e.g. by using + // reflect.Type.Method(i).Type.In(j). We need to traverse + // its child types with UsedInIface set. (See also the + // comment below.) + rs := r.Sym() + if !d.ldr.AttrUsedInIface(rs) { + d.ldr.SetAttrUsedInIface(rs, true) + if d.ldr.AttrReachable(rs) { + d.ldr.SetAttrReachable(rs, false) + d.mark(rs, symIdx) + } + } } i += 2 continue - } - if t == objabi.R_USETYPE { + case objabi.R_USETYPE: // type symbol used for DWARF. we need to load the symbol but it may not // be otherwise reachable in the program. // do nothing for now as we still load all type symbols. continue + case objabi.R_USEIFACE: + // R_USEIFACE is a marker relocation that tells the linker the type is + // converted to an interface, i.e. should have UsedInIface set. See the + // comment below for why we need to unset the Reachable bit and re-mark it. + rs := r.Sym() + if !d.ldr.AttrUsedInIface(rs) { + d.ldr.SetAttrUsedInIface(rs, true) + if d.ldr.AttrReachable(rs) { + d.ldr.SetAttrReachable(rs, false) + d.mark(rs, symIdx) + } + } + continue + case objabi.R_USEIFACEMETHOD: + // R_USEIFACEMETHOD is a marker relocation that marks an interface + // method as used. + rs := r.Sym() + if d.ldr.SymType(rs) != sym.SDYNIMPORT { // don't decode DYNIMPORT symbol (we'll mark all exported methods anyway) + m := d.decodeIfaceMethod(d.ldr, d.ctxt.Arch, rs, r.Add()) + if d.ctxt.Debugvlog > 1 { + d.ctxt.Logf("reached iface method: %v\n", m) + } + d.ifaceMethod[m] = true + } + continue } rs := r.Sym() if isgotype && usedInIface && d.ldr.IsGoType(rs) && !d.ldr.AttrUsedInIface(rs) { @@ -161,13 +195,9 @@ func (d *deadcodePass) flood() { naux := d.ldr.NAux(symIdx) for i := 0; i < naux; i++ { a := d.ldr.Aux(symIdx, i) - if a.Type() == goobj.AuxGotype && !d.ctxt.linkShared { + if a.Type() == goobj.AuxGotype { // A symbol being reachable doesn't imply we need its // type descriptor. Don't mark it. - // TODO: when -linkshared, the GCProg generation code - // seems to need it. I'm not sure why. I think it could - // just reach to the type descriptor's data without - // requiring to mark it reachable. continue } d.mark(a.Sym(), symIdx) @@ -209,15 +239,21 @@ func (d *deadcodePass) mark(symIdx, parent loader.Sym) { if symIdx != 0 && !d.ldr.AttrReachable(symIdx) { d.wq.push(symIdx) d.ldr.SetAttrReachable(symIdx, true) - if objabi.Fieldtrack_enabled != 0 { + if objabi.Fieldtrack_enabled != 0 && d.ldr.Reachparent[symIdx] == 0 { d.ldr.Reachparent[symIdx] = parent } if *flagDumpDep { to := d.ldr.SymName(symIdx) if to != "" { + if d.ldr.AttrUsedInIface(symIdx) { + to += " <UsedInIface>" + } from := "_" if parent != 0 { from = d.ldr.SymName(parent) + if d.ldr.AttrUsedInIface(parent) { + from += " <UsedInIface>" + } } fmt.Printf("%s -> %s\n", from, to) } @@ -349,23 +385,17 @@ func (d *deadcodePass) decodeMethodSig(ldr *loader.Loader, arch *sys.Arch, symId return methods } -func (d *deadcodePass) decodeIfaceMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig { +// Decode the method of interface type symbol symIdx at offset off. +func (d *deadcodePass) decodeIfaceMethod(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, off int64) methodsig { p := ldr.Data(symIdx) if decodetypeKind(arch, p)&kindMask != kindInterface { panic(fmt.Sprintf("symbol %q is not an interface", ldr.SymName(symIdx))) } - rel := decodeReloc(ldr, symIdx, relocs, int32(commonsize(arch)+arch.PtrSize)) - s := rel.Sym() - if s == 0 { - return nil - } - if s != symIdx { - panic(fmt.Sprintf("imethod slice pointer in %q leads to a different symbol", ldr.SymName(symIdx))) - } - off := int(rel.Add()) // array of reflect.imethod values - numMethods := int(decodetypeIfaceMethodCount(arch, p)) - sizeofIMethod := 4 + 4 - return d.decodeMethodSig(ldr, arch, symIdx, relocs, off, sizeofIMethod, numMethods) + relocs := ldr.Relocs(symIdx) + var m methodsig + m.name = decodetypeName(ldr, symIdx, &relocs, int(off)) + m.typ = decodeRelocSym(ldr, symIdx, &relocs, int32(off+4)) + return m } func (d *deadcodePass) decodetypeMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig { diff --git a/src/cmd/link/internal/ld/deadcode_test.go b/src/cmd/link/internal/ld/deadcode_test.go index 59122e9603..b756091613 100644 --- a/src/cmd/link/internal/ld/deadcode_test.go +++ b/src/cmd/link/internal/ld/deadcode_test.go @@ -32,6 +32,8 @@ func TestDeadcode(t *testing.T) { {"typedesc", "", "type.main.T"}, {"ifacemethod", "", "main.T.M"}, {"ifacemethod2", "main.T.M", ""}, + {"ifacemethod3", "main.S.M", ""}, + {"ifacemethod4", "", "main.T.M"}, } for _, test := range tests { test := test diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index d1f2ac583d..2ab9a55e96 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -23,6 +23,7 @@ import ( "cmd/link/internal/sym" "fmt" "log" + "path" "runtime" "sort" "strings" @@ -1173,13 +1174,81 @@ func expandFile(fname string) string { return expandGoroot(fname) } -// writelines collects up and chai,ns together the symbols needed to +// writeDirFileTables emits the portion of the DWARF line table +// prologue containing the include directories and file names, +// described in section 6.2.4 of the DWARF 4 standard. It walks the +// filepaths for the unit to discover any common directories, which +// are emitted to the directory table first, then the file table is +// emitted after that. +func (d *dwctxt) writeDirFileTables(unit *sym.CompilationUnit, lsu *loader.SymbolBuilder) { + type fileDir struct { + base string + dir int + } + dirNums := make(map[string]int) + dirs := []string{""} + files := []fileDir{} + + // Preprocess files to collect directories. This assumes that the + // file table is already de-duped. + for i, name := range unit.FileTable { + name := expandFile(name) + if len(name) == 0 { + // Can't have empty filenames, and having a unique + // filename is quite useful for debugging. + name = fmt.Sprintf("<missing>_%d", i) + } + // Note the use of "path" here and not "filepath". The compiler + // hard-codes to use "/" in DWARF paths (even for Windows), so we + // want to maintain that here. + file := path.Base(name) + dir := path.Dir(name) + dirIdx, ok := dirNums[dir] + if !ok && dir != "." { + dirIdx = len(dirNums) + 1 + dirNums[dir] = dirIdx + dirs = append(dirs, dir) + } + files = append(files, fileDir{base: file, dir: dirIdx}) + + // We can't use something that may be dead-code + // eliminated from a binary here. proc.go contains + // main and the scheduler, so it's not going anywhere. + if i := strings.Index(name, "runtime/proc.go"); i >= 0 { + d.dwmu.Lock() + if gdbscript == "" { + k := strings.Index(name, "runtime/proc.go") + gdbscript = name[:k] + "runtime/runtime-gdb.py" + } + d.dwmu.Unlock() + } + } + + // Emit directory section. This is a series of nul terminated + // strings, followed by a single zero byte. + lsDwsym := dwSym(lsu.Sym()) + for k := 1; k < len(dirs); k++ { + d.AddString(lsDwsym, dirs[k]) + } + lsu.AddUint8(0) // terminator + + // Emit file section. + for k := 0; k < len(files); k++ { + d.AddString(lsDwsym, files[k].base) + dwarf.Uleb128put(d, lsDwsym, int64(files[k].dir)) + lsu.AddUint8(0) // mtime + lsu.AddUint8(0) // length + } + lsu.AddUint8(0) // terminator +} + +// writelines collects up and chains together the symbols needed to // form the DWARF line table for the specified compilation unit, // returning a list of symbols. The returned list will include an -// initial symbol containing the line table header and prolog (with +// initial symbol containing the line table header and prologue (with // file table), then a series of compiler-emitted line table symbols // (one per live function), and finally an epilog symbol containing an -// end-of-sequence operator. The prolog and epilog symbols are passed +// end-of-sequence operator. The prologue and epilog symbols are passed // in (having been created earlier); here we add content to them. func (d *dwctxt) writelines(unit *sym.CompilationUnit, lineProlog loader.Sym) []loader.Sym { is_stmt := uint8(1) // initially = recommended default_is_stmt = 1, tracks is_stmt toggles. @@ -1220,39 +1289,11 @@ func (d *dwctxt) writelines(unit *sym.CompilationUnit, lineProlog loader.Sym) [] lsu.AddUint8(0) // standard_opcode_lengths[8] lsu.AddUint8(1) // standard_opcode_lengths[9] lsu.AddUint8(0) // standard_opcode_lengths[10] - lsu.AddUint8(0) // include_directories (empty) - - // Copy over the file table. - fileNums := make(map[string]int) - for i, name := range unit.FileTable { - name := expandFile(name) - if len(name) == 0 { - // Can't have empty filenames, and having a unique - // filename is quite useful for debugging. - name = fmt.Sprintf("<missing>_%d", i) - } - fileNums[name] = i + 1 - d.AddString(lsDwsym, name) - lsu.AddUint8(0) - lsu.AddUint8(0) - lsu.AddUint8(0) - // We can't use something that may be dead-code - // eliminated from a binary here. proc.go contains - // main and the scheduler, so it's not going anywhere. - if i := strings.Index(name, "runtime/proc.go"); i >= 0 { - d.dwmu.Lock() - if gdbscript == "" { - k := strings.Index(name, "runtime/proc.go") - gdbscript = name[:k] + "runtime/runtime-gdb.py" - } - d.dwmu.Unlock() - } - } + // Call helper to emit dir and file sections. + d.writeDirFileTables(unit, lsu) - // 4 zeros: the string termination + 3 fields. - lsu.AddUint8(0) - // terminate file_names. + // capture length at end of file names. headerend = lsu.Size() unitlen := lsu.Size() - unitstart @@ -1421,7 +1462,7 @@ func (d *dwctxt) writeframes(fs loader.Sym) dwarfSecInfo { deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr)) } - for pcsp.Init(fpcsp); !pcsp.Done; pcsp.Next() { + for pcsp.Init(d.linkctxt.loader.Data(fpcsp)); !pcsp.Done; pcsp.Next() { nextpc := pcsp.NextPC // pciterinit goes up to the end of the function, diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go index 22948521f5..a66506d392 100644 --- a/src/cmd/link/internal/ld/dwarf_test.go +++ b/src/cmd/link/internal/ld/dwarf_test.go @@ -238,6 +238,10 @@ func TestSizes(t *testing.T) { if runtime.GOOS == "plan9" { t.Skip("skipping on plan9; no DWARF symbol table in executables") } + + // External linking may bring in C symbols with unknown size. Skip. + testenv.MustInternalLink(t) + t.Parallel() // DWARF sizes should never be -1. @@ -919,6 +923,7 @@ func TestAbstractOriginSanityIssue26237(t *testing.T) { func TestRuntimeTypeAttrInternal(t *testing.T) { testenv.MustHaveGoBuild(t) + testenv.MustInternalLink(t) if runtime.GOOS == "plan9" { t.Skip("skipping on plan9; no DWARF symbol table in executables") @@ -1018,6 +1023,9 @@ func main() { t.Fatalf("*main.X DIE had no runtime type attr. DIE: %v", dies[0]) } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + return // everything is PIE on ARM64, addresses are relocated + } if rtAttr.(uint64)+types.Addr != addr { t.Errorf("DWARF type offset was %#x+%#x, but test program said %#x", rtAttr.(uint64), types.Addr, addr) } @@ -1203,6 +1211,15 @@ func main() { } } + // When external linking, we put all symbols in the symbol table (so the + // external linker can find them). Skip the symbol table check. + // TODO: maybe there is some way to tell the external linker not to put + // those symbols in the executable's symbol table? Prefix the symbol name + // with "." or "L" to pretend it is a label? + if !testenv.CanInternalLink() { + return + } + syms, err := f.Symbols() if err != nil { t.Fatalf("error reading symbols: %v", err) diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 2862f65f9f..37b2dc640d 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -10,8 +10,10 @@ import ( "cmd/link/internal/loader" "cmd/link/internal/sym" "crypto/sha1" + "debug/elf" "encoding/binary" "encoding/hex" + "fmt" "path/filepath" "sort" "strings" @@ -74,255 +76,6 @@ type elfNote struct { nType uint32 } -const ( - EI_MAG0 = 0 - EI_MAG1 = 1 - EI_MAG2 = 2 - EI_MAG3 = 3 - EI_CLASS = 4 - EI_DATA = 5 - EI_VERSION = 6 - EI_OSABI = 7 - EI_ABIVERSION = 8 - OLD_EI_BRAND = 8 - EI_PAD = 9 - EI_NIDENT = 16 - ELFMAG0 = 0x7f - ELFMAG1 = 'E' - ELFMAG2 = 'L' - ELFMAG3 = 'F' - SELFMAG = 4 - EV_NONE = 0 - EV_CURRENT = 1 - ELFCLASSNONE = 0 - ELFCLASS32 = 1 - ELFCLASS64 = 2 - ELFDATANONE = 0 - ELFDATA2LSB = 1 - ELFDATA2MSB = 2 - ELFOSABI_NONE = 0 - ELFOSABI_HPUX = 1 - ELFOSABI_NETBSD = 2 - ELFOSABI_LINUX = 3 - ELFOSABI_HURD = 4 - ELFOSABI_86OPEN = 5 - ELFOSABI_SOLARIS = 6 - ELFOSABI_AIX = 7 - ELFOSABI_IRIX = 8 - ELFOSABI_FREEBSD = 9 - ELFOSABI_TRU64 = 10 - ELFOSABI_MODESTO = 11 - ELFOSABI_OPENBSD = 12 - ELFOSABI_OPENVMS = 13 - ELFOSABI_NSK = 14 - ELFOSABI_ARM = 97 - ELFOSABI_STANDALONE = 255 - ELFOSABI_SYSV = ELFOSABI_NONE - ELFOSABI_MONTEREY = ELFOSABI_AIX - ET_NONE = 0 - ET_REL = 1 - ET_EXEC = 2 - ET_DYN = 3 - ET_CORE = 4 - ET_LOOS = 0xfe00 - ET_HIOS = 0xfeff - ET_LOPROC = 0xff00 - ET_HIPROC = 0xffff - EM_NONE = 0 - EM_M32 = 1 - EM_SPARC = 2 - EM_386 = 3 - EM_68K = 4 - EM_88K = 5 - EM_860 = 7 - EM_MIPS = 8 - EM_S370 = 9 - EM_MIPS_RS3_LE = 10 - EM_PARISC = 15 - EM_VPP500 = 17 - EM_SPARC32PLUS = 18 - EM_960 = 19 - EM_PPC = 20 - EM_PPC64 = 21 - EM_S390 = 22 - EM_V800 = 36 - EM_FR20 = 37 - EM_RH32 = 38 - EM_RCE = 39 - EM_ARM = 40 - EM_SH = 42 - EM_SPARCV9 = 43 - EM_TRICORE = 44 - EM_ARC = 45 - EM_H8_300 = 46 - EM_H8_300H = 47 - EM_H8S = 48 - EM_H8_500 = 49 - EM_IA_64 = 50 - EM_MIPS_X = 51 - EM_COLDFIRE = 52 - EM_68HC12 = 53 - EM_MMA = 54 - EM_PCP = 55 - EM_NCPU = 56 - EM_NDR1 = 57 - EM_STARCORE = 58 - EM_ME16 = 59 - EM_ST100 = 60 - EM_TINYJ = 61 - EM_X86_64 = 62 - EM_AARCH64 = 183 - EM_486 = 6 - EM_MIPS_RS4_BE = 10 - EM_ALPHA_STD = 41 - EM_ALPHA = 0x9026 - EM_RISCV = 243 - SHN_UNDEF = 0 - SHN_LORESERVE = 0xff00 - SHN_LOPROC = 0xff00 - SHN_HIPROC = 0xff1f - SHN_LOOS = 0xff20 - SHN_HIOS = 0xff3f - SHN_ABS = 0xfff1 - SHN_COMMON = 0xfff2 - SHN_XINDEX = 0xffff - SHN_HIRESERVE = 0xffff - SHT_NULL = 0 - SHT_PROGBITS = 1 - SHT_SYMTAB = 2 - SHT_STRTAB = 3 - SHT_RELA = 4 - SHT_HASH = 5 - SHT_DYNAMIC = 6 - SHT_NOTE = 7 - SHT_NOBITS = 8 - SHT_REL = 9 - SHT_SHLIB = 10 - SHT_DYNSYM = 11 - SHT_INIT_ARRAY = 14 - SHT_FINI_ARRAY = 15 - SHT_PREINIT_ARRAY = 16 - SHT_GROUP = 17 - SHT_SYMTAB_SHNDX = 18 - SHT_LOOS = 0x60000000 - SHT_HIOS = 0x6fffffff - SHT_GNU_VERDEF = 0x6ffffffd - SHT_GNU_VERNEED = 0x6ffffffe - SHT_GNU_VERSYM = 0x6fffffff - SHT_LOPROC = 0x70000000 - SHT_ARM_ATTRIBUTES = 0x70000003 - SHT_HIPROC = 0x7fffffff - SHT_LOUSER = 0x80000000 - SHT_HIUSER = 0xffffffff - SHF_WRITE = 0x1 - SHF_ALLOC = 0x2 - SHF_EXECINSTR = 0x4 - SHF_MERGE = 0x10 - SHF_STRINGS = 0x20 - SHF_INFO_LINK = 0x40 - SHF_LINK_ORDER = 0x80 - SHF_OS_NONCONFORMING = 0x100 - SHF_GROUP = 0x200 - SHF_TLS = 0x400 - SHF_MASKOS = 0x0ff00000 - SHF_MASKPROC = 0xf0000000 - PT_NULL = 0 - PT_LOAD = 1 - PT_DYNAMIC = 2 - PT_INTERP = 3 - PT_NOTE = 4 - PT_SHLIB = 5 - PT_PHDR = 6 - PT_TLS = 7 - PT_LOOS = 0x60000000 - PT_HIOS = 0x6fffffff - PT_LOPROC = 0x70000000 - PT_HIPROC = 0x7fffffff - PT_GNU_STACK = 0x6474e551 - PT_GNU_RELRO = 0x6474e552 - PT_PAX_FLAGS = 0x65041580 - PT_SUNWSTACK = 0x6ffffffb - PF_X = 0x1 - PF_W = 0x2 - PF_R = 0x4 - PF_MASKOS = 0x0ff00000 - PF_MASKPROC = 0xf0000000 - DT_NULL = 0 - DT_NEEDED = 1 - DT_PLTRELSZ = 2 - DT_PLTGOT = 3 - DT_HASH = 4 - DT_STRTAB = 5 - DT_SYMTAB = 6 - DT_RELA = 7 - DT_RELASZ = 8 - DT_RELAENT = 9 - DT_STRSZ = 10 - DT_SYMENT = 11 - DT_INIT = 12 - DT_FINI = 13 - DT_SONAME = 14 - DT_RPATH = 15 - DT_SYMBOLIC = 16 - DT_REL = 17 - DT_RELSZ = 18 - DT_RELENT = 19 - DT_PLTREL = 20 - DT_DEBUG = 21 - DT_TEXTREL = 22 - DT_JMPREL = 23 - DT_BIND_NOW = 24 - DT_INIT_ARRAY = 25 - DT_FINI_ARRAY = 26 - DT_INIT_ARRAYSZ = 27 - DT_FINI_ARRAYSZ = 28 - DT_RUNPATH = 29 - DT_FLAGS = 30 - DT_ENCODING = 32 - DT_PREINIT_ARRAY = 32 - DT_PREINIT_ARRAYSZ = 33 - DT_LOOS = 0x6000000d - DT_HIOS = 0x6ffff000 - DT_LOPROC = 0x70000000 - DT_HIPROC = 0x7fffffff - DT_VERNEED = 0x6ffffffe - DT_VERNEEDNUM = 0x6fffffff - DT_VERSYM = 0x6ffffff0 - DT_PPC64_GLINK = DT_LOPROC + 0 - DT_PPC64_OPT = DT_LOPROC + 3 - DF_ORIGIN = 0x0001 - DF_SYMBOLIC = 0x0002 - DF_TEXTREL = 0x0004 - DF_BIND_NOW = 0x0008 - DF_STATIC_TLS = 0x0010 - NT_PRSTATUS = 1 - NT_FPREGSET = 2 - NT_PRPSINFO = 3 - STB_LOCAL = 0 - STB_GLOBAL = 1 - STB_WEAK = 2 - STB_LOOS = 10 - STB_HIOS = 12 - STB_LOPROC = 13 - STB_HIPROC = 15 - STT_NOTYPE = 0 - STT_OBJECT = 1 - STT_FUNC = 2 - STT_SECTION = 3 - STT_FILE = 4 - STT_COMMON = 5 - STT_TLS = 6 - STT_LOOS = 10 - STT_HIOS = 12 - STT_LOPROC = 13 - STT_HIPROC = 15 - STV_DEFAULT = 0x0 - STV_INTERNAL = 0x1 - STV_HIDDEN = 0x2 - STV_PROTECTED = 0x3 - STN_UNDEF = 0 -) - /* For accessing the fields of r_info. */ /* For constructing r_info from field values. */ @@ -347,53 +100,20 @@ const ( /* * ELF header. */ -type ElfEhdr struct { - ident [EI_NIDENT]uint8 - type_ uint16 - machine uint16 - version uint32 - entry uint64 - phoff uint64 - shoff uint64 - flags uint32 - ehsize uint16 - phentsize uint16 - phnum uint16 - shentsize uint16 - shnum uint16 - shstrndx uint16 -} +type ElfEhdr elf.Header64 /* * Section header. */ type ElfShdr struct { - name uint32 - type_ uint32 - flags uint64 - addr uint64 - off uint64 - size uint64 - link uint32 - info uint32 - addralign uint64 - entsize uint64 - shnum int + elf.Section64 + shnum elf.SectionIndex } /* * Program header. */ -type ElfPhdr struct { - type_ uint32 - flags uint32 - off uint64 - vaddr uint64 - paddr uint64 - filesz uint64 - memsz uint64 - align uint64 -} +type ElfPhdr elf.ProgHeader /* For accessing the fields of r_info. */ @@ -496,22 +216,25 @@ func Elfinit(ctxt *Link) { // 64-bit architectures case sys.PPC64, sys.S390X: if ctxt.Arch.ByteOrder == binary.BigEndian { - ehdr.flags = 1 /* Version 1 ABI */ + ehdr.Flags = 1 /* Version 1 ABI */ } else { - ehdr.flags = 2 /* Version 2 ABI */ + ehdr.Flags = 2 /* Version 2 ABI */ } fallthrough case sys.AMD64, sys.ARM64, sys.MIPS64, sys.RISCV64: if ctxt.Arch.Family == sys.MIPS64 { - ehdr.flags = 0x20000004 /* MIPS 3 CPIC */ + ehdr.Flags = 0x20000004 /* MIPS 3 CPIC */ + } + if ctxt.Arch.Family == sys.RISCV64 { + ehdr.Flags = 0x4 /* RISCV Float ABI Double */ } elf64 = true - ehdr.phoff = ELF64HDRSIZE /* Must be ELF64HDRSIZE: first PHdr must follow ELF header */ - ehdr.shoff = ELF64HDRSIZE /* Will move as we add PHeaders */ - ehdr.ehsize = ELF64HDRSIZE /* Must be ELF64HDRSIZE */ - ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */ - ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */ + ehdr.Phoff = ELF64HDRSIZE /* Must be ELF64HDRSIZE: first PHdr must follow ELF header */ + ehdr.Shoff = ELF64HDRSIZE /* Will move as we add PHeaders */ + ehdr.Ehsize = ELF64HDRSIZE /* Must be ELF64HDRSIZE */ + ehdr.Phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */ + ehdr.Shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */ // 32-bit architectures case sys.ARM, sys.MIPS: @@ -526,19 +249,19 @@ func Elfinit(ctxt *Link) { // produced by the host C compiler. parseArmAttributes in // ldelf.go reads that information and updates this field as // appropriate. - ehdr.flags = 0x5000002 // has entry point, Version5 EABI + ehdr.Flags = 0x5000002 // has entry point, Version5 EABI } } else if ctxt.Arch.Family == sys.MIPS { - ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/ + ehdr.Flags = 0x50001004 /* MIPS 32 CPIC O32*/ } fallthrough default: - ehdr.phoff = ELF32HDRSIZE + ehdr.Phoff = ELF32HDRSIZE /* Must be ELF32HDRSIZE: first PHdr must follow ELF header */ - ehdr.shoff = ELF32HDRSIZE /* Will move as we add PHeaders */ - ehdr.ehsize = ELF32HDRSIZE /* Must be ELF32HDRSIZE */ - ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */ - ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */ + ehdr.Shoff = ELF32HDRSIZE /* Will move as we add PHeaders */ + ehdr.Ehsize = ELF32HDRSIZE /* Must be ELF32HDRSIZE */ + ehdr.Phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */ + ehdr.Shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */ } } @@ -548,83 +271,83 @@ func Elfinit(ctxt *Link) { // but buggy ELF loaders like the one in some // versions of QEMU and UPX won't. func fixElfPhdr(e *ElfPhdr) { - frag := int(e.vaddr & (e.align - 1)) + frag := int(e.Vaddr & (e.Align - 1)) - e.off -= uint64(frag) - e.vaddr -= uint64(frag) - e.paddr -= uint64(frag) - e.filesz += uint64(frag) - e.memsz += uint64(frag) + e.Off -= uint64(frag) + e.Vaddr -= uint64(frag) + e.Paddr -= uint64(frag) + e.Filesz += uint64(frag) + e.Memsz += uint64(frag) } func elf64phdr(out *OutBuf, e *ElfPhdr) { - if e.type_ == PT_LOAD { + if e.Type == elf.PT_LOAD { fixElfPhdr(e) } - out.Write32(e.type_) - out.Write32(e.flags) - out.Write64(e.off) - out.Write64(e.vaddr) - out.Write64(e.paddr) - out.Write64(e.filesz) - out.Write64(e.memsz) - out.Write64(e.align) + out.Write32(uint32(e.Type)) + out.Write32(uint32(e.Flags)) + out.Write64(e.Off) + out.Write64(e.Vaddr) + out.Write64(e.Paddr) + out.Write64(e.Filesz) + out.Write64(e.Memsz) + out.Write64(e.Align) } func elf32phdr(out *OutBuf, e *ElfPhdr) { - if e.type_ == PT_LOAD { + if e.Type == elf.PT_LOAD { fixElfPhdr(e) } - out.Write32(e.type_) - out.Write32(uint32(e.off)) - out.Write32(uint32(e.vaddr)) - out.Write32(uint32(e.paddr)) - out.Write32(uint32(e.filesz)) - out.Write32(uint32(e.memsz)) - out.Write32(e.flags) - out.Write32(uint32(e.align)) + out.Write32(uint32(e.Type)) + out.Write32(uint32(e.Off)) + out.Write32(uint32(e.Vaddr)) + out.Write32(uint32(e.Paddr)) + out.Write32(uint32(e.Filesz)) + out.Write32(uint32(e.Memsz)) + out.Write32(uint32(e.Flags)) + out.Write32(uint32(e.Align)) } func elf64shdr(out *OutBuf, e *ElfShdr) { - out.Write32(e.name) - out.Write32(e.type_) - out.Write64(e.flags) - out.Write64(e.addr) - out.Write64(e.off) - out.Write64(e.size) - out.Write32(e.link) - out.Write32(e.info) - out.Write64(e.addralign) - out.Write64(e.entsize) + out.Write32(e.Name) + out.Write32(uint32(e.Type)) + out.Write64(uint64(e.Flags)) + out.Write64(e.Addr) + out.Write64(e.Off) + out.Write64(e.Size) + out.Write32(e.Link) + out.Write32(e.Info) + out.Write64(e.Addralign) + out.Write64(e.Entsize) } func elf32shdr(out *OutBuf, e *ElfShdr) { - out.Write32(e.name) - out.Write32(e.type_) - out.Write32(uint32(e.flags)) - out.Write32(uint32(e.addr)) - out.Write32(uint32(e.off)) - out.Write32(uint32(e.size)) - out.Write32(e.link) - out.Write32(e.info) - out.Write32(uint32(e.addralign)) - out.Write32(uint32(e.entsize)) + out.Write32(e.Name) + out.Write32(uint32(e.Type)) + out.Write32(uint32(e.Flags)) + out.Write32(uint32(e.Addr)) + out.Write32(uint32(e.Off)) + out.Write32(uint32(e.Size)) + out.Write32(e.Link) + out.Write32(e.Info) + out.Write32(uint32(e.Addralign)) + out.Write32(uint32(e.Entsize)) } func elfwriteshdrs(out *OutBuf) uint32 { if elf64 { - for i := 0; i < int(ehdr.shnum); i++ { + for i := 0; i < int(ehdr.Shnum); i++ { elf64shdr(out, shdr[i]) } - return uint32(ehdr.shnum) * ELF64SHDRSIZE + return uint32(ehdr.Shnum) * ELF64SHDRSIZE } - for i := 0; i < int(ehdr.shnum); i++ { + for i := 0; i < int(ehdr.Shnum); i++ { elf32shdr(out, shdr[i]) } - return uint32(ehdr.shnum) * ELF32SHDRSIZE + return uint32(ehdr.Shnum) * ELF32SHDRSIZE } func elfsetstring(ctxt *Link, s loader.Sym, str string, off int) { @@ -640,43 +363,43 @@ func elfsetstring(ctxt *Link, s loader.Sym, str string, off int) { func elfwritephdrs(out *OutBuf) uint32 { if elf64 { - for i := 0; i < int(ehdr.phnum); i++ { + for i := 0; i < int(ehdr.Phnum); i++ { elf64phdr(out, phdr[i]) } - return uint32(ehdr.phnum) * ELF64PHDRSIZE + return uint32(ehdr.Phnum) * ELF64PHDRSIZE } - for i := 0; i < int(ehdr.phnum); i++ { + for i := 0; i < int(ehdr.Phnum); i++ { elf32phdr(out, phdr[i]) } - return uint32(ehdr.phnum) * ELF32PHDRSIZE + return uint32(ehdr.Phnum) * ELF32PHDRSIZE } func newElfPhdr() *ElfPhdr { e := new(ElfPhdr) - if ehdr.phnum >= NSECT { + if ehdr.Phnum >= NSECT { Errorf(nil, "too many phdrs") } else { - phdr[ehdr.phnum] = e - ehdr.phnum++ + phdr[ehdr.Phnum] = e + ehdr.Phnum++ } if elf64 { - ehdr.shoff += ELF64PHDRSIZE + ehdr.Shoff += ELF64PHDRSIZE } else { - ehdr.shoff += ELF32PHDRSIZE + ehdr.Shoff += ELF32PHDRSIZE } return e } func newElfShdr(name int64) *ElfShdr { e := new(ElfShdr) - e.name = uint32(name) - e.shnum = int(ehdr.shnum) - if ehdr.shnum >= NSECT { + e.Name = uint32(name) + e.shnum = elf.SectionIndex(ehdr.Shnum) + if ehdr.Shnum >= NSECT { Errorf(nil, "too many shdrs") } else { - shdr[ehdr.shnum] = e - ehdr.shnum++ + shdr[ehdr.Shnum] = e + ehdr.Shnum++ } return e @@ -687,38 +410,38 @@ func getElfEhdr() *ElfEhdr { } func elf64writehdr(out *OutBuf) uint32 { - out.Write(ehdr.ident[:]) - out.Write16(ehdr.type_) - out.Write16(ehdr.machine) - out.Write32(ehdr.version) - out.Write64(ehdr.entry) - out.Write64(ehdr.phoff) - out.Write64(ehdr.shoff) - out.Write32(ehdr.flags) - out.Write16(ehdr.ehsize) - out.Write16(ehdr.phentsize) - out.Write16(ehdr.phnum) - out.Write16(ehdr.shentsize) - out.Write16(ehdr.shnum) - out.Write16(ehdr.shstrndx) + out.Write(ehdr.Ident[:]) + out.Write16(uint16(ehdr.Type)) + out.Write16(uint16(ehdr.Machine)) + out.Write32(uint32(ehdr.Version)) + out.Write64(ehdr.Entry) + out.Write64(ehdr.Phoff) + out.Write64(ehdr.Shoff) + out.Write32(ehdr.Flags) + out.Write16(ehdr.Ehsize) + out.Write16(ehdr.Phentsize) + out.Write16(ehdr.Phnum) + out.Write16(ehdr.Shentsize) + out.Write16(ehdr.Shnum) + out.Write16(ehdr.Shstrndx) return ELF64HDRSIZE } func elf32writehdr(out *OutBuf) uint32 { - out.Write(ehdr.ident[:]) - out.Write16(ehdr.type_) - out.Write16(ehdr.machine) - out.Write32(ehdr.version) - out.Write32(uint32(ehdr.entry)) - out.Write32(uint32(ehdr.phoff)) - out.Write32(uint32(ehdr.shoff)) - out.Write32(ehdr.flags) - out.Write16(ehdr.ehsize) - out.Write16(ehdr.phentsize) - out.Write16(ehdr.phnum) - out.Write16(ehdr.shentsize) - out.Write16(ehdr.shnum) - out.Write16(ehdr.shstrndx) + out.Write(ehdr.Ident[:]) + out.Write16(uint16(ehdr.Type)) + out.Write16(uint16(ehdr.Machine)) + out.Write32(uint32(ehdr.Version)) + out.Write32(uint32(ehdr.Entry)) + out.Write32(uint32(ehdr.Phoff)) + out.Write32(uint32(ehdr.Shoff)) + out.Write32(ehdr.Flags) + out.Write16(ehdr.Ehsize) + out.Write16(ehdr.Phentsize) + out.Write16(ehdr.Phnum) + out.Write16(ehdr.Shentsize) + out.Write16(ehdr.Shnum) + out.Write16(ehdr.Shstrndx) return ELF32HDRSIZE } @@ -742,11 +465,11 @@ func elfhash(name string) uint32 { return h } -func elfWriteDynEntSym(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) { +func elfWriteDynEntSym(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym) { Elfwritedynentsymplus(ctxt, s, tag, t, 0) } -func Elfwritedynent(arch *sys.Arch, s *loader.SymbolBuilder, tag int, val uint64) { +func Elfwritedynent(arch *sys.Arch, s *loader.SymbolBuilder, tag elf.DynTag, val uint64) { if elf64 { s.AddUint64(arch, uint64(tag)) s.AddUint64(arch, val) @@ -756,11 +479,11 @@ func Elfwritedynent(arch *sys.Arch, s *loader.SymbolBuilder, tag int, val uint64 } } -func elfwritedynentsym(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) { +func elfwritedynentsym(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym) { Elfwritedynentsymplus(ctxt, s, tag, t, 0) } -func Elfwritedynentsymplus(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym, add int64) { +func Elfwritedynentsymplus(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym, add int64) { if elf64 { s.AddUint64(ctxt.Arch, uint64(tag)) } else { @@ -769,7 +492,7 @@ func Elfwritedynentsymplus(ctxt *Link, s *loader.SymbolBuilder, tag int, t loade s.AddAddrPlus(ctxt.Arch, t, add) } -func elfwritedynentsymsize(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) { +func elfwritedynentsymsize(ctxt *Link, s *loader.SymbolBuilder, tag elf.DynTag, t loader.Sym) { if elf64 { s.AddUint64(ctxt.Arch, uint64(tag)) } else { @@ -781,30 +504,30 @@ func elfwritedynentsymsize(ctxt *Link, s *loader.SymbolBuilder, tag int, t loade func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int { interp = p n := len(interp) + 1 - sh.addr = startva + resoff - uint64(n) - sh.off = resoff - uint64(n) - sh.size = uint64(n) + sh.Addr = startva + resoff - uint64(n) + sh.Off = resoff - uint64(n) + sh.Size = uint64(n) return n } func elfwriteinterp(out *OutBuf) int { sh := elfshname(".interp") - out.SeekSet(int64(sh.off)) + out.SeekSet(int64(sh.Off)) out.WriteString(interp) out.Write8(0) - return int(sh.size) + return int(sh.Size) } func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int { n := 3*4 + uint64(sz) + resoff%4 - sh.type_ = SHT_NOTE - sh.flags = SHF_ALLOC - sh.addralign = 4 - sh.addr = startva + resoff - n - sh.off = resoff - n - sh.size = n - resoff%4 + sh.Type = uint32(elf.SHT_NOTE) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Addralign = 4 + sh.Addr = startva + resoff - n + sh.Off = resoff - n + sh.Size = n - resoff%4 return int(n) } @@ -813,7 +536,7 @@ func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag sh := elfshname(str) // Write Elf_Note header. - out.SeekSet(int64(sh.off)) + out.SeekSet(int64(sh.Off)) out.Write32(namesz) out.Write32(descsz) @@ -850,7 +573,7 @@ func elfwritenetbsdsig(out *OutBuf) int { out.Write8(0) out.Write32(ELF_NOTE_NETBSD_VERSION) - return int(sh.size) + return int(sh.Size) } // The race detector can't handle ASLR (address space layout randomization). @@ -869,7 +592,7 @@ func elfwritenetbsdpax(out *OutBuf) int { } out.Write([]byte("PaX\x00")) out.Write32(0x20) // 0x20 = Force disable ASLR - return int(sh.size) + return int(sh.Size) } // OpenBSD Signature @@ -900,7 +623,7 @@ func elfwriteopenbsdsig(out *OutBuf) int { out.Write32(ELF_NOTE_OPENBSD_VERSION) - return int(sh.size) + return int(sh.Size) } func addbuildinfo(val string) { @@ -959,7 +682,7 @@ func elfwritebuildinfo(out *OutBuf) int { var zero = make([]byte, 4) out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))]) - return int(sh.size) + return int(sh.Size) } func elfwritegobuildid(out *OutBuf) int { @@ -973,7 +696,7 @@ func elfwritegobuildid(out *OutBuf) int { var zero = make([]byte, 4) out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))]) - return int(sh.size) + return int(sh.Size) } // Go specific notes @@ -1144,56 +867,56 @@ func elfdynhash(ctxt *Link) { s = ldr.CreateSymForUpdate(".dynamic", 0) elfverneed = nfile if elfverneed != 0 { - elfWriteDynEntSym(ctxt, s, DT_VERNEED, gnuVersionR.Sym()) - Elfwritedynent(ctxt.Arch, s, DT_VERNEEDNUM, uint64(nfile)) - elfWriteDynEntSym(ctxt, s, DT_VERSYM, gnuVersion.Sym()) + elfWriteDynEntSym(ctxt, s, elf.DT_VERNEED, gnuVersionR.Sym()) + Elfwritedynent(ctxt.Arch, s, elf.DT_VERNEEDNUM, uint64(nfile)) + elfWriteDynEntSym(ctxt, s, elf.DT_VERSYM, gnuVersion.Sym()) } sy := ldr.CreateSymForUpdate(elfRelType+".plt", 0) if sy.Size() > 0 { if elfRelType == ".rela" { - Elfwritedynent(ctxt.Arch, s, DT_PLTREL, DT_RELA) + Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_RELA)) } else { - Elfwritedynent(ctxt.Arch, s, DT_PLTREL, DT_REL) + Elfwritedynent(ctxt.Arch, s, elf.DT_PLTREL, uint64(elf.DT_REL)) } - elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy.Sym()) - elfWriteDynEntSym(ctxt, s, DT_JMPREL, sy.Sym()) + elfwritedynentsymsize(ctxt, s, elf.DT_PLTRELSZ, sy.Sym()) + elfWriteDynEntSym(ctxt, s, elf.DT_JMPREL, sy.Sym()) } - Elfwritedynent(ctxt.Arch, s, DT_NULL, 0) + Elfwritedynent(ctxt.Arch, s, elf.DT_NULL, 0) } func elfphload(seg *sym.Segment) *ElfPhdr { ph := newElfPhdr() - ph.type_ = PT_LOAD + ph.Type = elf.PT_LOAD if seg.Rwx&4 != 0 { - ph.flags |= PF_R + ph.Flags |= elf.PF_R } if seg.Rwx&2 != 0 { - ph.flags |= PF_W + ph.Flags |= elf.PF_W } if seg.Rwx&1 != 0 { - ph.flags |= PF_X + ph.Flags |= elf.PF_X } - ph.vaddr = seg.Vaddr - ph.paddr = seg.Vaddr - ph.memsz = seg.Length - ph.off = seg.Fileoff - ph.filesz = seg.Filelen - ph.align = uint64(*FlagRound) + ph.Vaddr = seg.Vaddr + ph.Paddr = seg.Vaddr + ph.Memsz = seg.Length + ph.Off = seg.Fileoff + ph.Filesz = seg.Filelen + ph.Align = uint64(*FlagRound) return ph } func elfphrelro(seg *sym.Segment) { ph := newElfPhdr() - ph.type_ = PT_GNU_RELRO - ph.vaddr = seg.Vaddr - ph.paddr = seg.Vaddr - ph.memsz = seg.Length - ph.off = seg.Fileoff - ph.filesz = seg.Filelen - ph.align = uint64(*FlagRound) + ph.Type = elf.PT_GNU_RELRO + ph.Vaddr = seg.Vaddr + ph.Paddr = seg.Vaddr + ph.Memsz = seg.Length + ph.Off = seg.Fileoff + ph.Filesz = seg.Filelen + ph.Align = uint64(*FlagRound) } func elfshname(name string) *ElfShdr { @@ -1202,9 +925,9 @@ func elfshname(name string) *ElfShdr { continue } off := elfstr[i].off - for i = 0; i < int(ehdr.shnum); i++ { + for i = 0; i < int(ehdr.Shnum); i++ { sh := shdr[i] - if sh.name == uint32(off) { + if sh.Name == uint32(off) { return sh } } @@ -1249,7 +972,7 @@ func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr { // If this section has already been set up as a note, we assume type_ and // flags are already correct, but the other fields still need filling in. - if sh.type_ == SHT_NOTE { + if sh.Type == uint32(elf.SHT_NOTE) { if linkmode != LinkExternal { // TODO(mwhudson): the approach here will work OK when // linking internally for notes that we want to be included @@ -1258,44 +981,44 @@ func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr { // list note). The real fix is probably to define new values // for Symbol.Type corresponding to mapped and unmapped notes // and handle them in dodata(). - Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally") + Errorf(nil, "sh.Type == SHT_NOTE in elfshbits when linking internally") } - sh.addralign = uint64(sect.Align) - sh.size = sect.Length - sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr + sh.Addralign = uint64(sect.Align) + sh.Size = sect.Length + sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr return sh } - if sh.type_ > 0 { + if sh.Type > 0 { return sh } if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen { - sh.type_ = SHT_PROGBITS + sh.Type = uint32(elf.SHT_PROGBITS) } else { - sh.type_ = SHT_NOBITS + sh.Type = uint32(elf.SHT_NOBITS) } - sh.flags = SHF_ALLOC + sh.Flags = uint64(elf.SHF_ALLOC) if sect.Rwx&1 != 0 { - sh.flags |= SHF_EXECINSTR + sh.Flags |= uint64(elf.SHF_EXECINSTR) } if sect.Rwx&2 != 0 { - sh.flags |= SHF_WRITE + sh.Flags |= uint64(elf.SHF_WRITE) } if sect.Name == ".tbss" { - sh.flags |= SHF_TLS - sh.type_ = SHT_NOBITS + sh.Flags |= uint64(elf.SHF_TLS) + sh.Type = uint32(elf.SHT_NOBITS) } if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") { - sh.flags = 0 + sh.Flags = 0 } if linkmode != LinkExternal { - sh.addr = sect.Vaddr + sh.Addr = sect.Vaddr } - sh.addralign = uint64(sect.Align) - sh.size = sect.Length + sh.Addralign = uint64(sect.Align) + sh.Size = sect.Length if sect.Name != ".tbss" { - sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr + sh.Off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr } return sh @@ -1310,13 +1033,13 @@ func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr { if sect.Name == ".shstrtab" || sect.Name == ".tbss" { return nil } - if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE { + if sect.Elfsect.(*ElfShdr).Type == uint32(elf.SHT_NOTE) { return nil } - typ := SHT_REL + typ := elf.SHT_REL if elfRelType == ".rela" { - typ = SHT_RELA + typ = elf.SHT_RELA } sh := elfshname(elfRelType + sect.Name) @@ -1324,21 +1047,21 @@ func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr { // its own .rela.text. if sect.Name == ".text" { - if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) { + if sh.Info != 0 && sh.Info != uint32(sect.Elfsect.(*ElfShdr).shnum) { sh = elfshnamedup(elfRelType + sect.Name) } } - sh.type_ = uint32(typ) - sh.entsize = uint64(arch.RegSize) * 2 - if typ == SHT_RELA { - sh.entsize += uint64(arch.RegSize) + sh.Type = uint32(typ) + sh.Entsize = uint64(arch.RegSize) * 2 + if typ == elf.SHT_RELA { + sh.Entsize += uint64(arch.RegSize) } - sh.link = uint32(elfshname(".symtab").shnum) - sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum) - sh.off = sect.Reloff - sh.size = sect.Rellen - sh.addralign = uint64(arch.RegSize) + sh.Link = uint32(elfshname(".symtab").shnum) + sh.Info = uint32(sect.Elfsect.(*ElfShdr).shnum) + sh.Off = sect.Reloff + sh.Size = sect.Rellen + sh.Addralign = uint64(arch.RegSize) return sh } @@ -1400,7 +1123,7 @@ func elfrelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) // sanity check if uint64(out.Offset()) != sect.Reloff+sect.Rellen { - panic("elfrelocsect: size mismatch") + panic(fmt.Sprintf("elfrelocsect: size mismatch %d != %d + %d", out.Offset(), sect.Reloff, sect.Rellen)) } } @@ -1651,47 +1374,47 @@ func (ctxt *Link) doelf() { /* * .dynamic table */ - elfwritedynentsym(ctxt, dynamic, DT_HASH, hash.Sym()) + elfwritedynentsym(ctxt, dynamic, elf.DT_HASH, hash.Sym()) - elfwritedynentsym(ctxt, dynamic, DT_SYMTAB, dynsym.Sym()) + elfwritedynentsym(ctxt, dynamic, elf.DT_SYMTAB, dynsym.Sym()) if elf64 { - Elfwritedynent(ctxt.Arch, dynamic, DT_SYMENT, ELF64SYMSIZE) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF64SYMSIZE) } else { - Elfwritedynent(ctxt.Arch, dynamic, DT_SYMENT, ELF32SYMSIZE) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_SYMENT, ELF32SYMSIZE) } - elfwritedynentsym(ctxt, dynamic, DT_STRTAB, dynstr.Sym()) - elfwritedynentsymsize(ctxt, dynamic, DT_STRSZ, dynstr.Sym()) + elfwritedynentsym(ctxt, dynamic, elf.DT_STRTAB, dynstr.Sym()) + elfwritedynentsymsize(ctxt, dynamic, elf.DT_STRSZ, dynstr.Sym()) if elfRelType == ".rela" { rela := ldr.LookupOrCreateSym(".rela", 0) - elfwritedynentsym(ctxt, dynamic, DT_RELA, rela) - elfwritedynentsymsize(ctxt, dynamic, DT_RELASZ, rela) - Elfwritedynent(ctxt.Arch, dynamic, DT_RELAENT, ELF64RELASIZE) + elfwritedynentsym(ctxt, dynamic, elf.DT_RELA, rela) + elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELASZ, rela) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELAENT, ELF64RELASIZE) } else { rel := ldr.LookupOrCreateSym(".rel", 0) - elfwritedynentsym(ctxt, dynamic, DT_REL, rel) - elfwritedynentsymsize(ctxt, dynamic, DT_RELSZ, rel) - Elfwritedynent(ctxt.Arch, dynamic, DT_RELENT, ELF32RELSIZE) + elfwritedynentsym(ctxt, dynamic, elf.DT_REL, rel) + elfwritedynentsymsize(ctxt, dynamic, elf.DT_RELSZ, rel) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RELENT, ELF32RELSIZE) } if rpath.val != "" { - Elfwritedynent(ctxt.Arch, dynamic, DT_RUNPATH, uint64(dynstr.Addstring(rpath.val))) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_RUNPATH, uint64(dynstr.Addstring(rpath.val))) } if ctxt.IsPPC64() { - elfwritedynentsym(ctxt, dynamic, DT_PLTGOT, plt.Sym()) + elfwritedynentsym(ctxt, dynamic, elf.DT_PLTGOT, plt.Sym()) } else { - elfwritedynentsym(ctxt, dynamic, DT_PLTGOT, gotplt.Sym()) + elfwritedynentsym(ctxt, dynamic, elf.DT_PLTGOT, gotplt.Sym()) } if ctxt.IsPPC64() { - Elfwritedynent(ctxt.Arch, dynamic, DT_PPC64_OPT, 0) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_PPC64_OPT, 0) } // Solaris dynamic linker can't handle an empty .rela.plt if - // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, - // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the + // DT_JMPREL is emitted so we have to defer generation of elf.DT_PLTREL, + // DT_PLTRELSZ, and elf.DT_JMPREL dynamic entries until after we know the // size of .rel(a).plt section. - Elfwritedynent(ctxt.Arch, dynamic, DT_DEBUG, 0) + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_DEBUG, 0) } if ctxt.IsShared() { @@ -1730,20 +1453,20 @@ func shsym(sh *ElfShdr, ldr *loader.Loader, s loader.Sym) { panic("bad symbol in shsym2") } addr := ldr.SymValue(s) - if sh.flags&SHF_ALLOC != 0 { - sh.addr = uint64(addr) + if sh.Flags&uint64(elf.SHF_ALLOC) != 0 { + sh.Addr = uint64(addr) } - sh.off = uint64(datoff(ldr, s, addr)) - sh.size = uint64(ldr.SymSize(s)) + sh.Off = uint64(datoff(ldr, s, addr)) + sh.Size = uint64(ldr.SymSize(s)) } func phsh(ph *ElfPhdr, sh *ElfShdr) { - ph.vaddr = sh.addr - ph.paddr = ph.vaddr - ph.off = sh.off - ph.filesz = sh.size - ph.memsz = sh.size - ph.align = sh.addralign + ph.Vaddr = sh.Addr + ph.Paddr = ph.Vaddr + ph.Off = sh.Off + ph.Filesz = sh.Size + ph.Memsz = sh.Size + ph.Align = sh.Addralign } func Asmbelfsetup() { @@ -1795,21 +1518,21 @@ func asmbElf(ctxt *Link) { default: Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family) case sys.MIPS, sys.MIPS64: - eh.machine = EM_MIPS + eh.Machine = uint16(elf.EM_MIPS) case sys.ARM: - eh.machine = EM_ARM + eh.Machine = uint16(elf.EM_ARM) case sys.AMD64: - eh.machine = EM_X86_64 + eh.Machine = uint16(elf.EM_X86_64) case sys.ARM64: - eh.machine = EM_AARCH64 + eh.Machine = uint16(elf.EM_AARCH64) case sys.I386: - eh.machine = EM_386 + eh.Machine = uint16(elf.EM_386) case sys.PPC64: - eh.machine = EM_PPC64 + eh.Machine = uint16(elf.EM_PPC64) case sys.RISCV64: - eh.machine = EM_RISCV + eh.Machine = uint16(elf.EM_RISCV) case sys.S390X: - eh.machine = EM_S390 + eh.Machine = uint16(elf.EM_S390) } elfreserve := int64(ELFRESERVE) @@ -1839,30 +1562,30 @@ func asmbElf(ctxt *Link) { sh := elfshname(".note.netbsd.pax") resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff))) pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R + pnote.Type = elf.PT_NOTE + pnote.Flags = elf.PF_R phsh(pnote, sh) } if ctxt.LinkMode == LinkExternal { /* skip program headers */ - eh.phoff = 0 + eh.Phoff = 0 - eh.phentsize = 0 + eh.Phentsize = 0 if ctxt.BuildMode == BuildModeShared { sh := elfshname(".note.go.pkg-list") - sh.type_ = SHT_NOTE + sh.Type = uint32(elf.SHT_NOTE) sh = elfshname(".note.go.abihash") - sh.type_ = SHT_NOTE - sh.flags = SHF_ALLOC + sh.Type = uint32(elf.SHT_NOTE) + sh.Flags = uint64(elf.SHF_ALLOC) sh = elfshname(".note.go.deps") - sh.type_ = SHT_NOTE + sh.Type = uint32(elf.SHT_NOTE) } if *flagBuildid != "" { sh := elfshname(".note.go.buildid") - sh.type_ = SHT_NOTE - sh.flags = SHF_ALLOC + sh.Type = uint32(elf.SHT_NOTE) + sh.Flags = uint64(elf.SHF_ALLOC) } goto elfobj @@ -1871,22 +1594,22 @@ func asmbElf(ctxt *Link) { /* program header info */ pph = newElfPhdr() - pph.type_ = PT_PHDR - pph.flags = PF_R - pph.off = uint64(eh.ehsize) - pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off - pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off - pph.align = uint64(*FlagRound) + pph.Type = elf.PT_PHDR + pph.Flags = elf.PF_R + pph.Off = uint64(eh.Ehsize) + pph.Vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off + pph.Paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.Off + pph.Align = uint64(*FlagRound) /* * PHDR must be in a loaded segment. Adjust the text * segment boundaries downwards to include it. */ { - o := int64(Segtext.Vaddr - pph.vaddr) + o := int64(Segtext.Vaddr - pph.Vaddr) Segtext.Vaddr -= uint64(o) Segtext.Length += uint64(o) - o = int64(Segtext.Fileoff - pph.off) + o = int64(Segtext.Fileoff - pph.Off) Segtext.Fileoff -= uint64(o) Segtext.Filelen += uint64(o) } @@ -1895,9 +1618,9 @@ func asmbElf(ctxt *Link) { /* interpreter */ sh := elfshname(".interp") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC - sh.addralign = 1 + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Addralign = 1 if interpreter == "" && objabi.GO_LDSO != "" { interpreter = objabi.GO_LDSO @@ -1935,8 +1658,8 @@ func asmbElf(ctxt *Link) { resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter)) ph := newElfPhdr() - ph.type_ = PT_INTERP - ph.flags = PF_R + ph.Type = elf.PT_INTERP + ph.Flags = elf.PF_R phsh(ph, sh) } @@ -1954,8 +1677,8 @@ func asmbElf(ctxt *Link) { } pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R + pnote.Type = elf.PT_NOTE + pnote.Flags = elf.PF_R phsh(pnote, sh) } @@ -1965,8 +1688,8 @@ func asmbElf(ctxt *Link) { if pnote == nil { pnote = newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R + pnote.Type = elf.PT_NOTE + pnote.Flags = elf.PF_R } phsh(pnote, sh) @@ -1977,8 +1700,8 @@ func asmbElf(ctxt *Link) { resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff))) pnote := newElfPhdr() - pnote.type_ = PT_NOTE - pnote.flags = PF_R + pnote.Type = elf.PT_NOTE + pnote.Flags = elf.PF_R phsh(pnote, sh) } @@ -1997,15 +1720,15 @@ func asmbElf(ctxt *Link) { /* Dynamic linking sections */ if !*FlagD { sh := elfshname(".dynsym") - sh.type_ = SHT_DYNSYM - sh.flags = SHF_ALLOC + sh.Type = uint32(elf.SHT_DYNSYM) + sh.Flags = uint64(elf.SHF_ALLOC) if elf64 { - sh.entsize = ELF64SYMSIZE + sh.Entsize = ELF64SYMSIZE } else { - sh.entsize = ELF32SYMSIZE + sh.Entsize = ELF32SYMSIZE } - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynstr").shnum) + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Link = uint32(elfshname(".dynstr").shnum) // sh.info is the index of first non-local symbol (number of local symbols) s := ldr.Lookup(".dynsym", 0) @@ -2016,134 +1739,134 @@ func asmbElf(ctxt *Link) { break } } - sh.info = i + sh.Info = i shsym(sh, ldr, s) sh = elfshname(".dynstr") - sh.type_ = SHT_STRTAB - sh.flags = SHF_ALLOC - sh.addralign = 1 + sh.Type = uint32(elf.SHT_STRTAB) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Addralign = 1 shsym(sh, ldr, ldr.Lookup(".dynstr", 0)) if elfverneed != 0 { sh := elfshname(".gnu.version") - sh.type_ = SHT_GNU_VERSYM - sh.flags = SHF_ALLOC - sh.addralign = 2 - sh.link = uint32(elfshname(".dynsym").shnum) - sh.entsize = 2 + sh.Type = uint32(elf.SHT_GNU_VERSYM) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Addralign = 2 + sh.Link = uint32(elfshname(".dynsym").shnum) + sh.Entsize = 2 shsym(sh, ldr, ldr.Lookup(".gnu.version", 0)) sh = elfshname(".gnu.version_r") - sh.type_ = SHT_GNU_VERNEED - sh.flags = SHF_ALLOC - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.info = uint32(elfverneed) - sh.link = uint32(elfshname(".dynstr").shnum) + sh.Type = uint32(elf.SHT_GNU_VERNEED) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Info = uint32(elfverneed) + sh.Link = uint32(elfshname(".dynstr").shnum) shsym(sh, ldr, ldr.Lookup(".gnu.version_r", 0)) } if elfRelType == ".rela" { sh := elfshname(".rela.plt") - sh.type_ = SHT_RELA - sh.flags = SHF_ALLOC - sh.entsize = ELF64RELASIZE - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynsym").shnum) - sh.info = uint32(elfshname(".plt").shnum) + sh.Type = uint32(elf.SHT_RELA) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Entsize = ELF64RELASIZE + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Link = uint32(elfshname(".dynsym").shnum) + sh.Info = uint32(elfshname(".plt").shnum) shsym(sh, ldr, ldr.Lookup(".rela.plt", 0)) sh = elfshname(".rela") - sh.type_ = SHT_RELA - sh.flags = SHF_ALLOC - sh.entsize = ELF64RELASIZE - sh.addralign = 8 - sh.link = uint32(elfshname(".dynsym").shnum) + sh.Type = uint32(elf.SHT_RELA) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Entsize = ELF64RELASIZE + sh.Addralign = 8 + sh.Link = uint32(elfshname(".dynsym").shnum) shsym(sh, ldr, ldr.Lookup(".rela", 0)) } else { sh := elfshname(".rel.plt") - sh.type_ = SHT_REL - sh.flags = SHF_ALLOC - sh.entsize = ELF32RELSIZE - sh.addralign = 4 - sh.link = uint32(elfshname(".dynsym").shnum) + sh.Type = uint32(elf.SHT_REL) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Entsize = ELF32RELSIZE + sh.Addralign = 4 + sh.Link = uint32(elfshname(".dynsym").shnum) shsym(sh, ldr, ldr.Lookup(".rel.plt", 0)) sh = elfshname(".rel") - sh.type_ = SHT_REL - sh.flags = SHF_ALLOC - sh.entsize = ELF32RELSIZE - sh.addralign = 4 - sh.link = uint32(elfshname(".dynsym").shnum) + sh.Type = uint32(elf.SHT_REL) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Entsize = ELF32RELSIZE + sh.Addralign = 4 + sh.Link = uint32(elfshname(".dynsym").shnum) shsym(sh, ldr, ldr.Lookup(".rel", 0)) } - if eh.machine == EM_PPC64 { + if elf.Machine(eh.Machine) == elf.EM_PPC64 { sh := elfshname(".glink") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_EXECINSTR - sh.addralign = 4 + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR) + sh.Addralign = 4 shsym(sh, ldr, ldr.Lookup(".glink", 0)) } sh = elfshname(".plt") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_EXECINSTR - if eh.machine == EM_X86_64 { - sh.entsize = 16 - } else if eh.machine == EM_S390 { - sh.entsize = 32 - } else if eh.machine == EM_PPC64 { + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR) + if elf.Machine(eh.Machine) == elf.EM_X86_64 { + sh.Entsize = 16 + } else if elf.Machine(eh.Machine) == elf.EM_S390 { + sh.Entsize = 32 + } else if elf.Machine(eh.Machine) == elf.EM_PPC64 { // On ppc64, this is just a table of addresses // filled by the dynamic linker - sh.type_ = SHT_NOBITS + sh.Type = uint32(elf.SHT_NOBITS) - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = 8 + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE) + sh.Entsize = 8 } else { - sh.entsize = 4 + sh.Entsize = 4 } - sh.addralign = sh.entsize + sh.Addralign = sh.Entsize shsym(sh, ldr, ldr.Lookup(".plt", 0)) // On ppc64, .got comes from the input files, so don't // create it here, and .got.plt is not used. - if eh.machine != EM_PPC64 { + if elf.Machine(eh.Machine) != elf.EM_PPC64 { sh := elfshname(".got") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE) + sh.Entsize = uint64(ctxt.Arch.RegSize) + sh.Addralign = uint64(ctxt.Arch.RegSize) shsym(sh, ldr, ldr.Lookup(".got", 0)) sh = elfshname(".got.plt") - sh.type_ = SHT_PROGBITS - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE) + sh.Entsize = uint64(ctxt.Arch.RegSize) + sh.Addralign = uint64(ctxt.Arch.RegSize) shsym(sh, ldr, ldr.Lookup(".got.plt", 0)) } sh = elfshname(".hash") - sh.type_ = SHT_HASH - sh.flags = SHF_ALLOC - sh.entsize = 4 - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynsym").shnum) + sh.Type = uint32(elf.SHT_HASH) + sh.Flags = uint64(elf.SHF_ALLOC) + sh.Entsize = 4 + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Link = uint32(elfshname(".dynsym").shnum) shsym(sh, ldr, ldr.Lookup(".hash", 0)) - /* sh and PT_DYNAMIC for .dynamic section */ + /* sh and elf.PT_DYNAMIC for .dynamic section */ sh = elfshname(".dynamic") - sh.type_ = SHT_DYNAMIC - sh.flags = SHF_ALLOC + SHF_WRITE - sh.entsize = 2 * uint64(ctxt.Arch.RegSize) - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".dynstr").shnum) + sh.Type = uint32(elf.SHT_DYNAMIC) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_WRITE) + sh.Entsize = 2 * uint64(ctxt.Arch.RegSize) + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Link = uint32(elfshname(".dynstr").shnum) shsym(sh, ldr, ldr.Lookup(".dynamic", 0)) ph := newElfPhdr() - ph.type_ = PT_DYNAMIC - ph.flags = PF_R + PF_W + ph.Type = elf.PT_DYNAMIC + ph.Flags = elf.PF_R + elf.PF_W phsh(ph, sh) /* @@ -2157,35 +1880,35 @@ func asmbElf(ctxt *Link) { } if tlssize != 0 { ph := newElfPhdr() - ph.type_ = PT_TLS - ph.flags = PF_R - ph.memsz = tlssize - ph.align = uint64(ctxt.Arch.RegSize) + ph.Type = elf.PT_TLS + ph.Flags = elf.PF_R + ph.Memsz = tlssize + ph.Align = uint64(ctxt.Arch.RegSize) } } if ctxt.HeadType == objabi.Hlinux { ph := newElfPhdr() - ph.type_ = PT_GNU_STACK - ph.flags = PF_W + PF_R - ph.align = uint64(ctxt.Arch.RegSize) + ph.Type = elf.PT_GNU_STACK + ph.Flags = elf.PF_W + elf.PF_R + ph.Align = uint64(ctxt.Arch.RegSize) ph = newElfPhdr() - ph.type_ = PT_PAX_FLAGS - ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled - ph.align = uint64(ctxt.Arch.RegSize) + ph.Type = elf.PT_PAX_FLAGS + ph.Flags = 0x2a00 // mprotect, randexec, emutramp disabled + ph.Align = uint64(ctxt.Arch.RegSize) } else if ctxt.HeadType == objabi.Hsolaris { ph := newElfPhdr() - ph.type_ = PT_SUNWSTACK - ph.flags = PF_W + PF_R + ph.Type = elf.PT_SUNWSTACK + ph.Flags = elf.PF_W + elf.PF_R } elfobj: sh := elfshname(".shstrtab") - sh.type_ = SHT_STRTAB - sh.addralign = 1 + sh.Type = uint32(elf.SHT_STRTAB) + sh.Addralign = 1 shsym(sh, ldr, ldr.Lookup(".shstrtab", 0)) - eh.shstrndx = uint16(sh.shnum) + eh.Shstrndx = uint16(sh.shnum) // put these sections early in the list if !*FlagS { @@ -2229,72 +1952,73 @@ elfobj: // add a .note.GNU-stack section to mark the stack as non-executable sh := elfshname(".note.GNU-stack") - sh.type_ = SHT_PROGBITS - sh.addralign = 1 - sh.flags = 0 + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Addralign = 1 + sh.Flags = 0 } if !*FlagS { sh := elfshname(".symtab") - sh.type_ = SHT_SYMTAB - sh.off = uint64(symo) - sh.size = uint64(symSize) - sh.addralign = uint64(ctxt.Arch.RegSize) - sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize) - sh.link = uint32(elfshname(".strtab").shnum) - sh.info = uint32(elfglobalsymndx) + sh.Type = uint32(elf.SHT_SYMTAB) + sh.Off = uint64(symo) + sh.Size = uint64(symSize) + sh.Addralign = uint64(ctxt.Arch.RegSize) + sh.Entsize = 8 + 2*uint64(ctxt.Arch.RegSize) + sh.Link = uint32(elfshname(".strtab").shnum) + sh.Info = uint32(elfglobalsymndx) sh = elfshname(".strtab") - sh.type_ = SHT_STRTAB - sh.off = uint64(symo) + uint64(symSize) - sh.size = uint64(len(Elfstrdat)) - sh.addralign = 1 + sh.Type = uint32(elf.SHT_STRTAB) + sh.Off = uint64(symo) + uint64(symSize) + sh.Size = uint64(len(Elfstrdat)) + sh.Addralign = 1 } /* Main header */ - eh.ident[EI_MAG0] = '\177' + copy(eh.Ident[:], elf.ELFMAG) - eh.ident[EI_MAG1] = 'E' - eh.ident[EI_MAG2] = 'L' - eh.ident[EI_MAG3] = 'F' - if ctxt.HeadType == objabi.Hfreebsd { - eh.ident[EI_OSABI] = ELFOSABI_FREEBSD - } else if ctxt.HeadType == objabi.Hnetbsd { - eh.ident[EI_OSABI] = ELFOSABI_NETBSD - } else if ctxt.HeadType == objabi.Hopenbsd { - eh.ident[EI_OSABI] = ELFOSABI_OPENBSD - } else if ctxt.HeadType == objabi.Hdragonfly { - eh.ident[EI_OSABI] = ELFOSABI_NONE + var osabi elf.OSABI + switch ctxt.HeadType { + case objabi.Hfreebsd: + osabi = elf.ELFOSABI_FREEBSD + case objabi.Hnetbsd: + osabi = elf.ELFOSABI_NETBSD + case objabi.Hopenbsd: + osabi = elf.ELFOSABI_OPENBSD + case objabi.Hdragonfly: + osabi = elf.ELFOSABI_NONE } + eh.Ident[elf.EI_OSABI] = byte(osabi) + if elf64 { - eh.ident[EI_CLASS] = ELFCLASS64 + eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS64) } else { - eh.ident[EI_CLASS] = ELFCLASS32 + eh.Ident[elf.EI_CLASS] = byte(elf.ELFCLASS32) } if ctxt.Arch.ByteOrder == binary.BigEndian { - eh.ident[EI_DATA] = ELFDATA2MSB + eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2MSB) } else { - eh.ident[EI_DATA] = ELFDATA2LSB + eh.Ident[elf.EI_DATA] = byte(elf.ELFDATA2LSB) } - eh.ident[EI_VERSION] = EV_CURRENT + eh.Ident[elf.EI_VERSION] = byte(elf.EV_CURRENT) if ctxt.LinkMode == LinkExternal { - eh.type_ = ET_REL + eh.Type = uint16(elf.ET_REL) } else if ctxt.BuildMode == BuildModePIE { - eh.type_ = ET_DYN + eh.Type = uint16(elf.ET_DYN) } else { - eh.type_ = ET_EXEC + eh.Type = uint16(elf.ET_EXEC) } if ctxt.LinkMode != LinkExternal { - eh.entry = uint64(Entryvalue(ctxt)) + eh.Entry = uint64(Entryvalue(ctxt)) } - eh.version = EV_CURRENT + eh.Version = uint32(elf.EV_CURRENT) if pph != nil { - pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize) - pph.memsz = pph.filesz + pph.Filesz = uint64(eh.Phnum) * uint64(eh.Phentsize) + pph.Memsz = pph.Filesz } ctxt.Out.SeekSet(0) @@ -2344,21 +2068,21 @@ func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.S if elf64 { /* type */ - t := STB_GLOBAL << 4 + var t uint8 if cgoexp && st == sym.STEXT { - t |= STT_FUNC + t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC) } else { - t |= STT_OBJECT + t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT) } - d.AddUint8(uint8(t)) + d.AddUint8(t) /* reserved */ d.AddUint8(0) /* section where symbol is defined */ if st == sym.SDYNIMPORT { - d.AddUint16(target.Arch, SHN_UNDEF) + d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF)) } else { d.AddUint16(target.Arch, 1) } @@ -2377,7 +2101,7 @@ func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.S if target.Arch.Family == sys.AMD64 && !cgoeDynamic && dil != "" && !seenlib[dil] { du := ldr.MakeSymbolUpdater(syms.Dynamic) - Elfwritedynent(target.Arch, du, DT_NEEDED, uint64(dstru.Addstring(dil))) + Elfwritedynent(target.Arch, du, elf.DT_NEEDED, uint64(dstru.Addstring(dil))) seenlib[dil] = true } } else { @@ -2393,80 +2117,24 @@ func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.S d.AddUint32(target.Arch, uint32(len(ldr.Data(s)))) /* type */ - t := STB_GLOBAL << 4 + var t uint8 // TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386. if target.Arch.Family == sys.I386 && cgoexp && st == sym.STEXT { - t |= STT_FUNC + t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC) } else if target.Arch.Family == sys.ARM && cgoeDynamic && st == sym.STEXT { - t |= STT_FUNC + t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_FUNC) } else { - t |= STT_OBJECT + t = elf.ST_INFO(elf.STB_GLOBAL, elf.STT_OBJECT) } - d.AddUint8(uint8(t)) + d.AddUint8(t) d.AddUint8(0) /* shndx */ if st == sym.SDYNIMPORT { - d.AddUint16(target.Arch, SHN_UNDEF) + d.AddUint16(target.Arch, uint16(elf.SHN_UNDEF)) } else { d.AddUint16(target.Arch, 1) } } } - -func ELF32_R_SYM(info uint32) uint32 { - return info >> 8 -} - -func ELF32_R_TYPE(info uint32) uint32 { - return uint32(uint8(info)) -} - -func ELF32_R_INFO(sym uint32, type_ uint32) uint32 { - return sym<<8 | type_ -} - -func ELF32_ST_BIND(info uint8) uint8 { - return info >> 4 -} - -func ELF32_ST_TYPE(info uint8) uint8 { - return info & 0xf -} - -func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 { - return bind<<4 | type_&0xf -} - -func ELF32_ST_VISIBILITY(oth uint8) uint8 { - return oth & 3 -} - -func ELF64_R_SYM(info uint64) uint32 { - return uint32(info >> 32) -} - -func ELF64_R_TYPE(info uint64) uint32 { - return uint32(info) -} - -func ELF64_R_INFO(sym uint32, type_ uint32) uint64 { - return uint64(sym)<<32 | uint64(type_) -} - -func ELF64_ST_BIND(info uint8) uint8 { - return info >> 4 -} - -func ELF64_ST_TYPE(info uint8) uint8 { - return info & 0xf -} - -func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 { - return bind<<4 | type_&0xf -} - -func ELF64_ST_VISIBILITY(oth uint8) uint8 { - return oth & 3 -} diff --git a/src/cmd/link/internal/ld/elf_test.go b/src/cmd/link/internal/ld/elf_test.go index 37f0e77336..776fc1b4f9 100644 --- a/src/cmd/link/internal/ld/elf_test.go +++ b/src/cmd/link/internal/ld/elf_test.go @@ -14,6 +14,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strings" "testing" ) @@ -123,7 +124,7 @@ func TestNoDuplicateNeededEntries(t *testing.T) { var count int for _, lib := range libs { - if lib == "libc.so" { + if lib == "libc.so" || strings.HasPrefix(lib, "libc.so.") { count++ } } diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index b3541c46c0..fbc7a78d0e 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go @@ -13,10 +13,13 @@ import ( "cmd/internal/sys" "cmd/link/internal/loader" "cmd/link/internal/sym" + "debug/elf" "encoding/json" "fmt" "io" "os" + "sort" + "strconv" "strings" ) @@ -288,6 +291,62 @@ func setCgoAttr(ctxt *Link, lookup func(string, int) loader.Sym, file string, pk return } +// openbsdTrimLibVersion indicates whether a shared library is +// versioned and if it is, returns the unversioned name. The +// OpenBSD library naming scheme is lib<name>.so.<major>.<minor> +func openbsdTrimLibVersion(lib string) (string, bool) { + parts := strings.Split(lib, ".") + if len(parts) != 4 { + return "", false + } + if parts[1] != "so" { + return "", false + } + if _, err := strconv.Atoi(parts[2]); err != nil { + return "", false + } + if _, err := strconv.Atoi(parts[3]); err != nil { + return "", false + } + return fmt.Sprintf("%s.%s", parts[0], parts[1]), true +} + +// dedupLibrariesOpenBSD dedups a list of shared libraries, treating versioned +// and unversioned libraries as equivalents. Versioned libraries are preferred +// and retained over unversioned libraries. This avoids the situation where +// the use of cgo results in a DT_NEEDED for a versioned library (for example, +// libc.so.96.1), while a dynamic import specifies an unversioned library (for +// example, libc.so) - this would otherwise result in two DT_NEEDED entries +// for the same library, resulting in a failure when ld.so attempts to load +// the Go binary. +func dedupLibrariesOpenBSD(ctxt *Link, libs []string) []string { + libraries := make(map[string]string) + for _, lib := range libs { + if name, ok := openbsdTrimLibVersion(lib); ok { + // Record unversioned name as seen. + seenlib[name] = true + libraries[name] = lib + } else if _, ok := libraries[lib]; !ok { + libraries[lib] = lib + } + } + + libs = nil + for _, lib := range libraries { + libs = append(libs, lib) + } + sort.Strings(libs) + + return libs +} + +func dedupLibraries(ctxt *Link, libs []string) []string { + if ctxt.Target.IsOpenbsd() { + return dedupLibrariesOpenBSD(ctxt, libs) + } + return libs +} + var seenlib = make(map[string]bool) func adddynlib(ctxt *Link, lib string) { @@ -302,7 +361,7 @@ func adddynlib(ctxt *Link, lib string) { dsu.Addstring("") } du := ctxt.loader.MakeSymbolUpdater(ctxt.Dynamic) - Elfwritedynent(ctxt.Arch, du, DT_NEEDED, uint64(dsu.Addstring(lib))) + Elfwritedynent(ctxt.Arch, du, elf.DT_NEEDED, uint64(dsu.Addstring(lib))) } else { Errorf(nil, "adddynlib: unsupported binary format") } @@ -384,7 +443,7 @@ func (ctxt *Link) addexport() { for _, exp := range ctxt.dynexp { Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp) } - for _, lib := range dynlib { + for _, lib := range dedupLibraries(ctxt, dynlib) { adddynlib(ctxt, lib) } } diff --git a/src/cmd/link/internal/ld/go_test.go b/src/cmd/link/internal/ld/go_test.go new file mode 100644 index 0000000000..0197196023 --- /dev/null +++ b/src/cmd/link/internal/ld/go_test.go @@ -0,0 +1,121 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ld + +import ( + "cmd/internal/objabi" + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "reflect" + "runtime" + "testing" +) + +func TestDedupLibraries(t *testing.T) { + ctxt := &Link{} + ctxt.Target.HeadType = objabi.Hlinux + + libs := []string{"libc.so", "libc.so.6"} + + got := dedupLibraries(ctxt, libs) + if !reflect.DeepEqual(got, libs) { + t.Errorf("dedupLibraries(%v) = %v, want %v", libs, got, libs) + } +} + +func TestDedupLibrariesOpenBSD(t *testing.T) { + ctxt := &Link{} + ctxt.Target.HeadType = objabi.Hopenbsd + + tests := []struct { + libs []string + want []string + }{ + { + libs: []string{"libc.so"}, + want: []string{"libc.so"}, + }, + { + libs: []string{"libc.so", "libc.so.96.1"}, + want: []string{"libc.so.96.1"}, + }, + { + libs: []string{"libc.so.96.1", "libc.so"}, + want: []string{"libc.so.96.1"}, + }, + { + libs: []string{"libc.a", "libc.so.96.1"}, + want: []string{"libc.a", "libc.so.96.1"}, + }, + { + libs: []string{"libpthread.so", "libc.so"}, + want: []string{"libc.so", "libpthread.so"}, + }, + { + libs: []string{"libpthread.so.26.1", "libpthread.so", "libc.so.96.1", "libc.so"}, + want: []string{"libc.so.96.1", "libpthread.so.26.1"}, + }, + { + libs: []string{"libpthread.so.26.1", "libpthread.so", "libc.so.96.1", "libc.so", "libfoo.so"}, + want: []string{"libc.so.96.1", "libfoo.so", "libpthread.so.26.1"}, + }, + } + + for _, test := range tests { + t.Run("dedup", func(t *testing.T) { + got := dedupLibraries(ctxt, test.libs) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("dedupLibraries(%v) = %v, want %v", test.libs, got, test.want) + } + }) + } +} + +func TestDedupLibrariesOpenBSDLink(t *testing.T) { + // The behavior we're checking for is of interest only on OpenBSD. + if runtime.GOOS != "openbsd" { + t.Skip("test only useful on openbsd") + } + + testenv.MustHaveGoBuild(t) + testenv.MustHaveCGO(t) + t.Parallel() + + dir, err := ioutil.TempDir("", "dedup-build") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + // cgo_import_dynamic both the unversioned libraries and pull in the + // net package to get a cgo package with a versioned library. + srcFile := filepath.Join(dir, "x.go") + src := `package main + +import ( + _ "net" +) + +//go:cgo_import_dynamic _ _ "libc.so" + +func main() {}` + if err := ioutil.WriteFile(srcFile, []byte(src), 0644); err != nil { + t.Fatal(err) + } + + exe := filepath.Join(dir, "deduped.exe") + out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, srcFile).CombinedOutput() + if err != nil { + t.Fatalf("build failure: %s\n%s\n", err, string(out)) + } + + // Result should be runnable. + if _, err = exec.Command(exe).CombinedOutput(); err != nil { + t.Fatal(err) + } +} diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go index db339b484d..cdfaadb17d 100644 --- a/src/cmd/link/internal/ld/ld_test.go +++ b/src/cmd/link/internal/ld/ld_test.go @@ -5,6 +5,7 @@ package ld import ( + "debug/pe" "fmt" "internal/testenv" "io/ioutil" @@ -17,8 +18,13 @@ import ( ) func TestUndefinedRelocErrors(t *testing.T) { - t.Parallel() testenv.MustHaveGoBuild(t) + + // When external linking, symbols may be defined externally, so we allow + // undefined symbols and let external linker resolve. Skip the test. + testenv.MustInternalLink(t) + + t.Parallel() dir, err := ioutil.TempDir("", "go-build") if err != nil { t.Fatal(err) @@ -167,3 +173,72 @@ func TestPPC64LargeTextSectionSplitting(t *testing.T) { t.Fatal(err) } } + +func TestWindowsBuildmodeCSharedASLR(t *testing.T) { + platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) + switch platform { + case "windows/amd64", "windows/386": + default: + t.Skip("skipping windows amd64/386 only test") + } + + t.Run("aslr", func(t *testing.T) { + testWindowsBuildmodeCSharedASLR(t, true) + }) + t.Run("no-aslr", func(t *testing.T) { + testWindowsBuildmodeCSharedASLR(t, false) + }) +} + +func testWindowsBuildmodeCSharedASLR(t *testing.T, useASLR bool) { + t.Parallel() + testenv.MustHaveGoBuild(t) + + dir, err := ioutil.TempDir("", "go-build") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + srcfile := filepath.Join(dir, "test.go") + objfile := filepath.Join(dir, "test.dll") + if err := ioutil.WriteFile(srcfile, []byte(`package main; func main() { print("hello") }`), 0666); err != nil { + t.Fatal(err) + } + argv := []string{"build", "-buildmode=c-shared"} + if !useASLR { + argv = append(argv, "-ldflags", "-aslr=false") + } + argv = append(argv, "-o", objfile, srcfile) + out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput() + if err != nil { + t.Fatalf("build failure: %s\n%s\n", err, string(out)) + } + + f, err := pe.Open(objfile) + if err != nil { + t.Fatal(err) + } + defer f.Close() + var dc uint16 + switch oh := f.OptionalHeader.(type) { + case *pe.OptionalHeader32: + dc = oh.DllCharacteristics + case *pe.OptionalHeader64: + dc = oh.DllCharacteristics + hasHEVA := (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) != 0 + if useASLR && !hasHEVA { + t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set") + } else if !useASLR && hasHEVA { + t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag should not be set") + } + default: + t.Fatalf("unexpected optional header type of %T", f.OptionalHeader) + } + hasASLR := (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) != 0 + if useASLR && !hasASLR { + t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set") + } else if !useASLR && hasASLR { + t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag should not be set") + } +} diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 4295b2a660..e1cc7184de 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -247,12 +247,16 @@ type Arch struct { Elfreloc1 func(*Link, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int, int64) bool ElfrelocSize uint32 // size of an ELF relocation record, must match Elfreloc1. Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) - Gentext func(*Link, *loader.Loader) + Gentext func(*Link, *loader.Loader) // Generate text before addressing has been performed. Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool MachorelocSize uint32 // size of an Mach-O relocation record, must match Machoreloc1. PEreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool Xcoffreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool + // Generate additional symbols for the native symbol table just prior to + // code generation. + GenSymsLate func(*Link, *loader.Loader) + // TLSIEtoLE converts a TLS Initial Executable relocation to // a TLS Local Executable relocation. // @@ -294,6 +298,11 @@ func (ctxt *Link) CanUsePlugins() bool { return ctxt.canUsePlugins } +// NeedCodeSign reports whether we need to code-sign the output binary. +func (ctxt *Link) NeedCodeSign() bool { + return ctxt.IsDarwin() && ctxt.IsARM64() +} + var ( dynlib []string ldflag []string @@ -543,7 +552,7 @@ func (ctxt *Link) loadlib() { } // Add non-package symbols and references of externally defined symbols. - ctxt.loader.LoadNonpkgSyms(ctxt.Arch) + ctxt.loader.LoadSyms(ctxt.Arch) // Load symbols from shared libraries, after all Go object symbols are loaded. for _, lib := range ctxt.Library { @@ -831,7 +840,12 @@ func (ctxt *Link) mangleTypeSym() { ldr := ctxt.loader for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ { - if !ldr.AttrReachable(s) { + if !ldr.AttrReachable(s) && !ctxt.linkShared { + // If -linkshared, the GCProg generation code may need to reach + // out to the shared library for the type descriptor's data, even + // the type descriptor itself is not actually needed at run time + // (therefore not reachable). We still need to mangle its name, + // so it is consistent with the one stored in the shared library. continue } name := ldr.SymName(s) @@ -1249,7 +1263,9 @@ func (ctxt *Link) hostlink() { // -headerpad is incompatible with -fembed-bitcode. argv = append(argv, "-Wl,-headerpad,1144") } - if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) { + if ctxt.DynlinkingGo() && objabi.GOOS != "ios" { + // -flat_namespace is deprecated on iOS. + // It is useful for supporting plugins. We don't support plugins on iOS. argv = append(argv, "-Wl,-flat_namespace") } if !combineDwarf { @@ -1285,6 +1301,17 @@ func (ctxt *Link) hostlink() { argv = append(argv, "-Wl,-bbigtoc") } + // Enable ASLR on Windows. + addASLRargs := func(argv []string) []string { + // Enable ASLR. + argv = append(argv, "-Wl,--dynamicbase") + // enable high-entropy ASLR on 64-bit. + if ctxt.Arch.PtrSize >= 8 { + argv = append(argv, "-Wl,--high-entropy-va") + } + return argv + } + switch ctxt.BuildMode { case BuildModeExe: if ctxt.HeadType == objabi.Hdarwin { @@ -1297,15 +1324,7 @@ func (ctxt *Link) hostlink() { switch ctxt.HeadType { case objabi.Hdarwin, objabi.Haix: case objabi.Hwindows: - // Enable ASLR. - argv = append(argv, "-Wl,--dynamicbase") - // enable high-entropy ASLR on 64-bit. - if ctxt.Arch.PtrSize >= 8 { - argv = append(argv, "-Wl,--high-entropy-va") - } - // Work around binutils limitation that strips relocation table for dynamicbase. - // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011 - argv = append(argv, "-Wl,--export-all-symbols") + argv = addASLRargs(argv) default: // ELF. if ctxt.UseRelro() { @@ -1316,9 +1335,6 @@ func (ctxt *Link) hostlink() { case BuildModeCShared: if ctxt.HeadType == objabi.Hdarwin { argv = append(argv, "-dynamiclib") - if ctxt.Arch.Family != sys.AMD64 { - argv = append(argv, "-Wl,-read_only_relocs,suppress") - } } else { // ELF. argv = append(argv, "-Wl,-Bsymbolic") @@ -1326,7 +1342,11 @@ func (ctxt *Link) hostlink() { argv = append(argv, "-Wl,-z,relro") } argv = append(argv, "-shared") - if ctxt.HeadType != objabi.Hwindows { + if ctxt.HeadType == objabi.Hwindows { + if *flagAslr { + argv = addASLRargs(argv) + } + } else { // Pass -z nodelete to mark the shared library as // non-closeable: a dlclose will do nothing. argv = append(argv, "-Wl,-z,nodelete") @@ -1596,12 +1616,12 @@ func (ctxt *Link) hostlink() { if combineDwarf { dsym := filepath.Join(*flagTmpdir, "go.dwarf") - if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { + if out, err := exec.Command("xcrun", "dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) } // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil). // They contain temporary file paths and make the build not reproducible. - if out, err := exec.Command("strip", "-S", *flagOutfile).CombinedOutput(); err != nil { + if out, err := exec.Command("xcrun", "strip", "-S", *flagOutfile).CombinedOutput(); err != nil { Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out) } // Skip combining if `dsymutil` didn't generate a file. See #11994. @@ -1627,6 +1647,12 @@ func (ctxt *Link) hostlink() { Exitf("%s: %v", os.Args[0], err) } } + if ctxt.NeedCodeSign() { + err := machoCodeSign(ctxt, *flagOutfile) + if err != nil { + Exitf("%s: code signing failed: %v", os.Args[0], err) + } + } } var createTrivialCOnce sync.Once @@ -1752,12 +1778,12 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) if magic == 0x7f454c46 { // \x7F E L F ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { - textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.flags) + textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags) if err != nil { Errorf(nil, "%v", err) return } - ehdr.flags = flags + ehdr.Flags = flags ctxt.Textp = append(ctxt.Textp, textp...) } return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file) @@ -2254,7 +2280,7 @@ func (sc *stkChk) check(up *chain, depth int) int { var ch1 chain pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC)) ri := 0 - for pcsp.Init(info.Pcsp()); !pcsp.Done; pcsp.Next() { + for pcsp.Init(ldr.Data(info.Pcsp())); !pcsp.Done; pcsp.Next() { // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). // Check stack size in effect for this span. @@ -2502,16 +2528,22 @@ func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, if target.Arch.PtrSize == 8 { rela := ldr.MakeSymbolUpdater(syms.Rela) rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) - rela.AddUint64(target.Arch, ELF64_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) rela.AddUint64(target.Arch, 0) } else { rel := ldr.MakeSymbolUpdater(syms.Rel) rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) - rel.AddUint32(target.Arch, ELF32_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp)) } } else if target.IsDarwin() { leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT) leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s))) + if target.IsPIE() && target.IsInternal() { + // Mach-O relocations are a royal pain to lay out. + // They use a compact stateful bytecode representation. + // Here we record what are needed and encode them later. + MachoAddBind(int64(ldr.SymGot(s)), s) + } } else { ldr.Errorf(s, "addgotsym: unsupported binary format") } diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go index a2c8552e94..f26d051a49 100644 --- a/src/cmd/link/internal/ld/link.go +++ b/src/cmd/link/internal/ld/link.go @@ -71,7 +71,6 @@ type Link struct { LibraryByPkg map[string]*sym.Library Shlibs []Shlib Textp []loader.Sym - NumFilesyms int Moduledata loader.Sym PackageFile map[string]string diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index f6356729a6..4605644767 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -6,6 +6,7 @@ package ld import ( "bytes" + "cmd/internal/codesign" "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/loader" @@ -17,6 +18,7 @@ import ( "os" "sort" "strings" + "unsafe" ) type MachoHdr struct { @@ -76,36 +78,38 @@ const ( ) const ( - MACHO_CPU_AMD64 = 1<<24 | 7 - MACHO_CPU_386 = 7 - MACHO_SUBCPU_X86 = 3 - MACHO_CPU_ARM = 12 - MACHO_SUBCPU_ARM = 0 - MACHO_SUBCPU_ARMV7 = 9 - MACHO_CPU_ARM64 = 1<<24 | 12 - MACHO_SUBCPU_ARM64_ALL = 0 - MACHO32SYMSIZE = 12 - MACHO64SYMSIZE = 16 - MACHO_X86_64_RELOC_UNSIGNED = 0 - MACHO_X86_64_RELOC_SIGNED = 1 - MACHO_X86_64_RELOC_BRANCH = 2 - MACHO_X86_64_RELOC_GOT_LOAD = 3 - MACHO_X86_64_RELOC_GOT = 4 - MACHO_X86_64_RELOC_SUBTRACTOR = 5 - MACHO_X86_64_RELOC_SIGNED_1 = 6 - MACHO_X86_64_RELOC_SIGNED_2 = 7 - MACHO_X86_64_RELOC_SIGNED_4 = 8 - MACHO_ARM_RELOC_VANILLA = 0 - MACHO_ARM_RELOC_PAIR = 1 - MACHO_ARM_RELOC_SECTDIFF = 2 - MACHO_ARM_RELOC_BR24 = 5 - MACHO_ARM64_RELOC_UNSIGNED = 0 - MACHO_ARM64_RELOC_BRANCH26 = 2 - MACHO_ARM64_RELOC_PAGE21 = 3 - MACHO_ARM64_RELOC_PAGEOFF12 = 4 - MACHO_ARM64_RELOC_ADDEND = 10 - MACHO_GENERIC_RELOC_VANILLA = 0 - MACHO_FAKE_GOTPCREL = 100 + MACHO_CPU_AMD64 = 1<<24 | 7 + MACHO_CPU_386 = 7 + MACHO_SUBCPU_X86 = 3 + MACHO_CPU_ARM = 12 + MACHO_SUBCPU_ARM = 0 + MACHO_SUBCPU_ARMV7 = 9 + MACHO_CPU_ARM64 = 1<<24 | 12 + MACHO_SUBCPU_ARM64_ALL = 0 + MACHO32SYMSIZE = 12 + MACHO64SYMSIZE = 16 + MACHO_X86_64_RELOC_UNSIGNED = 0 + MACHO_X86_64_RELOC_SIGNED = 1 + MACHO_X86_64_RELOC_BRANCH = 2 + MACHO_X86_64_RELOC_GOT_LOAD = 3 + MACHO_X86_64_RELOC_GOT = 4 + MACHO_X86_64_RELOC_SUBTRACTOR = 5 + MACHO_X86_64_RELOC_SIGNED_1 = 6 + MACHO_X86_64_RELOC_SIGNED_2 = 7 + MACHO_X86_64_RELOC_SIGNED_4 = 8 + MACHO_ARM_RELOC_VANILLA = 0 + MACHO_ARM_RELOC_PAIR = 1 + MACHO_ARM_RELOC_SECTDIFF = 2 + MACHO_ARM_RELOC_BR24 = 5 + MACHO_ARM64_RELOC_UNSIGNED = 0 + MACHO_ARM64_RELOC_BRANCH26 = 2 + MACHO_ARM64_RELOC_PAGE21 = 3 + MACHO_ARM64_RELOC_PAGEOFF12 = 4 + MACHO_ARM64_RELOC_GOT_LOAD_PAGE21 = 5 + MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6 + MACHO_ARM64_RELOC_ADDEND = 10 + MACHO_GENERIC_RELOC_VANILLA = 0 + MACHO_FAKE_GOTPCREL = 100 ) const ( @@ -116,6 +120,8 @@ const ( MH_EXECUTE = 0x2 MH_NOUNDEFS = 0x1 + MH_DYLDLINK = 0x4 + MH_PIE = 0x200000 ) const ( @@ -191,6 +197,58 @@ const ( PLATFORM_BRIDGEOS MachoPlatform = 5 ) +// rebase table opcode +const ( + REBASE_TYPE_POINTER = 1 + REBASE_TYPE_TEXT_ABSOLUTE32 = 2 + REBASE_TYPE_TEXT_PCREL32 = 3 + + REBASE_OPCODE_MASK = 0xF0 + REBASE_IMMEDIATE_MASK = 0x0F + REBASE_OPCODE_DONE = 0x00 + REBASE_OPCODE_SET_TYPE_IMM = 0x10 + REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20 + REBASE_OPCODE_ADD_ADDR_ULEB = 0x30 + REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40 + REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50 + REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60 + REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70 + REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80 +) + +// bind table opcode +const ( + BIND_TYPE_POINTER = 1 + BIND_TYPE_TEXT_ABSOLUTE32 = 2 + BIND_TYPE_TEXT_PCREL32 = 3 + + BIND_SPECIAL_DYLIB_SELF = 0 + BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1 + BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2 + BIND_SPECIAL_DYLIB_WEAK_LOOKUP = -3 + + BIND_OPCODE_MASK = 0xF0 + BIND_IMMEDIATE_MASK = 0x0F + BIND_OPCODE_DONE = 0x00 + BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10 + BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20 + BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30 + BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40 + BIND_OPCODE_SET_TYPE_IMM = 0x50 + BIND_OPCODE_SET_ADDEND_SLEB = 0x60 + BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70 + BIND_OPCODE_ADD_ADDR_ULEB = 0x80 + BIND_OPCODE_DO_BIND = 0x90 + BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0 + BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0 + BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0 + BIND_OPCODE_THREADED = 0xD0 + BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB = 0x00 + BIND_SUBOPCODE_THREADED_APPLY = 0x01 +) + +const machoHeaderSize64 = 8 * 4 // size of 64-bit Mach-O header + // Mach-O file writing // https://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html @@ -277,7 +335,7 @@ var dylib []string var linkoff int64 -func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int { +func machowrite(ctxt *Link, arch *sys.Arch, out *OutBuf, linkmode LinkMode) int { o1 := out.Offset() loadsize := 4 * 4 * ndebug @@ -306,11 +364,14 @@ func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int { } out.Write32(uint32(len(load)) + uint32(nseg) + uint32(ndebug)) out.Write32(uint32(loadsize)) + flags := uint32(0) if nkind[SymKindUndef] == 0 { - out.Write32(MH_NOUNDEFS) /* flags - no undefines */ - } else { - out.Write32(0) /* flags */ + flags |= MH_NOUNDEFS } + if ctxt.IsPIE() && linkmode == LinkInternal { + flags |= MH_PIE | MH_DYLDLINK + } + out.Write32(flags) /* flags */ if arch.PtrSize == 8 { out.Write32(0) /* reserved */ } @@ -473,6 +534,18 @@ func (ctxt *Link) domacho() { sb.SetReachable(true) sb.AddUint8(0) } + + // Do not export C symbols dynamically in plugins, as runtime C symbols like crosscall2 + // are in pclntab and end up pointing at the host binary, breaking unwinding. + // See Issue #18190. + if ctxt.BuildMode == BuildModePlugin { + for _, name := range []string{"_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2"} { + s := ctxt.loader.Lookup(name, 0) + if s != 0 { + ctxt.loader.SetAttrCgoExportDynamic(s, false) + } + } + } } func machoadddynlib(lib string, linkmode LinkMode) { @@ -499,16 +572,7 @@ func machoadddynlib(lib string, linkmode LinkMode) { func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) { buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1) - var msect *MachoSect - if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 || - (ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe)) { - // Darwin external linker on arm64, and on amd64 in c-shared/c-archive buildmode - // complains about absolute relocs in __TEXT, so if the section is not - // executable, put it in __DATA segment. - msect = newMachoSect(mseg, buf, "__DATA") - } else { - msect = newMachoSect(mseg, buf, segname) - } + msect := newMachoSect(mseg, buf, segname) if sect.Rellen > 0 { msect.reloc = uint32(sect.Reloff) @@ -583,6 +647,8 @@ func asmbMacho(ctxt *Link) { } ctxt.Out.SeekSet(0) + ldr := ctxt.loader + /* apple MACH */ va := *FlagTextAddr - int64(HEADR) @@ -633,13 +699,28 @@ func asmbMacho(ctxt *Link) { machoshbits(ctxt, ms, sect, "__TEXT") } + /* rodata */ + if ctxt.LinkMode != LinkExternal && Segrelrodata.Length > 0 { + ms = newMachoSeg("__DATA_CONST", 20) + ms.vaddr = Segrelrodata.Vaddr + ms.vsize = Segrelrodata.Length + ms.fileoffset = Segrelrodata.Fileoff + ms.filesize = Segrelrodata.Filelen + ms.prot1 = 3 + ms.prot2 = 3 + ms.flag = 0x10 // SG_READ_ONLY + } + + for _, sect := range Segrelrodata.Sections { + machoshbits(ctxt, ms, sect, "__DATA_CONST") + } + /* data */ if ctxt.LinkMode != LinkExternal { - w := int64(Segdata.Length) ms = newMachoSeg("__DATA", 20) - ms.vaddr = uint64(va) + uint64(v) - ms.vsize = uint64(w) - ms.fileoffset = uint64(v) + ms.vaddr = Segdata.Vaddr + ms.vsize = Segdata.Length + ms.fileoffset = Segdata.Fileoff ms.filesize = Segdata.Filelen ms.prot1 = 3 ms.prot2 = 3 @@ -676,40 +757,56 @@ func asmbMacho(ctxt *Link) { ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32) case sys.ARM64: - ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2) - ml.data[0] = 6 /* thread type */ - ml.data[1] = 68 /* word count */ - ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */ - ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32) + ml := newMachoLoad(ctxt.Arch, LC_MAIN, 4) + ml.data[0] = uint32(uint64(Entryvalue(ctxt)) - (Segtext.Vaddr - uint64(HEADR))) + ml.data[1] = uint32((uint64(Entryvalue(ctxt)) - (Segtext.Vaddr - uint64(HEADR))) >> 32) } } + var codesigOff int64 if !*FlagD { - ldr := ctxt.loader - - // must match domacholink below - s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0)) - s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT) - s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT) - s4 := ldr.SymSize(ldr.Lookup(".machosymstr", 0)) + // must match doMachoLink below + s1 := ldr.SymSize(ldr.Lookup(".machorebase", 0)) + s2 := ldr.SymSize(ldr.Lookup(".machobind", 0)) + s3 := ldr.SymSize(ldr.Lookup(".machosymtab", 0)) + s4 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT) + s5 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT) + s6 := ldr.SymSize(ldr.Lookup(".machosymstr", 0)) + s7 := ldr.SymSize(ldr.Lookup(".machocodesig", 0)) if ctxt.LinkMode != LinkExternal { ms := newMachoSeg("__LINKEDIT", 0) - ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound))) - ms.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4) + ms.vaddr = uint64(Rnd(int64(Segdata.Vaddr+Segdata.Length), int64(*FlagRound))) + ms.vsize = uint64(s1 + s2 + s3 + s4 + s5 + s6 + s7) ms.fileoffset = uint64(linkoff) ms.filesize = ms.vsize - ms.prot1 = 7 - ms.prot2 = 3 + ms.prot1 = 1 + ms.prot2 = 1 + + codesigOff = linkoff + s1 + s2 + s3 + s4 + s5 + s6 + } + + if ctxt.LinkMode != LinkExternal && ctxt.IsPIE() { + ml := newMachoLoad(ctxt.Arch, LC_DYLD_INFO_ONLY, 10) + ml.data[0] = uint32(linkoff) // rebase off + ml.data[1] = uint32(s1) // rebase size + ml.data[2] = uint32(linkoff + s1) // bind off + ml.data[3] = uint32(s2) // bind size + ml.data[4] = 0 // weak bind off + ml.data[5] = 0 // weak bind size + ml.data[6] = 0 // lazy bind off + ml.data[7] = 0 // lazy bind size + ml.data[8] = 0 // export + ml.data[9] = 0 // export size } ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4) - ml.data[0] = uint32(linkoff) /* symoff */ - ml.data[1] = uint32(nsortsym) /* nsyms */ - ml.data[2] = uint32(linkoff + s1 + s2 + s3) /* stroff */ - ml.data[3] = uint32(s4) /* strsize */ + ml.data[0] = uint32(linkoff + s1 + s2) /* symoff */ + ml.data[1] = uint32(nsortsym) /* nsyms */ + ml.data[2] = uint32(linkoff + s1 + s2 + s3 + s4 + s5) /* stroff */ + ml.data[3] = uint32(s6) /* strsize */ - machodysymtab(ctxt) + machodysymtab(ctxt, linkoff+s1+s2) if ctxt.LinkMode != LinkExternal { ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6) @@ -725,12 +822,31 @@ func asmbMacho(ctxt *Link) { stringtouint32(ml.data[4:], lib) } } + + if ctxt.IsInternal() && ctxt.NeedCodeSign() { + ml := newMachoLoad(ctxt.Arch, LC_CODE_SIGNATURE, 2) + ml.data[0] = uint32(codesigOff) + ml.data[1] = uint32(s7) + } } - a := machowrite(ctxt.Arch, ctxt.Out, ctxt.LinkMode) + a := machowrite(ctxt, ctxt.Arch, ctxt.Out, ctxt.LinkMode) if int32(a) > HEADR { Exitf("HEADR too small: %d > %d", a, HEADR) } + + // Now we have written everything. Compute the code signature (which + // is a hash of the file content, so it must be done at last.) + if ctxt.IsInternal() && ctxt.NeedCodeSign() { + cs := ldr.Lookup(".machocodesig", 0) + data := ctxt.Out.Data() + if int64(len(data)) != codesigOff { + panic("wrong size") + } + codesign.Sign(ldr.Data(cs), bytes.NewReader(data), "a.out", codesigOff, int64(Segtext.Fileoff), int64(Segtext.Filelen), ctxt.IsExe() || ctxt.IsPIE()) + ctxt.Out.SeekSet(codesigOff) + ctxt.Out.Write(ldr.Data(cs)) + } } func symkind(ldr *loader.Loader, s loader.Sym) int { @@ -812,12 +928,10 @@ func collectmachosyms(ctxt *Link) { switch objabi.GOARCH { case "amd64": ldr.SetSymExtname(s, n+"$INODE64") - case "386": - ldr.SetSymExtname(s, n+"$INODE64$UNIX2003") } case "readdir_r", "getfsstat": switch objabi.GOARCH { - case "amd64", "386": + case "amd64": ldr.SetSymExtname(s, n+"$INODE64") } } @@ -891,19 +1005,12 @@ func machosymtab(ctxt *Link) { symtab.AddUint32(ctxt.Arch, uint32(symstr.Size())) export := machoShouldExport(ctxt, ldr, s) - isGoSymbol := strings.Contains(ldr.SymExtname(s), ".") - // In normal buildmodes, only add _ to C symbols, as - // Go symbols have dot in the name. - // - // Do not export C symbols in plugins, as runtime C - // symbols like crosscall2 are in pclntab and end up - // pointing at the host binary, breaking unwinding. - // See Issue #18190. - cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(ldr.SymName(s))) - if cexport || export || isGoSymbol { - symstr.AddUint8('_') - } + // Prefix symbol names with "_" to match the system toolchain. + // (We used to only prefix C symbols, which is all required for the build. + // But some tools don't recognize Go symbols as symbols, so we prefix them + // as well.) + symstr.AddUint8('_') // replace "·" as ".", because DTrace cannot handle it. symstr.Addstring(strings.Replace(ldr.SymExtname(s), "·", ".", -1)) @@ -914,10 +1021,13 @@ func machosymtab(ctxt *Link) { symtab.AddUint16(ctxt.Arch, 0) // desc symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value } else { - if ldr.AttrCgoExport(s) || export { - symtab.AddUint8(0x0f) + if export || ldr.AttrCgoExportDynamic(s) { + symtab.AddUint8(0x0f) // N_SECT | N_EXT + } else if ldr.AttrCgoExportStatic(s) { + // Only export statically, not dynamically. (N_PEXT is like hidden visibility) + symtab.AddUint8(0x1f) // N_SECT | N_EXT | N_PEXT } else { - symtab.AddUint8(0x0e) + symtab.AddUint8(0x0e) // N_SECT } o := s if outer := ldr.OuterSym(o); outer != 0 { @@ -935,7 +1045,7 @@ func machosymtab(ctxt *Link) { } } -func machodysymtab(ctxt *Link) { +func machodysymtab(ctxt *Link, base int64) { ml := newMachoLoad(ctxt.Arch, LC_DYSYMTAB, 18) n := 0 @@ -963,7 +1073,7 @@ func machodysymtab(ctxt *Link) { s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0)) s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT) s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT) - ml.data[12] = uint32(linkoff + s1) /* indirectsymoff */ + ml.data[12] = uint32(base + s1) /* indirectsymoff */ ml.data[13] = uint32((s2 + s3) / 4) /* nindirectsyms */ ml.data[14] = 0 /* extreloff */ @@ -974,14 +1084,19 @@ func machodysymtab(ctxt *Link) { func doMachoLink(ctxt *Link) int64 { machosymtab(ctxt) + machoDyldInfo(ctxt) ldr := ctxt.loader // write data that will be linkedit section - s1 := ldr.Lookup(".machosymtab", 0) - s2 := ctxt.ArchSyms.LinkEditPLT - s3 := ctxt.ArchSyms.LinkEditGOT - s4 := ldr.Lookup(".machosymstr", 0) + s1 := ldr.Lookup(".machorebase", 0) + s2 := ldr.Lookup(".machobind", 0) + s3 := ldr.Lookup(".machosymtab", 0) + s4 := ctxt.ArchSyms.LinkEditPLT + s5 := ctxt.ArchSyms.LinkEditGOT + s6 := ldr.Lookup(".machosymstr", 0) + + size := ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4) + ldr.SymSize(s5) + ldr.SymSize(s6) // Force the linkedit section to end on a 16-byte // boundary. This allows pure (non-cgo) Go binaries @@ -1000,24 +1115,31 @@ func doMachoLink(ctxt *Link) int64 { // boundary, codesign_allocate will not need to apply // any alignment padding itself, working around the // issue. - s4b := ldr.MakeSymbolUpdater(s4) - for s4b.Size()%16 != 0 { - s4b.AddUint8(0) + if size%16 != 0 { + n := 16 - size%16 + s6b := ldr.MakeSymbolUpdater(s6) + s6b.Grow(s6b.Size() + n) + s6b.SetSize(s6b.Size() + n) + size += n } - size := int(ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4)) - if size > 0 { - linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound)) + linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segrelrodata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound)) ctxt.Out.SeekSet(linkoff) ctxt.Out.Write(ldr.Data(s1)) ctxt.Out.Write(ldr.Data(s2)) ctxt.Out.Write(ldr.Data(s3)) ctxt.Out.Write(ldr.Data(s4)) + ctxt.Out.Write(ldr.Data(s5)) + ctxt.Out.Write(ldr.Data(s6)) + + // Add code signature if necessary. This must be the last. + s7 := machoCodeSigSym(ctxt, linkoff+size) + size += ldr.SymSize(s7) } - return Rnd(int64(size), int64(*FlagRound)) + return Rnd(size, int64(*FlagRound)) } func machorelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) { @@ -1086,6 +1208,9 @@ func machoEmitReloc(ctxt *Link) { for _, sect := range Segtext.Sections[1:] { relocSect(ctxt, sect, ctxt.datap) } + for _, sect := range Segrelrodata.Sections { + relocSect(ctxt, sect, ctxt.datap) + } for _, sect := range Segdata.Sections { relocSect(ctxt, sect, ctxt.datap) } @@ -1155,3 +1280,240 @@ func peekMachoPlatform(m *macho.File) (*MachoPlatformLoad, error) { } return nil, nil } + +// A rebase entry tells the dynamic linker the data at sym+off needs to be +// relocated when the in-memory image moves. (This is somewhat like, say, +// ELF R_X86_64_RELATIVE). +// For now, the only kind of entry we support is that the data is an absolute +// address. That seems all we need. +// In the binary it uses a compact stateful bytecode encoding. So we record +// entries as we go and build the table at the end. +type machoRebaseRecord struct { + sym loader.Sym + off int64 +} + +var machorebase []machoRebaseRecord + +func MachoAddRebase(s loader.Sym, off int64) { + machorebase = append(machorebase, machoRebaseRecord{s, off}) +} + +// A bind entry tells the dynamic linker the data at GOT+off should be bound +// to the address of the target symbol, which is a dynamic import. +// For now, the only kind of entry we support is that the data is an absolute +// address, and the source symbol is always the GOT. That seems all we need. +// In the binary it uses a compact stateful bytecode encoding. So we record +// entries as we go and build the table at the end. +type machoBindRecord struct { + off int64 + targ loader.Sym +} + +var machobind []machoBindRecord + +func MachoAddBind(off int64, targ loader.Sym) { + machobind = append(machobind, machoBindRecord{off, targ}) +} + +// Generate data for the dynamic linker, used in LC_DYLD_INFO_ONLY load command. +// See mach-o/loader.h, struct dyld_info_command, for the encoding. +// e.g. https://opensource.apple.com/source/xnu/xnu-6153.81.5/EXTERNAL_HEADERS/mach-o/loader.h +func machoDyldInfo(ctxt *Link) { + ldr := ctxt.loader + rebase := ldr.CreateSymForUpdate(".machorebase", 0) + bind := ldr.CreateSymForUpdate(".machobind", 0) + + if !(ctxt.IsPIE() && ctxt.IsInternal()) { + return + } + + segId := func(seg *sym.Segment) uint8 { + switch seg { + case &Segtext: + return 1 + case &Segrelrodata: + return 2 + case &Segdata: + if Segrelrodata.Length > 0 { + return 3 + } + return 2 + } + panic("unknown segment") + } + + dylibId := func(s loader.Sym) int { + slib := ldr.SymDynimplib(s) + for i, lib := range dylib { + if lib == slib { + return i + 1 + } + } + return BIND_SPECIAL_DYLIB_FLAT_LOOKUP // don't know where it is from + } + + // Rebase table. + // TODO: use more compact encoding. The encoding is stateful, and + // we can use delta encoding. + rebase.AddUint8(REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER) + for _, r := range machorebase { + seg := ldr.SymSect(r.sym).Seg + off := uint64(ldr.SymValue(r.sym)+r.off) - seg.Vaddr + rebase.AddUint8(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segId(seg)) + rebase.AddUleb(off) + + rebase.AddUint8(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1) + } + rebase.AddUint8(REBASE_OPCODE_DONE) + sz := Rnd(rebase.Size(), 8) + rebase.Grow(sz) + rebase.SetSize(sz) + + // Bind table. + // TODO: compact encoding, as above. + // TODO: lazy binding? + got := ctxt.GOT + seg := ldr.SymSect(got).Seg + gotAddr := ldr.SymValue(got) + bind.AddUint8(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER) + for _, r := range machobind { + off := uint64(gotAddr+r.off) - seg.Vaddr + bind.AddUint8(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segId(seg)) + bind.AddUleb(off) + + d := dylibId(r.targ) + if d > 0 && d < 128 { + bind.AddUint8(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | uint8(d)&0xf) + } else if d >= 128 { + bind.AddUint8(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB) + bind.AddUleb(uint64(d)) + } else { // d <= 0 + bind.AddUint8(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | uint8(d)&0xf) + } + + bind.AddUint8(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) + // target symbol name as a C string, with _ prefix + bind.AddUint8('_') + bind.Addstring(ldr.SymExtname(r.targ)) + + bind.AddUint8(BIND_OPCODE_DO_BIND) + } + bind.AddUint8(BIND_OPCODE_DONE) + sz = Rnd(bind.Size(), 16) // make it 16-byte aligned, see the comment in doMachoLink + bind.Grow(sz) + bind.SetSize(sz) + + // TODO: export table. + // The symbols names are encoded as a trie. I'm really too lazy to do that + // for now. + // Without it, the symbols are not dynamically exported, so they cannot be + // e.g. dlsym'd. But internal linking is not the default in that case, so + // it is fine. +} + +// machoCodeSigSym creates and returns a symbol for code signature. +// The symbol context is left as zeros, which will be generated at the end +// (as it depends on the rest of the file). +func machoCodeSigSym(ctxt *Link, codeSize int64) loader.Sym { + ldr := ctxt.loader + cs := ldr.CreateSymForUpdate(".machocodesig", 0) + if !ctxt.NeedCodeSign() || ctxt.IsExternal() { + return cs.Sym() + } + sz := codesign.Size(codeSize, "a.out") + cs.Grow(sz) + cs.SetSize(sz) + return cs.Sym() +} + +// machoCodeSign code-signs Mach-O file fname with an ad-hoc signature. +// This is used for updating an external linker generated binary. +func machoCodeSign(ctxt *Link, fname string) error { + f, err := os.OpenFile(fname, os.O_RDWR, 0) + if err != nil { + return err + } + defer f.Close() + + mf, err := macho.NewFile(f) + if err != nil { + return err + } + if mf.Magic != macho.Magic64 { + Exitf("not 64-bit Mach-O file: %s", fname) + } + + // Find existing LC_CODE_SIGNATURE and __LINKEDIT segment + var sigOff, sigSz, csCmdOff, linkeditOff int64 + var linkeditSeg, textSeg *macho.Segment + loadOff := int64(machoHeaderSize64) + get32 := mf.ByteOrder.Uint32 + for _, l := range mf.Loads { + data := l.Raw() + cmd, sz := get32(data), get32(data[4:]) + if cmd == LC_CODE_SIGNATURE { + sigOff = int64(get32(data[8:])) + sigSz = int64(get32(data[12:])) + csCmdOff = loadOff + } + if seg, ok := l.(*macho.Segment); ok { + switch seg.Name { + case "__LINKEDIT": + linkeditSeg = seg + linkeditOff = loadOff + case "__TEXT": + textSeg = seg + } + } + loadOff += int64(sz) + } + + if sigOff == 0 { + // The C linker doesn't generate a signed binary, for some reason. + // Skip. + return nil + } + + fi, err := f.Stat() + if err != nil { + return err + } + if sigOff+sigSz != fi.Size() { + // We don't expect anything after the signature (this will invalidate + // the signature anyway.) + return fmt.Errorf("unexpected content after code signature") + } + + sz := codesign.Size(sigOff, "a.out") + if sz != sigSz { + // Update the load command, + var tmp [8]byte + mf.ByteOrder.PutUint32(tmp[:4], uint32(sz)) + _, err = f.WriteAt(tmp[:4], csCmdOff+12) + if err != nil { + return err + } + + // Uodate the __LINKEDIT segment. + segSz := sigOff + sz - int64(linkeditSeg.Offset) + mf.ByteOrder.PutUint64(tmp[:8], uint64(segSz)) + _, err = f.WriteAt(tmp[:8], int64(linkeditOff)+int64(unsafe.Offsetof(macho.Segment64{}.Memsz))) + if err != nil { + return err + } + _, err = f.WriteAt(tmp[:8], int64(linkeditOff)+int64(unsafe.Offsetof(macho.Segment64{}.Filesz))) + if err != nil { + return err + } + } + + cs := make([]byte, sz) + codesign.Sign(cs, f, "a.out", sigOff, int64(textSeg.Offset), int64(textSeg.Filesz), ctxt.IsExe() || ctxt.IsPIE()) + _, err = f.WriteAt(cs, sigOff) + if err != nil { + return err + } + err = f.Truncate(sigOff + sz) + return err +} diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index 6f4ccbfb7a..5c8293810f 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -65,6 +65,7 @@ var ( flagDumpDep = flag.Bool("dumpdep", false, "dump symbol dependency graph") flagRace = flag.Bool("race", false, "enable race detector") flagMsan = flag.Bool("msan", false, "enable MSan interface") + flagAslr = flag.Bool("aslr", true, "enable ASLR for buildmode=c-shared on windows") flagFieldTrack = flag.String("k", "", "set field tracking `symbol`") flagLibGCC = flag.String("libgcc", "", "compiler support lib for internal linking; use \"none\" to disable") @@ -157,11 +158,16 @@ func Main(arch *sys.Arch, theArch Arch) { ctxt.HeadType.Set(objabi.GOOS) } + if !*flagAslr && ctxt.BuildMode != BuildModeCShared { + Errorf(nil, "-aslr=false is only allowed for -buildmode=c-shared") + usage() + } + checkStrictDups = *FlagStrictDups startProfile() if ctxt.BuildMode == BuildModeUnset { - ctxt.BuildMode = BuildModeExe + ctxt.BuildMode.Set("exe") } if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 { @@ -323,10 +329,14 @@ func Main(arch *sys.Arch, theArch Arch) { // will be applied directly there. bench.Start("Asmb") asmb(ctxt) - // Generate large symbols. - for s, f := range ctxt.generatorSyms { - f(ctxt, s) + + // Generate additional symbols for the native symbol table just prior + // to code generation. + bench.Start("GenSymsLate") + if thearch.GenSymsLate != nil { + thearch.GenSymsLate(ctxt, ctxt.loader) } + bench.Start("Asmb2") asmb2(ctxt) diff --git a/src/cmd/link/internal/ld/outbuf.go b/src/cmd/link/internal/ld/outbuf.go index d696a68088..530836ef7c 100644 --- a/src/cmd/link/internal/ld/outbuf.go +++ b/src/cmd/link/internal/ld/outbuf.go @@ -13,11 +13,10 @@ import ( "os" ) -// If fallocate is not supported on this platform, return this error. -// Note this is the same error returned by filesystems that don't support -// fallocate, and that is intentional. The error is ignored where needed, and -// OutBuf writes to heap memory. -const fallocateNotSupportedErr = "operation not supported" +// If fallocate is not supported on this platform, return this error. The error +// is ignored where needed, and OutBuf writes to heap memory. +var errNoFallocate = errors.New("operation not supported") + const outbufMode = 0775 // OutBuf is a buffered file writer. @@ -114,6 +113,7 @@ func (out *OutBuf) Close() error { } if out.isMmapped() { out.copyHeap() + out.purgeSignatureCache() out.munmap() } if out.f == nil { @@ -136,6 +136,15 @@ func (out *OutBuf) isMmapped() bool { return len(out.buf) != 0 } +// Data returns the whole written OutBuf as a byte slice. +func (out *OutBuf) Data() []byte { + if out.isMmapped() { + out.copyHeap() + return out.buf + } + return out.heap +} + // copyHeap copies the heap to the mmapped section of memory, returning true if // a copy takes place. func (out *OutBuf) copyHeap() bool { @@ -184,7 +193,9 @@ func (out *OutBuf) writeLoc(lenToWrite int64) (int64, []byte) { // See if our heap would grow to be too large, and if so, copy it to the end // of the mmapped area. if heapLen > maxOutBufHeapLen && out.copyHeap() { - heapPos, heapLen, lenNeeded = 0, 0, lenToWrite + heapPos -= heapLen + lenNeeded = heapPos + lenToWrite + heapLen = 0 } out.heap = append(out.heap, make([]byte, lenNeeded-heapLen)...) } diff --git a/src/cmd/link/internal/ld/outbuf_darwin.go b/src/cmd/link/internal/ld/outbuf_darwin.go index d7e3372230..9444b6567e 100644 --- a/src/cmd/link/internal/ld/outbuf_darwin.go +++ b/src/cmd/link/internal/ld/outbuf_darwin.go @@ -36,3 +36,12 @@ func (out *OutBuf) fallocate(size uint64) error { return nil } + +func (out *OutBuf) purgeSignatureCache() { + // Apparently, the Darwin kernel may cache the code signature at mmap. + // When we mmap the output buffer, it doesn't have a code signature + // (as we haven't generated one). Invalidate the kernel cache now that + // we have generated the signature. See issue #42684. + syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(&out.buf[0])), uintptr(len(out.buf)), syscall.MS_INVALIDATE) + // Best effort. Ignore error. +} diff --git a/src/cmd/link/internal/ld/outbuf_mmap.go b/src/cmd/link/internal/ld/outbuf_mmap.go index 53b14b09cc..807fe24375 100644 --- a/src/cmd/link/internal/ld/outbuf_mmap.go +++ b/src/cmd/link/internal/ld/outbuf_mmap.go @@ -28,7 +28,7 @@ func (out *OutBuf) Mmap(filesize uint64) (err error) { // Some file systems do not support fallocate. We ignore that error as linking // can still take place, but you might SIGBUS when you write to the mmapped // area. - if err.Error() != fallocateNotSupportedErr { + if err != syscall.ENOTSUP && err != syscall.EPERM && err != errNoFallocate { return err } } diff --git a/src/cmd/link/internal/ld/outbuf_nofallocate.go b/src/cmd/link/internal/ld/outbuf_nofallocate.go index 51b4fe7aff..6bf96bcb2b 100644 --- a/src/cmd/link/internal/ld/outbuf_nofallocate.go +++ b/src/cmd/link/internal/ld/outbuf_nofallocate.go @@ -6,8 +6,6 @@ package ld -import "errors" - func (out *OutBuf) fallocate(size uint64) error { - return errors.New(fallocateNotSupportedErr) + return errNoFallocate } diff --git a/src/cmd/link/internal/ld/outbuf_notdarwin.go b/src/cmd/link/internal/ld/outbuf_notdarwin.go new file mode 100644 index 0000000000..8c5666f216 --- /dev/null +++ b/src/cmd/link/internal/ld/outbuf_notdarwin.go @@ -0,0 +1,9 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !darwin + +package ld + +func (out *OutBuf) purgeSignatureCache() {} diff --git a/src/cmd/link/internal/ld/outbuf_test.go b/src/cmd/link/internal/ld/outbuf_test.go index db0a92485e..e6643da396 100644 --- a/src/cmd/link/internal/ld/outbuf_test.go +++ b/src/cmd/link/internal/ld/outbuf_test.go @@ -17,7 +17,7 @@ func TestMMap(t *testing.T) { switch runtime.GOOS { default: t.Skip("unsupported OS") - case "aix", "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "windows": + case "aix", "darwin", "ios", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "windows": } dir, err := ioutil.TempDir("", "TestMMap") if err != nil { diff --git a/src/cmd/link/internal/ld/outbuf_windows.go b/src/cmd/link/internal/ld/outbuf_windows.go index 60dc1ab92d..915c72bef3 100644 --- a/src/cmd/link/internal/ld/outbuf_windows.go +++ b/src/cmd/link/internal/ld/outbuf_windows.go @@ -35,7 +35,10 @@ func (out *OutBuf) Mmap(filesize uint64) error { if err != nil { return err } - *(*reflect.SliceHeader)(unsafe.Pointer(&out.buf)) = reflect.SliceHeader{Data: ptr, Len: int(filesize), Cap: int(filesize)} + bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&out.buf)) + bufHdr.Data = ptr + bufHdr.Len = int(filesize) + bufHdr.Cap = int(filesize) // copy heap to new mapping if uint64(oldlen+len(out.heap)) > filesize { diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index 30e0bdc839..facb30fe15 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -6,45 +6,23 @@ package ld import ( "cmd/internal/goobj" - "cmd/internal/obj" "cmd/internal/objabi" - "cmd/internal/src" "cmd/internal/sys" "cmd/link/internal/loader" "cmd/link/internal/sym" - "encoding/binary" "fmt" - "log" - "math" "os" "path/filepath" - "strings" ) -// oldPclnState holds state information used during pclntab generation. Here -// 'ldr' is just a pointer to the context's loader, 'deferReturnSym' is the -// index for the symbol "runtime.deferreturn", 'nameToOffset' is a helper -// function for capturing function names, 'numberedFiles' records the file -// number assigned to a given file symbol, 'filepaths' is a slice of expanded -// paths (indexed by file number). -// -// NB: This is deprecated, and will be eliminated when pclntab_old is -// eliminated. -type oldPclnState struct { - ldr *loader.Loader - deferReturnSym loader.Sym - numberedFiles map[string]int64 - filepaths []string -} - // pclntab holds the state needed for pclntab generation. type pclntab struct { + // The size of the func object in the runtime. + funcSize uint32 + // The first and last functions found. firstFunc, lastFunc loader.Sym - // The offset to the filetab. - filetabOffset int32 - // Running total size of pclntab. size int64 @@ -54,6 +32,9 @@ type pclntab struct { pcheader loader.Sym funcnametab loader.Sym findfunctab loader.Sym + cutab loader.Sym + filetab loader.Sym + pctab loader.Sym // The number of functions + number of TEXT sections - 1. This is such an // unexpected value because platforms that have more than one TEXT section @@ -64,11 +45,8 @@ type pclntab struct { // On most platforms this is the number of reachable functions. nfunc int32 - // maps the function symbol to offset in runtime.funcnametab - // This doesn't need to reside in the state once pclntab_old's been - // deleted -- it can live in generateFuncnametab. - // TODO(jfaller): Delete me! - funcNameOffset map[loader.Sym]int32 + // The number of filenames in runtime.filetab. + nfiles uint32 } // addGeneratedSym adds a generator symbol to pclntab, returning the new Sym. @@ -83,40 +61,29 @@ func (state *pclntab) addGeneratedSym(ctxt *Link, name string, size int64, f gen return s } -func makeOldPclnState(ctxt *Link) *oldPclnState { - ldr := ctxt.loader - drs := ldr.Lookup("runtime.deferreturn", sym.SymVerABIInternal) - state := &oldPclnState{ - ldr: ldr, - deferReturnSym: drs, - numberedFiles: make(map[string]int64), - // NB: initial entry in filepaths below is to reserve the zero value, - // so that when we do a map lookup in numberedFiles fails, it will not - // return a value slot in filepaths. - filepaths: []string{""}, - } - - return state -} - // makePclntab makes a pclntab object, and assembles all the compilation units -// we'll need to write pclntab. -func makePclntab(ctxt *Link, container loader.Bitmap) (*pclntab, []*sym.CompilationUnit) { +// we'll need to write pclntab. Returns the pclntab structure, a slice of the +// CompilationUnits we need, and a slice of the function symbols we need to +// generate pclntab. +func makePclntab(ctxt *Link, container loader.Bitmap) (*pclntab, []*sym.CompilationUnit, []loader.Sym) { ldr := ctxt.loader state := &pclntab{ - funcNameOffset: make(map[loader.Sym]int32), + // This is the size of the _func object in runtime/runtime2.go. + funcSize: uint32(ctxt.Arch.PtrSize + 9*4), } // Gather some basic stats and info. seenCUs := make(map[*sym.CompilationUnit]struct{}) prevSect := ldr.SymSect(ctxt.Textp[0]) compUnits := []*sym.CompilationUnit{} + funcs := []loader.Sym{} for _, s := range ctxt.Textp { if !emitPcln(ctxt, s, container) { continue } + funcs = append(funcs, s) state.nfunc++ if state.firstFunc == 0 { state.firstFunc = s @@ -142,116 +109,22 @@ func makePclntab(ctxt *Link, container loader.Bitmap) (*pclntab, []*sym.Compilat compUnits = append(compUnits, cu) } } - return state, compUnits -} - -func ftabaddstring(ftab *loader.SymbolBuilder, s string) int32 { - start := len(ftab.Data()) - ftab.Grow(int64(start + len(s) + 1)) // make room for s plus trailing NUL - ftd := ftab.Data() - copy(ftd[start:], s) - return int32(start) -} - -// numberfile assigns a file number to the file if it hasn't been assigned already. -// This funciton looks at a CU's file at index [i], and if it's a new filename, -// stores that filename in the global file table, and adds it to the map lookup -// for renumbering pcfile. -func (state *oldPclnState) numberfile(cu *sym.CompilationUnit, i goobj.CUFileIndex) int64 { - file := cu.FileTable[i] - if val, ok := state.numberedFiles[file]; ok { - return val - } - path := file - if strings.HasPrefix(path, src.FileSymPrefix) { - path = file[len(src.FileSymPrefix):] - } - val := int64(len(state.filepaths)) - state.numberedFiles[file] = val - state.filepaths = append(state.filepaths, expandGoroot(path)) - return val -} - -func (state *oldPclnState) fileVal(cu *sym.CompilationUnit, i int32) int64 { - file := cu.FileTable[i] - if val, ok := state.numberedFiles[file]; ok { - return val - } - panic("should have been numbered first") -} - -func (state *oldPclnState) renumberfiles(ctxt *Link, cu *sym.CompilationUnit, fi loader.FuncInfo, d *sym.Pcdata) { - // Give files numbers. - nf := fi.NumFile() - for i := uint32(0); i < nf; i++ { - state.numberfile(cu, fi.File(int(i))) - } - - buf := make([]byte, binary.MaxVarintLen32) - newval := int32(-1) - var out sym.Pcdata - it := obj.NewPCIter(uint32(ctxt.Arch.MinLC)) - for it.Init(d.P); !it.Done; it.Next() { - // value delta - oldval := it.Value - - var val int32 - if oldval == -1 { - val = -1 - } else { - if oldval < 0 || oldval >= int32(len(cu.FileTable)) { - log.Fatalf("bad pcdata %d", oldval) - } - val = int32(state.fileVal(cu, oldval)) - } - - dv := val - newval - newval = val - - // value - n := binary.PutVarint(buf, int64(dv)) - out.P = append(out.P, buf[:n]...) - - // pc delta - pc := (it.NextPC - it.PC) / it.PCScale - n = binary.PutUvarint(buf, uint64(pc)) - out.P = append(out.P, buf[:n]...) - } - - // terminating value delta - // we want to write varint-encoded 0, which is just 0 - out.P = append(out.P, 0) - - *d = out -} - -// onlycsymbol looks at a symbol's name to report whether this is a -// symbol that is referenced by C code -func onlycsymbol(sname string) bool { - switch sname { - case "_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2": - return true - } - if strings.HasPrefix(sname, "_cgoexp_") { - return true - } - return false + return state, compUnits, funcs } func emitPcln(ctxt *Link, s loader.Sym, container loader.Bitmap) bool { - if ctxt.BuildMode == BuildModePlugin && ctxt.HeadType == objabi.Hdarwin && onlycsymbol(ctxt.loader.SymName(s)) { - return false - } // We want to generate func table entries only for the "lowest // level" symbols, not containers of subsymbols. return !container.Has(s) } -func (state *oldPclnState) computeDeferReturn(target *Target, s loader.Sym) uint32 { +func computeDeferReturn(ctxt *Link, deferReturnSym, s loader.Sym) uint32 { + ldr := ctxt.loader + target := ctxt.Target deferreturn := uint32(0) lastWasmAddr := uint32(0) - relocs := state.ldr.Relocs(s) + relocs := ldr.Relocs(s) for ri := 0; ri < relocs.Count(); ri++ { r := relocs.At(ri) if target.IsWasm() && r.Type() == objabi.R_ADDR { @@ -262,7 +135,7 @@ func (state *oldPclnState) computeDeferReturn(target *Target, s loader.Sym) uint // set the resumption point to PC_B. lastWasmAddr = uint32(r.Add()) } - if r.Type().IsDirectCall() && (r.Sym() == state.deferReturnSym || state.ldr.IsDeferReturnTramp(r.Sym())) { + if r.Type().IsDirectCall() && (r.Sym() == deferReturnSym || ldr.IsDeferReturnTramp(r.Sym())) { if target.IsWasm() { deferreturn = lastWasmAddr - 1 } else { @@ -295,8 +168,8 @@ func (state *oldPclnState) computeDeferReturn(target *Target, s loader.Sym) uint // genInlTreeSym generates the InlTree sym for a function with the // specified FuncInfo. -func (state *oldPclnState) genInlTreeSym(cu *sym.CompilationUnit, fi loader.FuncInfo, arch *sys.Arch, newState *pclntab) loader.Sym { - ldr := state.ldr +func genInlTreeSym(ctxt *Link, cu *sym.CompilationUnit, fi loader.FuncInfo, arch *sys.Arch, nameOffsets map[loader.Sym]uint32) loader.Sym { + ldr := ctxt.loader its := ldr.CreateExtSym("", 0) inlTreeSym := ldr.MakeSymbolUpdater(its) // Note: the generated symbol is given a type of sym.SGOFUNC, as a @@ -308,13 +181,8 @@ func (state *oldPclnState) genInlTreeSym(cu *sym.CompilationUnit, fi loader.Func ninl := fi.NumInlTree() for i := 0; i < int(ninl); i++ { call := fi.InlTree(i) - // Usually, call.File is already numbered since the file - // shows up in the Pcfile table. However, two inlined calls - // might overlap exactly so that only the innermost file - // appears in the Pcfile table. In that case, this assigns - // the outer file a number. - val := state.numberfile(cu, call.File) - nameoff, ok := newState.funcNameOffset[call.Func] + val := call.File + nameoff, ok := nameOffsets[call.Func] if !ok { panic("couldn't find function name offset") } @@ -337,6 +205,22 @@ func (state *oldPclnState) genInlTreeSym(cu *sym.CompilationUnit, fi loader.Func return its } +// makeInlSyms returns a map of loader.Sym that are created inlSyms. +func makeInlSyms(ctxt *Link, funcs []loader.Sym, nameOffsets map[loader.Sym]uint32) map[loader.Sym]loader.Sym { + ldr := ctxt.loader + // Create the inline symbols we need. + inlSyms := make(map[loader.Sym]loader.Sym) + for _, s := range funcs { + if fi := ldr.FuncInfo(s); fi.Valid() { + fi.Preload() + if fi.NumInlTree() > 0 { + inlSyms[s] = genInlTreeSym(ctxt, ldr.SymUnit(s), fi, ctxt.Arch, nameOffsets) + } + } + } + return inlSyms +} + // generatePCHeader creates the runtime.pcheader symbol, setting it up as a // generator to fill in its data later. func (state *pclntab) generatePCHeader(ctxt *Link) { @@ -359,24 +243,24 @@ func (state *pclntab) generatePCHeader(ctxt *Link) { header.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC)) header.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize)) off := header.SetUint(ctxt.Arch, 8, uint64(state.nfunc)) + off = header.SetUint(ctxt.Arch, off, uint64(state.nfiles)) off = writeSymOffset(off, state.funcnametab) + off = writeSymOffset(off, state.cutab) + off = writeSymOffset(off, state.filetab) + off = writeSymOffset(off, state.pctab) off = writeSymOffset(off, state.pclntab) } - size := int64(8 + 3*ctxt.Arch.PtrSize) + size := int64(8 + 7*ctxt.Arch.PtrSize) state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader) } -// walkFuncs iterates over the Textp, calling a function for each unique +// walkFuncs iterates over the funcs, calling a function for each unique // function and inlined function. -func (state *pclntab) walkFuncs(ctxt *Link, container loader.Bitmap, f func(loader.Sym)) { +func walkFuncs(ctxt *Link, funcs []loader.Sym, f func(loader.Sym)) { ldr := ctxt.loader seen := make(map[loader.Sym]struct{}) - for _, ls := range ctxt.Textp { - s := loader.Sym(ls) - if !emitPcln(ctxt, s, container) { - continue - } + for _, s := range funcs { if _, ok := seen[s]; !ok { f(s) seen[s] = struct{}{} @@ -397,207 +281,484 @@ func (state *pclntab) walkFuncs(ctxt *Link, container loader.Bitmap, f func(load } } -// generateFuncnametab creates the function name table. -func (state *pclntab) generateFuncnametab(ctxt *Link, container loader.Bitmap) { +// generateFuncnametab creates the function name table. Returns a map of +// func symbol to the name offset in runtime.funcnamtab. +func (state *pclntab) generateFuncnametab(ctxt *Link, funcs []loader.Sym) map[loader.Sym]uint32 { + nameOffsets := make(map[loader.Sym]uint32, state.nfunc) + // Write the null terminated strings. writeFuncNameTab := func(ctxt *Link, s loader.Sym) { symtab := ctxt.loader.MakeSymbolUpdater(s) - for s, off := range state.funcNameOffset { + for s, off := range nameOffsets { symtab.AddStringAt(int64(off), ctxt.loader.SymName(s)) } } // Loop through the CUs, and calculate the size needed. var size int64 - state.walkFuncs(ctxt, container, func(s loader.Sym) { - state.funcNameOffset[s] = int32(size) + walkFuncs(ctxt, funcs, func(s loader.Sym) { + nameOffsets[s] = uint32(size) size += int64(ctxt.loader.SymNameLen(s)) + 1 // NULL terminate }) state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, writeFuncNameTab) + return nameOffsets } -// pclntab initializes the pclntab symbol with -// runtime function and file name information. +// walkFilenames walks funcs, calling a function for each filename used in each +// function's line table. +func walkFilenames(ctxt *Link, funcs []loader.Sym, f func(*sym.CompilationUnit, goobj.CUFileIndex)) { + ldr := ctxt.loader -// pclntab generates the pcln table for the link output. -func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab { - // Go 1.2's symtab layout is documented in golang.org/s/go12symtab, but the - // layout and data has changed since that time. - // - // As of July 2020, here's the layout of pclntab: - // - // .gopclntab/__gopclntab [elf/macho section] - // runtime.pclntab - // Carrier symbol for the entire pclntab section. - // - // runtime.pcheader (see: runtime/symtab.go:pcHeader) - // 8-byte magic - // nfunc [thearch.ptrsize bytes] - // offset to runtime.funcnametab from the beginning of runtime.pcheader - // offset to runtime.pclntab_old from beginning of runtime.pcheader + // Loop through all functions, finding the filenames we need. + for _, s := range funcs { + fi := ldr.FuncInfo(s) + if !fi.Valid() { + continue + } + fi.Preload() + + cu := ldr.SymUnit(s) + for i, nf := 0, int(fi.NumFile()); i < nf; i++ { + f(cu, fi.File(i)) + } + for i, ninl := 0, int(fi.NumInlTree()); i < ninl; i++ { + call := fi.InlTree(i) + f(cu, call.File) + } + } +} + +// generateFilenameTabs creates LUTs needed for filename lookup. Returns a slice +// of the index at which each CU begins in runtime.cutab. +// +// Function objects keep track of the files they reference to print the stack. +// This function creates a per-CU list of filenames if CU[M] references +// files[1-N], the following is generated: +// +// runtime.cutab: +// CU[M] +// offsetToFilename[0] +// offsetToFilename[1] +// .. +// +// runtime.filetab +// filename[0] +// filename[1] +// +// Looking up a filename then becomes: +// 0) Given a func, and filename index [K] +// 1) Get Func.CUIndex: M := func.cuOffset +// 2) Find filename offset: fileOffset := runtime.cutab[M+K] +// 3) Get the filename: getcstring(runtime.filetab[fileOffset]) +func (state *pclntab) generateFilenameTabs(ctxt *Link, compUnits []*sym.CompilationUnit, funcs []loader.Sym) []uint32 { + // On a per-CU basis, keep track of all the filenames we need. // - // runtime.funcnametab - // []list of null terminated function names + // Note, that we store the filenames in a separate section in the object + // files, and deduplicate based on the actual value. It would be better to + // store the filenames as symbols, using content addressable symbols (and + // then not loading extra filenames), and just use the hash value of the + // symbol name to do this cataloging. // - // runtime.pclntab_old - // function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes] - // end PC [thearch.ptrsize bytes] - // offset to file table [4 bytes] - // func structures, pcdata tables. - // filetable + // TOOD: Store filenames as symbols. (Note this would be easiest if you + // also move strings to ALWAYS using the larger content addressable hash + // function, and use that hash value for uniqueness testing.) + cuEntries := make([]goobj.CUFileIndex, len(compUnits)) + fileOffsets := make(map[string]uint32) - oldState := makeOldPclnState(ctxt) - state, _ := makePclntab(ctxt, container) + // Walk the filenames. + // We store the total filename string length we need to load, and the max + // file index we've seen per CU so we can calculate how large the + // CU->global table needs to be. + var fileSize int64 + walkFilenames(ctxt, funcs, func(cu *sym.CompilationUnit, i goobj.CUFileIndex) { + // Note we use the raw filename for lookup, but use the expanded filename + // when we save the size. + filename := cu.FileTable[i] + if _, ok := fileOffsets[filename]; !ok { + fileOffsets[filename] = uint32(fileSize) + fileSize += int64(len(expandFile(filename)) + 1) // NULL terminate + } - ldr := ctxt.loader - state.carrier = ldr.LookupOrCreateSym("runtime.pclntab", 0) - ldr.MakeSymbolUpdater(state.carrier).SetType(sym.SPCLNTAB) - ldr.SetAttrReachable(state.carrier, true) + // Find the maximum file index we've seen. + if cuEntries[cu.PclnIndex] < i+1 { + cuEntries[cu.PclnIndex] = i + 1 // Store max + 1 + } + }) - // runtime.pclntab_old is just a placeholder,and will eventually be deleted. - // It contains the pieces of runtime.pclntab that haven't moved to a more - // rational form. - state.pclntab = ldr.LookupOrCreateSym("runtime.pclntab_old", 0) - state.generatePCHeader(ctxt) - state.generateFuncnametab(ctxt, container) + // Calculate the size of the runtime.cutab variable. + var totalEntries uint32 + cuOffsets := make([]uint32, len(cuEntries)) + for i, entries := range cuEntries { + // Note, cutab is a slice of uint32, so an offset to a cu's entry is just the + // running total of all cu indices we've needed to store so far, not the + // number of bytes we've stored so far. + cuOffsets[i] = totalEntries + totalEntries += uint32(entries) + } + + // Write cutab. + writeCutab := func(ctxt *Link, s loader.Sym) { + sb := ctxt.loader.MakeSymbolUpdater(s) - funcdataBytes := int64(0) - ldr.SetCarrierSym(state.pclntab, state.carrier) - ldr.SetAttrNotInSymbolTable(state.pclntab, true) - ftab := ldr.MakeSymbolUpdater(state.pclntab) - ftab.SetValue(state.size) - ftab.SetType(sym.SPCLNTAB) - ftab.SetReachable(true) + var off int64 + for i, max := range cuEntries { + // Write the per CU LUT. + cu := compUnits[i] + for j := goobj.CUFileIndex(0); j < max; j++ { + fileOffset, ok := fileOffsets[cu.FileTable[j]] + if !ok { + // We're looping through all possible file indices. It's possible a file's + // been deadcode eliminated, and although it's a valid file in the CU, it's + // not needed in this binary. When that happens, use an invalid offset. + fileOffset = ^uint32(0) + } + off = sb.SetUint32(ctxt.Arch, off, fileOffset) + } + } + } + state.cutab = state.addGeneratedSym(ctxt, "runtime.cutab", int64(totalEntries*4), writeCutab) - ftab.Grow(int64(state.nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4) + // Write filetab. + writeFiletab := func(ctxt *Link, s loader.Sym) { + sb := ctxt.loader.MakeSymbolUpdater(s) - szHint := len(ctxt.Textp) * 2 - pctaboff := make(map[string]uint32, szHint) - writepctab := func(off int32, p []byte) int32 { - start, ok := pctaboff[string(p)] - if !ok { - if len(p) > 0 { - start = uint32(len(ftab.Data())) - ftab.AddBytes(p) + // Write the strings. + for filename, loc := range fileOffsets { + sb.AddStringAt(int64(loc), expandFile(filename)) + } + } + state.nfiles = uint32(len(fileOffsets)) + state.filetab = state.addGeneratedSym(ctxt, "runtime.filetab", fileSize, writeFiletab) + + return cuOffsets +} + +// generatePctab creates the runtime.pctab variable, holding all the +// deduplicated pcdata. +func (state *pclntab) generatePctab(ctxt *Link, funcs []loader.Sym) { + ldr := ctxt.loader + + // Pctab offsets of 0 are considered invalid in the runtime. We respect + // that by just padding a single byte at the beginning of runtime.pctab, + // that way no real offsets can be zero. + size := int64(1) + + // Walk the functions, finding offset to store each pcdata. + seen := make(map[loader.Sym]struct{}) + saveOffset := func(pcSym loader.Sym) { + if _, ok := seen[pcSym]; !ok { + datSize := ldr.SymSize(pcSym) + if datSize != 0 { + ldr.SetSymValue(pcSym, size) + } else { + // Invalid PC data, record as zero. + ldr.SetSymValue(pcSym, 0) } - pctaboff[string(p)] = start + size += datSize + seen[pcSym] = struct{}{} + } + } + for _, s := range funcs { + fi := ldr.FuncInfo(s) + if !fi.Valid() { + continue + } + fi.Preload() + + pcSyms := []loader.Sym{fi.Pcsp(), fi.Pcfile(), fi.Pcline()} + for _, pcSym := range pcSyms { + saveOffset(pcSym) + } + for _, pcSym := range fi.Pcdata() { + saveOffset(pcSym) + } + if fi.NumInlTree() > 0 { + saveOffset(fi.Pcinline()) + } + } + + // TODO: There is no reason we need a generator for this variable, and it + // could be moved to a carrier symbol. However, carrier symbols containing + // carrier symbols don't work yet (as of Aug 2020). Once this is fixed, + // runtime.pctab could just be a carrier sym. + writePctab := func(ctxt *Link, s loader.Sym) { + ldr := ctxt.loader + sb := ldr.MakeSymbolUpdater(s) + for sym := range seen { + sb.SetBytesAt(ldr.SymValue(sym), ldr.Data(sym)) + } + } + + state.pctab = state.addGeneratedSym(ctxt, "runtime.pctab", size, writePctab) +} + +// numPCData returns the number of PCData syms for the FuncInfo. +// NB: Preload must be called on valid FuncInfos before calling this function. +func numPCData(fi loader.FuncInfo) uint32 { + if !fi.Valid() { + return 0 + } + numPCData := uint32(len(fi.Pcdata())) + if fi.NumInlTree() > 0 { + if numPCData < objabi.PCDATA_InlTreeIndex+1 { + numPCData = objabi.PCDATA_InlTreeIndex + 1 } - newoff := int32(ftab.SetUint32(ctxt.Arch, int64(off), start)) - return newoff } + return numPCData +} + +// Helper types for iterating pclntab. +type pclnSetAddr func(*loader.SymbolBuilder, *sys.Arch, int64, loader.Sym, int64) int64 +type pclnSetUint func(*loader.SymbolBuilder, *sys.Arch, int64, uint64) int64 - setAddr := (*loader.SymbolBuilder).SetAddrPlus - if ctxt.IsExe() && ctxt.IsInternal() { - // Internal linking static executable. At this point the function - // addresses are known, so we can just use them instead of emitting - // relocations. - // For other cases we are generating a relocatable binary so we - // still need to emit relocations. - setAddr = func(s *loader.SymbolBuilder, arch *sys.Arch, off int64, tgt loader.Sym, add int64) int64 { - if v := ldr.SymValue(tgt); v != 0 { - return s.SetUint(arch, off, uint64(v+add)) +// generateFunctab creates the runtime.functab +// +// runtime.functab contains two things: +// +// - pc->func look up table. +// - array of func objects, interleaved with pcdata and funcdata +// +// Because of timing in the linker, generating this table takes two passes. +// The first pass is executed early in the link, and it creates any needed +// relocations to layout the data. The pieces that need relocations are: +// 1) the PC->func table. +// 2) The entry points in the func objects. +// 3) The funcdata. +// (1) and (2) are handled in walkPCToFunc. (3) is handled in walkFuncdata. +// +// After relocations, once we know where to write things in the output buffer, +// we execute the second pass, which is actually writing the data. +func (state *pclntab) generateFunctab(ctxt *Link, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) { + // Calculate the size of the table. + size, startLocations := state.calculateFunctabSize(ctxt, funcs) + + // If we are internally linking a static executable, the function addresses + // are known, so we can just use them instead of emitting relocations. For + // other cases we still need to emit relocations. + // + // This boolean just helps us figure out which callback to use. + useSymValue := ctxt.IsExe() && ctxt.IsInternal() + + writePcln := func(ctxt *Link, s loader.Sym) { + ldr := ctxt.loader + sb := ldr.MakeSymbolUpdater(s) + + // Create our callbacks. + var setAddr pclnSetAddr + if useSymValue { + // We need to write the offset. + setAddr = func(s *loader.SymbolBuilder, arch *sys.Arch, off int64, tgt loader.Sym, add int64) int64 { + if v := ldr.SymValue(tgt); v != 0 { + s.SetUint(arch, off, uint64(v+add)) + } + return 0 } - return s.SetAddrPlus(arch, off, tgt, add) + } else { + // We already wrote relocations. + setAddr = func(s *loader.SymbolBuilder, arch *sys.Arch, off int64, tgt loader.Sym, add int64) int64 { return 0 } } + + // Write the data. + writePcToFunc(ctxt, sb, funcs, startLocations, setAddr, (*loader.SymbolBuilder).SetUint) + writeFuncs(ctxt, sb, funcs, inlSyms, startLocations, cuOffsets, nameOffsets) + state.writeFuncData(ctxt, sb, funcs, inlSyms, startLocations, setAddr, (*loader.SymbolBuilder).SetUint) } - pcsp := sym.Pcdata{} - pcfile := sym.Pcdata{} - pcline := sym.Pcdata{} - pcdata := []sym.Pcdata{} - funcdata := []loader.Sym{} - funcdataoff := []int64{} + state.pclntab = state.addGeneratedSym(ctxt, "runtime.functab", size, writePcln) - var nfunc int32 - prevFunc := ctxt.Textp[0] - for _, s := range ctxt.Textp { - if !emitPcln(ctxt, s, container) { - continue + // Create the relocations we need. + ldr := ctxt.loader + sb := ldr.MakeSymbolUpdater(state.pclntab) + + var setAddr pclnSetAddr + if useSymValue { + // If we should use the symbol value, and we don't have one, write a relocation. + setAddr = func(sb *loader.SymbolBuilder, arch *sys.Arch, off int64, tgt loader.Sym, add int64) int64 { + if v := ldr.SymValue(tgt); v == 0 { + sb.SetAddrPlus(arch, off, tgt, add) + } + return 0 } + } else { + // If we're externally linking, write a relocation. + setAddr = (*loader.SymbolBuilder).SetAddrPlus + } + setUintNOP := func(*loader.SymbolBuilder, *sys.Arch, int64, uint64) int64 { return 0 } + writePcToFunc(ctxt, sb, funcs, startLocations, setAddr, setUintNOP) + if !useSymValue { + // Generate relocations for funcdata when externally linking. + state.writeFuncData(ctxt, sb, funcs, inlSyms, startLocations, setAddr, setUintNOP) + } +} - thisSect := ldr.SymSect(s) - prevSect := ldr.SymSect(prevFunc) - if thisSect != prevSect { - // With multiple text sections, there may be a hole here - // in the address space (see the comment above). We use an - // invalid funcoff value to mark the hole. See also - // runtime/symtab.go:findfunc - prevFuncSize := int64(ldr.SymSize(prevFunc)) - setAddr(ftab, ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize), prevFunc, prevFuncSize) - ftab.SetUint(ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), ^uint64(0)) - nfunc++ +// funcData returns the funcdata and offsets for the FuncInfo. +// The funcdata and offsets are written into runtime.functab after each func +// object. This is a helper function to make querying the FuncInfo object +// cleaner. +// +// Note, the majority of fdOffsets are 0, meaning there is no offset between +// the compiler's generated symbol, and what the runtime needs. They are +// plumbed through for no loss of generality. +// +// NB: Preload must be called on the FuncInfo before calling. +// NB: fdSyms and fdOffs are used as scratch space. +func funcData(fi loader.FuncInfo, inlSym loader.Sym, fdSyms []loader.Sym, fdOffs []int64) ([]loader.Sym, []int64) { + fdSyms, fdOffs = fdSyms[:0], fdOffs[:0] + if fi.Valid() { + numOffsets := int(fi.NumFuncdataoff()) + for i := 0; i < numOffsets; i++ { + fdOffs = append(fdOffs, fi.Funcdataoff(i)) } - prevFunc = s + fdSyms = fi.Funcdata(fdSyms) + if fi.NumInlTree() > 0 { + if len(fdSyms) < objabi.FUNCDATA_InlTree+1 { + fdSyms = append(fdSyms, make([]loader.Sym, objabi.FUNCDATA_InlTree+1-len(fdSyms))...) + fdOffs = append(fdOffs, make([]int64, objabi.FUNCDATA_InlTree+1-len(fdOffs))...) + } + fdSyms[objabi.FUNCDATA_InlTree] = inlSym + } + } + return fdSyms, fdOffs +} + +// calculateFunctabSize calculates the size of the pclntab, and the offsets in +// the output buffer for individual func entries. +func (state pclntab) calculateFunctabSize(ctxt *Link, funcs []loader.Sym) (int64, []uint32) { + ldr := ctxt.loader + startLocations := make([]uint32, len(funcs)) + + // Allocate space for the pc->func table. This structure consists of a pc + // and an offset to the func structure. After that, we have a single pc + // value that marks the end of the last function in the binary. + size := int64(int(state.nfunc)*2*ctxt.Arch.PtrSize + ctxt.Arch.PtrSize) - pcsp.P = pcsp.P[:0] - pcline.P = pcline.P[:0] - pcfile.P = pcfile.P[:0] - pcdata = pcdata[:0] - funcdataoff = funcdataoff[:0] - funcdata = funcdata[:0] + // Now find the space for the func objects. We do this in a running manner, + // so that we can find individual starting locations, and because funcdata + // requires alignment. + for i, s := range funcs { + size = Rnd(size, int64(ctxt.Arch.PtrSize)) + startLocations[i] = uint32(size) fi := ldr.FuncInfo(s) + size += int64(state.funcSize) if fi.Valid() { fi.Preload() - npc := fi.NumPcdata() - for i := uint32(0); i < npc; i++ { - pcdata = append(pcdata, sym.Pcdata{P: fi.Pcdata(int(i))}) + numFuncData := int(fi.NumFuncdataoff()) + if fi.NumInlTree() > 0 { + if numFuncData < objabi.FUNCDATA_InlTree+1 { + numFuncData = objabi.FUNCDATA_InlTree + 1 + } } - nfd := fi.NumFuncdataoff() - for i := uint32(0); i < nfd; i++ { - funcdataoff = append(funcdataoff, fi.Funcdataoff(int(i))) + size += int64(numPCData(fi) * 4) + if numFuncData > 0 { // Func data is aligned. + size = Rnd(size, int64(ctxt.Arch.PtrSize)) } - funcdata = fi.Funcdata(funcdata) + size += int64(numFuncData * ctxt.Arch.PtrSize) } + } - if fi.Valid() && fi.NumInlTree() > 0 { - - if len(pcdata) <= objabi.PCDATA_InlTreeIndex { - // Create inlining pcdata table. - newpcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1) - copy(newpcdata, pcdata) - pcdata = newpcdata - } + return size, startLocations +} - if len(funcdataoff) <= objabi.FUNCDATA_InlTree { - // Create inline tree funcdata. - newfuncdata := make([]loader.Sym, objabi.FUNCDATA_InlTree+1) - newfuncdataoff := make([]int64, objabi.FUNCDATA_InlTree+1) - copy(newfuncdata, funcdata) - copy(newfuncdataoff, funcdataoff) - funcdata = newfuncdata - funcdataoff = newfuncdataoff - } +// writePcToFunc writes the PC->func lookup table. +// This function walks the pc->func lookup table, executing callbacks +// to generate relocations and writing the values for the table. +func writePcToFunc(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, startLocations []uint32, setAddr pclnSetAddr, setUint pclnSetUint) { + ldr := ctxt.loader + var prevFunc loader.Sym + prevSect := ldr.SymSect(funcs[0]) + funcIndex := 0 + for i, s := range funcs { + if thisSect := ldr.SymSect(s); thisSect != prevSect { + // With multiple text sections, there may be a hole here in the + // address space. We use an invalid funcoff value to mark the hole. + // See also runtime/symtab.go:findfunc + prevFuncSize := int64(ldr.SymSize(prevFunc)) + setAddr(sb, ctxt.Arch, int64(funcIndex*2*ctxt.Arch.PtrSize), prevFunc, prevFuncSize) + setUint(sb, ctxt.Arch, int64((funcIndex*2+1)*ctxt.Arch.PtrSize), ^uint64(0)) + funcIndex++ + prevSect = thisSect } + prevFunc = s + // TODO: We don't actually need these relocations, provided we go to a + // module->func look-up-table like we do for filenames. We could have a + // single relocation for the module, and have them all laid out as + // offsets from the beginning of that module. + setAddr(sb, ctxt.Arch, int64(funcIndex*2*ctxt.Arch.PtrSize), s, 0) + setUint(sb, ctxt.Arch, int64((funcIndex*2+1)*ctxt.Arch.PtrSize), uint64(startLocations[i])) + funcIndex++ - dSize := len(ftab.Data()) - funcstart := int32(dSize) - funcstart += int32(-dSize) & (int32(ctxt.Arch.PtrSize) - 1) // align to ptrsize + // Write the entry location. + setAddr(sb, ctxt.Arch, int64(startLocations[i]), s, 0) + } - setAddr(ftab, ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s, 0) - ftab.SetUint(ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart)) + // Final entry of table is just end pc. + setAddr(sb, ctxt.Arch, int64(funcIndex)*2*int64(ctxt.Arch.PtrSize), prevFunc, ldr.SymSize(prevFunc)) +} - // Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func - // and package debug/gosym. +// writeFuncData writes the funcdata tables. +// +// This function executes a callback for each funcdata needed in +// runtime.functab. It should be called once for internally linked static +// binaries, or twice (once to generate the needed relocations) for other +// build modes. +// +// Note the output of this function is interwoven with writeFuncs, but this is +// a separate function, because it's needed in different passes in +// generateFunctab. +func (state *pclntab) writeFuncData(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations []uint32, setAddr pclnSetAddr, setUint pclnSetUint) { + ldr := ctxt.loader + funcdata, funcdataoff := []loader.Sym{}, []int64{} + for i, s := range funcs { + fi := ldr.FuncInfo(s) + if !fi.Valid() { + continue + } + fi.Preload() - // fixed size of struct, checked below - off := funcstart + // funcdata, must be pointer-aligned and we're only int32-aligned. + // Missing funcdata will be 0 (nil pointer). + funcdata, funcdataoff := funcData(fi, inlSyms[s], funcdata, funcdataoff) + if len(funcdata) > 0 { + off := int64(startLocations[i] + state.funcSize + numPCData(fi)*4) + off = Rnd(off, int64(ctxt.Arch.PtrSize)) + for j := range funcdata { + dataoff := off + int64(ctxt.Arch.PtrSize*j) + if funcdata[j] == 0 { + setUint(sb, ctxt.Arch, dataoff, uint64(funcdataoff[j])) + continue + } + // TODO: Does this need deduping? + setAddr(sb, ctxt.Arch, dataoff, funcdata[j], funcdataoff[j]) + } + } + } +} + +// writeFuncs writes the func structures and pcdata to runtime.functab. +func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) { + ldr := ctxt.loader + deferReturnSym := ldr.Lookup("runtime.deferreturn", sym.SymVerABIInternal) + funcdata, funcdataoff := []loader.Sym{}, []int64{} - end := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 5*4 + int32(len(pcdata))*4 + int32(len(funcdata))*int32(ctxt.Arch.PtrSize) - if len(funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) { - end += 4 + // Write the individual func objects. + for i, s := range funcs { + fi := ldr.FuncInfo(s) + if fi.Valid() { + fi.Preload() } - ftab.Grow(int64(end)) - // entry uintptr - off = int32(setAddr(ftab, ctxt.Arch, int64(off), s, 0)) + // Note we skip the space for the entry value -- that's handled inn + // walkPCToFunc. We don't write it here, because it might require a + // relocation. + off := startLocations[i] + uint32(ctxt.Arch.PtrSize) // entry // name int32 - nameoff, ok := state.funcNameOffset[s] + nameoff, ok := nameOffsets[s] if !ok { panic("couldn't find function name offset") } - off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(nameoff))) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), uint32(nameoff))) // args int32 // TODO: Move into funcinfo. @@ -605,118 +766,106 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab { if fi.Valid() { args = uint32(fi.Args()) } - off = int32(ftab.SetUint32(ctxt.Arch, int64(off), args)) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), args)) // deferreturn - deferreturn := oldState.computeDeferReturn(&ctxt.Target, s) - off = int32(ftab.SetUint32(ctxt.Arch, int64(off), deferreturn)) + deferreturn := computeDeferReturn(ctxt, deferReturnSym, s) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), deferreturn)) - cu := ldr.SymUnit(s) + // pcdata if fi.Valid() { - pcsp = sym.Pcdata{P: fi.Pcsp()} - pcfile = sym.Pcdata{P: fi.Pcfile()} - pcline = sym.Pcdata{P: fi.Pcline()} - oldState.renumberfiles(ctxt, cu, fi, &pcfile) - if false { - // Sanity check the new numbering - it := obj.NewPCIter(uint32(ctxt.Arch.MinLC)) - for it.Init(pcfile.P); !it.Done; it.Next() { - if it.Value < 1 || it.Value > int32(len(oldState.numberedFiles)) { - ctxt.Errorf(s, "bad file number in pcfile: %d not in range [1, %d]\n", it.Value, len(oldState.numberedFiles)) - errorexit() - } - } - } - } - - if fi.Valid() && fi.NumInlTree() > 0 { - its := oldState.genInlTreeSym(cu, fi, ctxt.Arch, state) - funcdata[objabi.FUNCDATA_InlTree] = its - pcdata[objabi.PCDATA_InlTreeIndex] = sym.Pcdata{P: fi.Pcinline()} + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcsp())))) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcfile())))) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcline())))) + } else { + off += 12 } + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), uint32(numPCData(fi)))) - // pcdata - off = writepctab(off, pcsp.P) - off = writepctab(off, pcfile.P) - off = writepctab(off, pcline.P) - off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcdata)))) - - // Store the compilation unit index. - cuIdx := ^uint16(0) + // Store the offset to compilation unit's file table. + cuIdx := ^uint32(0) if cu := ldr.SymUnit(s); cu != nil { - if cu.PclnIndex > math.MaxUint16 { - panic("cu limit reached.") - } - cuIdx = uint16(cu.PclnIndex) + cuIdx = cuOffsets[cu.PclnIndex] } - off = int32(ftab.SetUint16(ctxt.Arch, int64(off), cuIdx)) + off = uint32(sb.SetUint32(ctxt.Arch, int64(off), cuIdx)) // funcID uint8 var funcID objabi.FuncID if fi.Valid() { funcID = fi.FuncID() } - off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(funcID))) + off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(funcID))) + + off += 2 // pad // nfuncdata must be the final entry. - off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata)))) - for i := range pcdata { - off = writepctab(off, pcdata[i].P) - } + funcdata, funcdataoff = funcData(fi, 0, funcdata, funcdataoff) + off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata)))) - // funcdata, must be pointer-aligned and we're only int32-aligned. - // Missing funcdata will be 0 (nil pointer). - if len(funcdata) > 0 { - if off&int32(ctxt.Arch.PtrSize-1) != 0 { - off += 4 + // Output the pcdata. + if fi.Valid() { + for j, pcSym := range fi.Pcdata() { + sb.SetUint32(ctxt.Arch, int64(off+uint32(j*4)), uint32(ldr.SymValue(pcSym))) } - for i := range funcdata { - dataoff := int64(off) + int64(ctxt.Arch.PtrSize)*int64(i) - if funcdata[i] == 0 { - ftab.SetUint(ctxt.Arch, dataoff, uint64(funcdataoff[i])) - continue - } - // TODO: Dedup. - funcdataBytes += int64(len(ldr.Data(funcdata[i]))) - setAddr(ftab, ctxt.Arch, dataoff, funcdata[i], funcdataoff[i]) + if fi.NumInlTree() > 0 { + sb.SetUint32(ctxt.Arch, int64(off+objabi.PCDATA_InlTreeIndex*4), uint32(ldr.SymValue(fi.Pcinline()))) } - off += int32(len(funcdata)) * int32(ctxt.Arch.PtrSize) - } - - if off != end { - ctxt.Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcdata), len(funcdata), ctxt.Arch.PtrSize) - errorexit() } - - nfunc++ } +} - // Final entry of table is just end pc. - setAddr(ftab, ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize), state.lastFunc, ldr.SymSize(state.lastFunc)) - - // Start file table. - dSize := len(ftab.Data()) - start := int32(dSize) - start += int32(-dSize) & (int32(ctxt.Arch.PtrSize) - 1) - state.filetabOffset = start - ftab.SetUint32(ctxt.Arch, int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start)) +// pclntab initializes the pclntab symbol with +// runtime function and file name information. - nf := len(oldState.numberedFiles) - ftab.Grow(int64(start) + int64((nf+1)*4)) - ftab.SetUint32(ctxt.Arch, int64(start), uint32(nf+1)) - for i := nf; i > 0; i-- { - path := oldState.filepaths[i] - val := int64(i) - ftab.SetUint32(ctxt.Arch, int64(start)+val*4, uint32(ftabaddstring(ftab, path))) - } +// pclntab generates the pcln table for the link output. +func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab { + // Go 1.2's symtab layout is documented in golang.org/s/go12symtab, but the + // layout and data has changed since that time. + // + // As of August 2020, here's the layout of pclntab: + // + // .gopclntab/__gopclntab [elf/macho section] + // runtime.pclntab + // Carrier symbol for the entire pclntab section. + // + // runtime.pcheader (see: runtime/symtab.go:pcHeader) + // 8-byte magic + // nfunc [thearch.ptrsize bytes] + // offset to runtime.funcnametab from the beginning of runtime.pcheader + // offset to runtime.pclntab_old from beginning of runtime.pcheader + // + // runtime.funcnametab + // []list of null terminated function names + // + // runtime.cutab + // for i=0..#CUs + // for j=0..#max used file index in CU[i] + // uint32 offset into runtime.filetab for the filename[j] + // + // runtime.filetab + // []null terminated filename strings + // + // runtime.pctab + // []byte of deduplicated pc data. + // + // runtime.functab + // function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes] + // end PC [thearch.ptrsize bytes] + // func structures, pcdata offsets, func data. - ftab.SetSize(int64(len(ftab.Data()))) + state, compUnits, funcs := makePclntab(ctxt, container) - ctxt.NumFilesyms = len(oldState.numberedFiles) + ldr := ctxt.loader + state.carrier = ldr.LookupOrCreateSym("runtime.pclntab", 0) + ldr.MakeSymbolUpdater(state.carrier).SetType(sym.SPCLNTAB) + ldr.SetAttrReachable(state.carrier, true) - if ctxt.Debugvlog != 0 { - ctxt.Logf("pclntab=%d bytes, funcdata total %d bytes\n", ftab.Size(), funcdataBytes) - } + state.generatePCHeader(ctxt) + nameOffsets := state.generateFuncnametab(ctxt, funcs) + cuOffsets := state.generateFilenameTabs(ctxt, compUnits, funcs) + state.generatePctab(ctxt, funcs) + inlSyms := makeInlSyms(ctxt, funcs, nameOffsets) + state.generateFunctab(ctxt, funcs, inlSyms, cuOffsets, nameOffsets) return state } diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index bc880955b8..4971389613 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -34,6 +34,7 @@ import ( "cmd/internal/objabi" "cmd/link/internal/loader" "cmd/link/internal/sym" + "debug/elf" "fmt" "path/filepath" "strings" @@ -53,10 +54,10 @@ func putelfstr(s string) int { return off } -func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx int, other int) { +func putelfsyment(out *OutBuf, off int, addr int64, size int64, info uint8, shndx elf.SectionIndex, other int) { if elf64 { out.Write32(uint32(off)) - out.Write8(uint8(info)) + out.Write8(info) out.Write8(uint8(other)) out.Write16(uint16(shndx)) out.Write64(uint64(addr)) @@ -66,14 +67,14 @@ func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx out.Write32(uint32(off)) out.Write32(uint32(addr)) out.Write32(uint32(size)) - out.Write8(uint8(info)) + out.Write8(info) out.Write8(uint8(other)) out.Write16(uint16(shndx)) symSize += ELF32SYMSIZE } } -func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { +func putelfsym(ctxt *Link, x loader.Sym, typ elf.SymType, curbind elf.SymBind) { ldr := ctxt.loader addr := ldr.SymValue(x) size := ldr.SymSize(x) @@ -85,9 +86,9 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { xot := ldr.SymType(xo) xosect := ldr.SymSect(xo) - var elfshnum int + var elfshnum elf.SectionIndex if xot == sym.SDYNIMPORT || xot == sym.SHOSTOBJ || xot == sym.SUNDEFEXT { - elfshnum = SHN_UNDEF + elfshnum = elf.SHN_UNDEF size = 0 } else { if xosect == nil { @@ -101,11 +102,11 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { elfshnum = xosect.Elfsect.(*ElfShdr).shnum } - // One pass for each binding: STB_LOCAL, STB_GLOBAL, - // maybe one day STB_WEAK. - bind := STB_GLOBAL + // One pass for each binding: elf.STB_LOCAL, elf.STB_GLOBAL, + // maybe one day elf.STB_WEAK. + bind := elf.STB_GLOBAL if ldr.IsFileLocal(x) || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) { - bind = STB_LOCAL + bind = elf.STB_LOCAL } // In external linking mode, we have to invoke gcc with -rdynamic @@ -113,23 +114,23 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { // To avoid filling the dynamic table with lots of unnecessary symbols, // mark all Go symbols local (not global) in the final executable. // But when we're dynamically linking, we need all those global symbols. - if !ctxt.DynlinkingGo() && ctxt.IsExternal() && !ldr.AttrCgoExportStatic(x) && elfshnum != SHN_UNDEF { - bind = STB_LOCAL + if !ctxt.DynlinkingGo() && ctxt.IsExternal() && !ldr.AttrCgoExportStatic(x) && elfshnum != elf.SHN_UNDEF { + bind = elf.STB_LOCAL } - if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF { + if ctxt.LinkMode == LinkExternal && elfshnum != elf.SHN_UNDEF { addr -= int64(xosect.Vaddr) } - other := STV_DEFAULT + other := int(elf.STV_DEFAULT) if ldr.AttrVisibilityHidden(x) { // TODO(mwhudson): We only set AttrVisibilityHidden in ldelf, i.e. when // internally linking. But STV_HIDDEN visibility only matters in object // files and shared libraries, and as we are a long way from implementing // internal linking for shared libraries and only create object files when // externally linking, I don't think this makes a lot of sense. - other = STV_HIDDEN + other = int(elf.STV_HIDDEN) } - if ctxt.IsPPC64() && typ == STT_FUNC && ldr.AttrShared(x) && ldr.SymName(x) != "runtime.duffzero" && ldr.SymName(x) != "runtime.duffcopy" { + if ctxt.IsPPC64() && typ == elf.STT_FUNC && ldr.AttrShared(x) && ldr.SymName(x) != "runtime.duffzero" && ldr.SymName(x) != "runtime.duffcopy" { // On ppc64 the top three bits of the st_other field indicate how // many instructions separate the global and local entry points. In // our case it is two instructions, indicated by the value 3. @@ -149,7 +150,7 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { sname = strings.Replace(sname, "·", ".", -1) } - if ctxt.DynlinkingGo() && bind == STB_GLOBAL && curbind == STB_LOCAL && ldr.SymType(x) == sym.STEXT { + if ctxt.DynlinkingGo() && bind == elf.STB_GLOBAL && curbind == elf.STB_LOCAL && ldr.SymType(x) == sym.STEXT { // When dynamically linking, we want references to functions defined // in this module to always be to the function object, not to the // PLT. We force this by writing an additional local symbol for every @@ -158,7 +159,7 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { // (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the // ELF linker -Bsymbolic-functions option, but that is buggy on // several platforms. - putelfsyment(ctxt.Out, putelfstr("local."+sname), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other) + putelfsyment(ctxt.Out, putelfstr("local."+sname), addr, size, elf.ST_INFO(elf.STB_LOCAL, typ), elfshnum, other) ldr.SetSymLocalElfSym(x, int32(ctxt.numelfsym)) ctxt.numelfsym++ return @@ -166,23 +167,23 @@ func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) { return } - putelfsyment(ctxt.Out, putelfstr(sname), addr, size, bind<<4|typ&0xf, elfshnum, other) + putelfsyment(ctxt.Out, putelfstr(sname), addr, size, elf.ST_INFO(bind, typ), elfshnum, other) ldr.SetSymElfSym(x, int32(ctxt.numelfsym)) ctxt.numelfsym++ } -func putelfsectionsym(ctxt *Link, out *OutBuf, s loader.Sym, shndx int) { - putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0) +func putelfsectionsym(ctxt *Link, out *OutBuf, s loader.Sym, shndx elf.SectionIndex) { + putelfsyment(out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_SECTION), shndx, 0) ctxt.loader.SetSymElfSym(s, int32(ctxt.numelfsym)) ctxt.numelfsym++ } -func genelfsym(ctxt *Link, elfbind int) { +func genelfsym(ctxt *Link, elfbind elf.SymBind) { ldr := ctxt.loader // runtime.text marker symbol(s). s := ldr.Lookup("runtime.text", 0) - putelfsym(ctxt, s, STT_FUNC, elfbind) + putelfsym(ctxt, s, elf.STT_FUNC, elfbind) for k, sect := range Segtext.Sections[1:] { n := k + 1 if sect.Name != ".text" || (ctxt.IsAIX() && ctxt.IsExternal()) { @@ -196,18 +197,18 @@ func genelfsym(ctxt *Link, elfbind int) { if ldr.SymType(s) != sym.STEXT { panic("unexpected type for runtime.text symbol") } - putelfsym(ctxt, s, STT_FUNC, elfbind) + putelfsym(ctxt, s, elf.STT_FUNC, elfbind) } // Text symbols. for _, s := range ctxt.Textp { - putelfsym(ctxt, s, STT_FUNC, elfbind) + putelfsym(ctxt, s, elf.STT_FUNC, elfbind) } // runtime.etext marker symbol. s = ldr.Lookup("runtime.etext", 0) if ldr.SymType(s) == sym.STEXT { - putelfsym(ctxt, s, STT_FUNC, elfbind) + putelfsym(ctxt, s, elf.STT_FUNC, elfbind) } shouldBeInSymbolTable := func(s loader.Sym) bool { @@ -236,12 +237,12 @@ func genelfsym(ctxt *Link, elfbind int) { } st := ldr.SymType(s) if st >= sym.SELFRXSECT && st < sym.SXREF { - typ := STT_OBJECT + typ := elf.STT_OBJECT if st == sym.STLSBSS { if ctxt.IsInternal() { continue } - typ = STT_TLS + typ = elf.STT_TLS } if !shouldBeInSymbolTable(s) { continue @@ -250,7 +251,7 @@ func genelfsym(ctxt *Link, elfbind int) { continue } if st == sym.SHOSTOBJ || st == sym.SDYNIMPORT || st == sym.SUNDEFEXT { - putelfsym(ctxt, s, int(ldr.SymElfType(s)), elfbind) + putelfsym(ctxt, s, ldr.SymElfType(s), elfbind) } } } @@ -258,7 +259,7 @@ func genelfsym(ctxt *Link, elfbind int) { func asmElfSym(ctxt *Link) { // the first symbol entry is reserved - putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0) + putelfsyment(ctxt.Out, 0, 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_NOTYPE), 0, 0) dwarfaddelfsectionsyms(ctxt) @@ -266,12 +267,12 @@ func asmElfSym(ctxt *Link) { // Avoid having the working directory inserted into the symbol table. // It is added with a name to avoid problems with external linking // encountered on some versions of Solaris. See issue #14957. - putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0) + putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, elf.ST_INFO(elf.STB_LOCAL, elf.STT_FILE), elf.SHN_ABS, 0) ctxt.numelfsym++ - bindings := []int{STB_LOCAL, STB_GLOBAL} + bindings := []elf.SymBind{elf.STB_LOCAL, elf.STB_GLOBAL} for _, elfbind := range bindings { - if elfbind == STB_GLOBAL { + if elfbind == elf.STB_GLOBAL { elfglobalsymndx = ctxt.numelfsym } genelfsym(ctxt, elfbind) @@ -518,7 +519,7 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind { nsym := loader.Sym(ldr.NSym()) symGroupType := make([]sym.SymKind, nsym) for s := loader.Sym(1); s < nsym; s++ { - if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) { + if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "" { ldr.SetAttrNotInSymbolTable(s, true) } if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) { @@ -580,8 +581,12 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind { symGroupType[s] = sym.SGOFUNC ldr.SetAttrNotInSymbolTable(s, true) ldr.SetCarrierSym(s, symgofunc) - const align = 4 - ldr.SetSymAlign(s, align) + align := int32(4) + if a := ldr.SymAlign(s); a < align { + ldr.SetSymAlign(s, align) + } else { + align = a + } liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1) } } @@ -619,6 +624,18 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind { moduledata.AddAddr(ctxt.Arch, pcln.funcnametab) moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab))) moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.funcnametab))) + // The cutab slice + moduledata.AddAddr(ctxt.Arch, pcln.cutab) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab))) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.cutab))) + // The filetab slice + moduledata.AddAddr(ctxt.Arch, pcln.filetab) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab))) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab))) + // The pctab slice + moduledata.AddAddr(ctxt.Arch, pcln.pctab) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab))) + moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab))) // The pclntab slice moduledata.AddAddr(ctxt.Arch, pcln.pclntab) moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab))) @@ -627,10 +644,6 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind { moduledata.AddAddr(ctxt.Arch, pcln.pclntab) moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1)) moduledata.AddUint(ctxt.Arch, uint64(pcln.nfunc+1)) - // The filetab slice - moduledata.AddAddrPlus(ctxt.Arch, pcln.pclntab, int64(pcln.filetabOffset)) - moduledata.AddUint(ctxt.Arch, uint64(ctxt.NumFilesyms)+1) - moduledata.AddUint(ctxt.Arch, uint64(ctxt.NumFilesyms)+1) // findfunctab moduledata.AddAddr(ctxt.Arch, pcln.findfunctab) // minpc, maxpc @@ -681,8 +694,8 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind { itablinkSym := ldr.Lookup("runtime.itablink", 0) nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize) moduledata.AddAddr(ctxt.Arch, itablinkSym) - moduledata.AddUint(ctxt.Arch, uint64(nitablinks)) - moduledata.AddUint(ctxt.Arch, uint64(nitablinks)) + moduledata.AddUint(ctxt.Arch, nitablinks) + moduledata.AddUint(ctxt.Arch, nitablinks) // The ptab slice if ptab := ldr.Lookup("go.plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) { ldr.SetAttrLocal(ptab, true) diff --git a/src/cmd/link/internal/ld/target.go b/src/cmd/link/internal/ld/target.go index 102b6c5436..f68de8fff1 100644 --- a/src/cmd/link/internal/ld/target.go +++ b/src/cmd/link/internal/ld/target.go @@ -74,8 +74,12 @@ func (t *Target) IsDynlinkingGo() bool { func (t *Target) UseRelro() bool { switch t.BuildMode { case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin: - return t.IsELF || t.HeadType == objabi.Haix + return t.IsELF || t.HeadType == objabi.Haix || t.HeadType == objabi.Hdarwin default: + if t.HeadType == objabi.Hdarwin && t.IsARM64() { + // On darwin/ARM64, everything is PIE. + return true + } return t.linkShared || (t.HeadType == objabi.Haix && t.LinkMode == LinkExternal) } } diff --git a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod.go b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod.go index b62f18c342..32a24cf6f0 100644 --- a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod.go +++ b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod.go @@ -18,6 +18,13 @@ var p *T var e interface{} func main() { - p = new(T) // used T, but never converted to interface + p = new(T) // used T, but never converted to interface in any reachable code e.(I).M() // used I and I.M } + +func Unused() { // convert T to interface, but this function is not reachable + var i I = T(0) + i.M() +} + +var Unused2 interface{} = T(1) // convert T to interface, in an unreachable global initializer diff --git a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go new file mode 100644 index 0000000000..9a8dfbce5f --- /dev/null +++ b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go @@ -0,0 +1,29 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Like ifacemethod2.go, this tests that a method *is* live +// if the type is "indirectly" converted to an interface +// using reflection with a method descriptor as intermediate. + +package main + +import "reflect" + +type S int + +func (s S) M() { println("S.M") } + +type I interface { M() } + +type T float64 + +func (t T) F(s S) {} + +func main() { + var t T + ft := reflect.TypeOf(t).Method(0).Type + at := ft.In(1) + v := reflect.New(at).Elem() + v.Interface().(I).M() +} diff --git a/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go new file mode 100644 index 0000000000..52ee2e3d86 --- /dev/null +++ b/src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go @@ -0,0 +1,23 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that a live type's method is not live even if +// it matches an interface method, as long as the interface +// method is not used. + +package main + +type T int + +func (T) M() {} + +type I interface{ M() } + +var p *T +var pp *I + +func main() { + p = new(T) // use type T + pp = new(I) // use type I +} diff --git a/src/cmd/link/internal/ld/testdata/issue39256/x.go b/src/cmd/link/internal/ld/testdata/issue39256/x.go index d8562ad172..97bc1cc407 100644 --- a/src/cmd/link/internal/ld/testdata/issue39256/x.go +++ b/src/cmd/link/internal/ld/testdata/issue39256/x.go @@ -13,6 +13,8 @@ import ( //go:cgo_import_dynamic libc_close close "libc.so" //go:cgo_import_dynamic libc_open open "libc.so" +//go:cgo_import_dynamic _ _ "libc.so" + func trampoline() func main() { diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go index 5a39856a3b..c698874b32 100644 --- a/src/cmd/link/internal/loadelf/ldelf.go +++ b/src/cmd/link/internal/loadelf/ldelf.go @@ -372,6 +372,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, return errorf("elf object but not ppc64") } + case sys.RISCV64: + if mach != elf.EM_RISCV || class != elf.ELFCLASS64 { + return errorf("elf object but not riscv64") + } + case sys.S390X: if mach != elf.EM_S390 || class != elf.ELFCLASS64 { return errorf("elf object but not s390x") @@ -946,14 +951,15 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { // performance. const ( - AMD64 = uint32(sys.AMD64) - ARM = uint32(sys.ARM) - ARM64 = uint32(sys.ARM64) - I386 = uint32(sys.I386) - PPC64 = uint32(sys.PPC64) - S390X = uint32(sys.S390X) - MIPS = uint32(sys.MIPS) - MIPS64 = uint32(sys.MIPS64) + AMD64 = uint32(sys.AMD64) + ARM = uint32(sys.ARM) + ARM64 = uint32(sys.ARM64) + I386 = uint32(sys.I386) + MIPS = uint32(sys.MIPS) + MIPS64 = uint32(sys.MIPS64) + PPC64 = uint32(sys.PPC64) + RISCV64 = uint32(sys.RISCV64) + S390X = uint32(sys.S390X) ) switch uint32(arch.Family) | elftype<<16 { @@ -963,6 +969,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { case MIPS | uint32(elf.R_MIPS_HI16)<<16, MIPS | uint32(elf.R_MIPS_LO16)<<16, MIPS | uint32(elf.R_MIPS_GOT16)<<16, + MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16, + MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16, MIPS | uint32(elf.R_MIPS_GPREL16)<<16, MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16, MIPS | uint32(elf.R_MIPS_JALR)<<16, @@ -970,6 +978,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { MIPS64 | uint32(elf.R_MIPS_HI16)<<16, MIPS64 | uint32(elf.R_MIPS_LO16)<<16, MIPS64 | uint32(elf.R_MIPS_GOT16)<<16, + MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16, + MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16, MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16, MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16, MIPS64 | uint32(elf.R_MIPS_JALR)<<16, @@ -1013,6 +1023,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16, ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16, + ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16, @@ -1056,6 +1067,27 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { S390X | uint32(elf.R_390_GOT64)<<16, S390X | uint32(elf.R_390_PLT64)<<16: return 8, nil + + case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16, + RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16: + return 2, nil + + case RISCV64 | uint32(elf.R_RISCV_32)<<16, + RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16, + RISCV64 | uint32(elf.R_RISCV_HI20)<<16, + RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16, + RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16, + RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16, + RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16, + RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16, + RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16, + RISCV64 | uint32(elf.R_RISCV_RELAX)<<16: + return 4, nil + + case RISCV64 | uint32(elf.R_RISCV_64)<<16, + RISCV64 | uint32(elf.R_RISCV_CALL)<<16, + RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16: + return 8, nil } } diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 8fd10b0848..971cc432ff 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -63,6 +63,7 @@ type Reloc struct { func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) + rel.typ } func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) } func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) } +func (rel Reloc) IsMarker() bool { return rel.Siz() == 0 } func (rel Reloc) SetType(t objabi.RelocType) { if t != objabi.RelocType(uint8(t)) { @@ -93,11 +94,12 @@ type oReader struct { version int // version of static symbol flags uint32 // read from object file pkgprefix string - syms []Sym // Sym's global index, indexed by local index - ndef int // cache goobj.Reader.NSym() - nhashed64def int // cache goobj.Reader.NHashed64Def() - nhasheddef int // cache goobj.Reader.NHashedDef() - objidx uint32 // index of this reader in the objs slice + syms []Sym // Sym's global index, indexed by local index + pkg []uint32 // indices of referenced package by PkgIdx (index into loader.objs array) + ndef int // cache goobj.Reader.NSym() + nhashed64def int // cache goobj.Reader.NHashed64Def() + nhasheddef int // cache goobj.Reader.NHashedDef() + objidx uint32 // index of this reader in the objs slice } // Total number of defined symbols (package symbols, hashed symbols, and @@ -219,7 +221,7 @@ type Loader struct { deferReturnTramp map[Sym]bool // whether the symbol is a trampoline of a deferreturn call - objByPkg map[string]*oReader // map package path to its Go object reader + objByPkg map[string]uint32 // map package path to the index of its Go object reader anonVersion int // most recently assigned ext static sym pseudo-version @@ -328,10 +330,10 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor ldr := &Loader{ start: make(map[*oReader]Sym), objs: []objIdx{{}, {extReader, 0}}, // reserve index 0 for nil symbol, 1 for external symbols - objSyms: make([]objSym, 1, 100000), // reserve index 0 for nil symbol + objSyms: make([]objSym, 1, 1), // This will get overwritten later. extReader: extReader, symsByName: [2]map[string]Sym{make(map[string]Sym, 80000), make(map[string]Sym, 50000)}, // preallocate ~2MB for ABI0 and ~1MB for ABI1 symbols - objByPkg: make(map[string]*oReader), + objByPkg: make(map[string]uint32), outer: make(map[Sym]Sym), sub: make(map[Sym]Sym), dynimplib: make(map[Sym]string), @@ -370,7 +372,7 @@ func (l *Loader) addObj(pkg string, r *oReader) Sym { } pkg = objabi.PathToPrefix(pkg) // the object file contains escaped package path if _, ok := l.objByPkg[pkg]; !ok { - l.objByPkg[pkg] = r + l.objByPkg[pkg] = r.objidx } i := Sym(len(l.objSyms)) l.start[r] = i @@ -631,20 +633,42 @@ func (l *Loader) resolve(r *oReader, s goobj.SymRef) Sym { i := int(s.SymIdx) + r.ndef + r.nhashed64def + r.nhasheddef return r.syms[i] case goobj.PkgIdxBuiltin: - return l.builtinSyms[s.SymIdx] + if bi := l.builtinSyms[s.SymIdx]; bi != 0 { + return bi + } + l.reportMissingBuiltin(int(s.SymIdx), r.unit.Lib.Pkg) + return 0 case goobj.PkgIdxSelf: rr = r default: - pkg := r.Pkg(int(p)) - var ok bool - rr, ok = l.objByPkg[pkg] - if !ok { - log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib) - } + rr = l.objs[r.pkg[p]].r } return l.toGlobal(rr, s.SymIdx) } +// reportMissingBuiltin issues an error in the case where we have a +// relocation against a runtime builtin whose definition is not found +// when the runtime package is built. The canonical example is +// "runtime.racefuncenter" -- currently if you do something like +// +// go build -gcflags=-race myprogram.go +// +// the compiler will insert calls to the builtin runtime.racefuncenter, +// but the version of the runtime used for linkage won't actually contain +// definitions of that symbol. See issue #42396 for details. +// +// As currently implemented, this is a fatal error. This has drawbacks +// in that if there are multiple missing builtins, the error will only +// cite the first one. On the plus side, terminating the link here has +// advantages in that we won't run the risk of panics or crashes later +// on in the linker due to R_CALL relocations with 0-valued target +// symbols. +func (l *Loader) reportMissingBuiltin(bsym int, reflib string) { + bname, _ := goobj.BuiltinName(bsym) + log.Fatalf("reference to undefined builtin %q from package %q", + bname, reflib) +} + // Look up a symbol by name, return global index, or 0 if not found. // This is more like Syms.ROLookup than Lookup -- it doesn't create // new symbol. @@ -1794,6 +1818,11 @@ func (l *Loader) SortSub(s Sym) Sym { return sl[0].s } +// SortSyms sorts a list of symbols by their value. +func (l *Loader) SortSyms(ss []Sym) { + sort.SliceStable(ss, func(i, j int) bool { return l.SymValue(ss[i]) < l.SymValue(ss[j]) }) +} + // Insure that reachable bitmap and its siblings have enough size. func (l *Loader) growAttrBitmaps(reqLen int) { if reqLen > l.attrReachable.Len() { @@ -1878,19 +1907,24 @@ func (fi *FuncInfo) FuncID() objabi.FuncID { return objabi.FuncID((*goobj.FuncInfo)(nil).ReadFuncID(fi.data)) } -func (fi *FuncInfo) Pcsp() []byte { - pcsp, end := (*goobj.FuncInfo)(nil).ReadPcsp(fi.data) - return fi.r.BytesAt(fi.r.PcdataBase()+pcsp, int(end-pcsp)) +func (fi *FuncInfo) Pcsp() Sym { + sym := (*goobj.FuncInfo)(nil).ReadPcsp(fi.data) + return fi.l.resolve(fi.r, sym) } -func (fi *FuncInfo) Pcfile() []byte { - pcf, end := (*goobj.FuncInfo)(nil).ReadPcfile(fi.data) - return fi.r.BytesAt(fi.r.PcdataBase()+pcf, int(end-pcf)) +func (fi *FuncInfo) Pcfile() Sym { + sym := (*goobj.FuncInfo)(nil).ReadPcfile(fi.data) + return fi.l.resolve(fi.r, sym) } -func (fi *FuncInfo) Pcline() []byte { - pcln, end := (*goobj.FuncInfo)(nil).ReadPcline(fi.data) - return fi.r.BytesAt(fi.r.PcdataBase()+pcln, int(end-pcln)) +func (fi *FuncInfo) Pcline() Sym { + sym := (*goobj.FuncInfo)(nil).ReadPcline(fi.data) + return fi.l.resolve(fi.r, sym) +} + +func (fi *FuncInfo) Pcinline() Sym { + sym := (*goobj.FuncInfo)(nil).ReadPcinline(fi.data) + return fi.l.resolve(fi.r, sym) } // Preload has to be called prior to invoking the various methods @@ -1899,27 +1933,16 @@ func (fi *FuncInfo) Preload() { fi.lengths = (*goobj.FuncInfo)(nil).ReadFuncInfoLengths(fi.data) } -func (fi *FuncInfo) Pcinline() []byte { - if !fi.lengths.Initialized { - panic("need to call Preload first") - } - pcinl, end := (*goobj.FuncInfo)(nil).ReadPcinline(fi.data, fi.lengths.PcdataOff) - return fi.r.BytesAt(fi.r.PcdataBase()+pcinl, int(end-pcinl)) -} - -func (fi *FuncInfo) NumPcdata() uint32 { +func (fi *FuncInfo) Pcdata() []Sym { if !fi.lengths.Initialized { panic("need to call Preload first") } - return fi.lengths.NumPcdata -} - -func (fi *FuncInfo) Pcdata(k int) []byte { - if !fi.lengths.Initialized { - panic("need to call Preload first") + syms := (*goobj.FuncInfo)(nil).ReadPcdata(fi.data) + ret := make([]Sym, len(syms)) + for i := range ret { + ret[i] = fi.l.resolve(fi.r, syms[i]) } - pcdat, end := (*goobj.FuncInfo)(nil).ReadPcdata(fi.data, fi.lengths.PcdataOff, uint32(k)) - return fi.r.BytesAt(fi.r.PcdataBase()+pcdat, int(end-pcdat)) + return ret } func (fi *FuncInfo) NumFuncdataoff() uint32 { @@ -2022,8 +2045,9 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo { return FuncInfo{} } -// Preload a package: add autolibs, add defined package symbols to the symbol table. -// Does not add non-package symbols yet, which will be done in LoadNonpkgSyms. +// Preload a package: adds autolib. +// Does not add defined package or non-packaged symbols to the symbol table. +// These are done in LoadSyms. // Does not read symbol data. // Returns the fingerprint of the object. func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj.FingerprintType { @@ -2066,8 +2090,6 @@ func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, u } l.addObj(lib.Pkg, or) - st := loadState{l: l} - st.preloadSyms(or, pkgDef) // The caller expects us consuming all the data f.MustSeek(length, os.SEEK_CUR) @@ -2150,17 +2172,30 @@ func (st *loadState) preloadSyms(r *oReader, kind int) { } } -// Add hashed (content-addressable) symbols, non-package symbols, and +// Add syms, hashed (content-addressable) symbols, non-package symbols, and // references to external symbols (which are always named). -func (l *Loader) LoadNonpkgSyms(arch *sys.Arch) { +func (l *Loader) LoadSyms(arch *sys.Arch) { + // Allocate space for symbols, making a guess as to how much space we need. + // This function was determined empirically by looking at the cmd/compile on + // Darwin, and picking factors for hashed and hashed64 syms. + var symSize, hashedSize, hashed64Size int + for _, o := range l.objs[goObjStart:] { + symSize += o.r.ndef + o.r.nhasheddef/2 + o.r.nhashed64def/2 + o.r.NNonpkgdef() + hashedSize += o.r.nhasheddef / 2 + hashed64Size += o.r.nhashed64def / 2 + } + // Index 0 is invalid for symbols. + l.objSyms = make([]objSym, 1, symSize) + l.npkgsyms = l.NSym() - // Preallocate some space (a few hundreds KB) for some symbols. - // As of Go 1.15, linking cmd/compile has ~8000 hashed64 symbols and - // ~13000 hashed symbols. st := loadState{ l: l, - hashed64Syms: make(map[uint64]symAndSize, 10000), - hashedSyms: make(map[goobj.HashType]symAndSize, 15000), + hashed64Syms: make(map[uint64]symAndSize, hashed64Size), + hashedSyms: make(map[goobj.HashType]symAndSize, hashedSize), + } + + for _, o := range l.objs[goObjStart:] { + st.preloadSyms(o.r, pkgDef) } for _, o := range l.objs[goObjStart:] { st.preloadSyms(o.r, hashed64Def) @@ -2195,6 +2230,18 @@ func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) { } } + // referenced packages + npkg := r.NPkg() + r.pkg = make([]uint32, npkg) + for i := 1; i < npkg; i++ { // PkgIdx 0 is a dummy invalid package + pkg := r.Pkg(i) + objidx, ok := l.objByPkg[pkg] + if !ok { + log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib) + } + r.pkg[i] = objidx + } + // load flags of package refs for i, n := 0, r.NRefFlags(); i < n; i++ { rf := r.RefFlags(i) @@ -2602,11 +2649,15 @@ func (l *Loader) Dump() { fmt.Println("Nsyms:", len(l.objSyms)) fmt.Println("syms") for i := Sym(1); i < Sym(len(l.objSyms)); i++ { - pi := interface{}("") + pi := "" if l.IsExternal(i) { pi = fmt.Sprintf("<ext %d>", l.extIndex(i)) } - fmt.Println(i, l.SymName(i), l.SymType(i), pi) + sect := "" + if l.SymSect(i) != nil { + sect = l.SymSect(i).Name + } + fmt.Printf("%v %v %v %v %x %v\n", i, l.SymName(i), l.SymType(i), pi, l.SymValue(i), sect) } fmt.Println("symsByName") for name, i := range l.symsByName[0] { diff --git a/src/cmd/link/internal/loader/symbolbuilder.go b/src/cmd/link/internal/loader/symbolbuilder.go index e14d89a927..5d37da8ac6 100644 --- a/src/cmd/link/internal/loader/symbolbuilder.go +++ b/src/cmd/link/internal/loader/symbolbuilder.go @@ -336,6 +336,15 @@ func (sb *SymbolBuilder) Addstring(str string) int64 { return r } +func (sb *SymbolBuilder) SetBytesAt(off int64, b []byte) int64 { + datLen := int64(len(b)) + if off+datLen > int64(len(sb.data)) { + panic("attempt to write past end of buffer") + } + copy(sb.data[off:off+datLen], b) + return off + datLen +} + func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 { if sb.kind == 0 { sb.kind = sym.SDATA @@ -411,3 +420,21 @@ func (sb *SymbolBuilder) MakeWritable() { sb.l.SetAttrReadOnly(sb.symIdx, false) } } + +func (sb *SymbolBuilder) AddUleb(v uint64) { + if v < 128 { // common case: 1 byte + sb.AddUint8(uint8(v)) + return + } + for { + c := uint8(v & 0x7f) + v >>= 7 + if v != 0 { + c |= 0x80 + } + sb.AddUint8(c) + if c&0x80 == 0 { + break + } + } +} diff --git a/src/cmd/link/internal/loadmacho/ldmacho.go b/src/cmd/link/internal/loadmacho/ldmacho.go index 864d80835b..6d1d9bb29e 100644 --- a/src/cmd/link/internal/loadmacho/ldmacho.go +++ b/src/cmd/link/internal/loadmacho/ldmacho.go @@ -43,11 +43,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld +// TODO(crawshaw): de-duplicate these symbols with cmd/link/internal/ld const ( MACHO_X86_64_RELOC_UNSIGNED = 0 MACHO_X86_64_RELOC_SIGNED = 1 - MACHO_FAKE_GOTPCREL = 100 + MACHO_ARM64_RELOC_ADDEND = 10 ) type ldMachoObj struct { @@ -172,11 +172,12 @@ const ( LdMachoCpuVax = 1 LdMachoCpu68000 = 6 LdMachoCpu386 = 7 - LdMachoCpuAmd64 = 0x1000007 + LdMachoCpuAmd64 = 1<<24 | 7 LdMachoCpuMips = 8 LdMachoCpu98000 = 10 LdMachoCpuHppa = 11 LdMachoCpuArm = 12 + LdMachoCpuArm64 = 1<<24 | 12 LdMachoCpu88000 = 13 LdMachoCpuSparc = 14 LdMachoCpu860 = 15 @@ -471,11 +472,14 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, switch arch.Family { default: return errorf("mach-o %s unimplemented", arch.Name) - case sys.AMD64: if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 { return errorf("mach-o object but not amd64") } + case sys.ARM64: + if e != binary.LittleEndian || m.cputype != LdMachoCpuArm64 { + return errorf("mach-o object but not arm64") + } } m.cmd = make([]ldMachoCmd, ncmd) @@ -633,7 +637,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, } bld.SetType(l.SymType(outer)) - l.AddInteriorSym(outer, s) + if l.SymSize(outer) != 0 { // skip empty section (0-sized symbol) + l.AddInteriorSym(outer, s) + } bld.SetValue(int64(machsym.value - sect.addr)) if !l.AttrCgoExportDynamic(s) { @@ -701,11 +707,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, } sb := l.MakeSymbolUpdater(sect.sym) + var rAdd int64 for j := uint32(0); j < sect.nreloc; j++ { var ( rOff int32 rSize uint8 - rAdd int64 rType objabi.RelocType rSym loader.Sym ) @@ -716,33 +722,40 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, return errorf("%v: unexpected scattered relocation", s) } + if arch.Family == sys.ARM64 && rel.type_ == MACHO_ARM64_RELOC_ADDEND { + // Two relocations. This addend will be applied to the next one. + rAdd = int64(rel.symnum) << 40 >> 40 // convert unsigned 24-bit to signed 24-bit + continue + } + rSize = rel.length rType = objabi.MachoRelocOffset + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel) rOff = int32(rel.addr) // Handle X86_64_RELOC_SIGNED referencing a section (rel.extrn == 0). p := l.Data(s) - if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED { - // Calculate the addend as the offset into the section. - // - // The rip-relative offset stored in the object file is encoded - // as follows: - // - // movsd 0x00000360(%rip),%xmm0 - // - // To get the absolute address of the value this rip-relative address is pointing - // to, we must add the address of the next instruction to it. This is done by - // taking the address of the relocation and adding 4 to it (since the rip-relative - // offset can at most be 32 bits long). To calculate the offset into the section the - // relocation is referencing, we subtract the vaddr of the start of the referenced - // section found in the original object file. - // - // [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h] - secaddr := c.seg.sect[rel.symnum-1].addr - - rAdd = int64(uint64(int64(int32(e.Uint32(p[rOff:])))+int64(rOff)+4) - secaddr) - } else { - rAdd = int64(int32(e.Uint32(p[rOff:]))) + if arch.Family == sys.AMD64 { + if rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED { + // Calculate the addend as the offset into the section. + // + // The rip-relative offset stored in the object file is encoded + // as follows: + // + // movsd 0x00000360(%rip),%xmm0 + // + // To get the absolute address of the value this rip-relative address is pointing + // to, we must add the address of the next instruction to it. This is done by + // taking the address of the relocation and adding 4 to it (since the rip-relative + // offset can at most be 32 bits long). To calculate the offset into the section the + // relocation is referencing, we subtract the vaddr of the start of the referenced + // section found in the original object file. + // + // [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h] + secaddr := c.seg.sect[rel.symnum-1].addr + rAdd = int64(uint64(int64(int32(e.Uint32(p[rOff:])))+int64(rOff)+4) - secaddr) + } else { + rAdd = int64(int32(e.Uint32(p[rOff:]))) + } } // An unsigned internal relocation has a value offset @@ -774,6 +787,8 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, r.SetSiz(rSize) r.SetSym(rSym) r.SetAdd(rAdd) + + rAdd = 0 // clear rAdd for next iteration } sb.SortRelocs() diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go index d2dc20f5c1..01d89a209c 100644 --- a/src/cmd/link/internal/mips64/obj.go +++ b/src/cmd/link/internal/mips64/obj.go @@ -60,7 +60,7 @@ func Init() (*sys.Arch, ld.Arch) { Linuxdynld: "/lib64/ld64.so.1", Freebsddynld: "XXX", - Openbsddynld: "XXX", + Openbsddynld: "/usr/libexec/ld.so", Netbsddynld: "XXX", Dragonflydynld: "XXX", Solarisdynld: "XXX", @@ -84,7 +84,8 @@ func archinit(ctxt *ld.Link) { *ld.FlagRound = 16 * 1024 } - case objabi.Hlinux: /* mips64 elf */ + case objabi.Hlinux, /* mips64 elf */ + objabi.Hopenbsd: ld.Elfinit(ctxt) ld.HEADR = ld.ELFRESERVE if *ld.FlagTextAddr == -1 { diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index dc522e6a38..5bf3898eb9 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -313,7 +313,7 @@ func addelfdynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s lo rela := ldr.MakeSymbolUpdater(syms.Rela) rela.AddAddrPlus(target.Arch, s, int64(r.Off())) - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_PPC64_ADDR64))) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_PPC64_ADDR64))) rela.AddUint64(target.Arch, uint64(r.Add())) su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym } @@ -994,9 +994,10 @@ func addpltsym(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym) { ldr.SetPlt(s, int32(plt.Size())) plt.Grow(plt.Size() + 8) + plt.SetSize(plt.Size() + 8) rela.AddAddrPlus(ctxt.Arch, plt.Sym(), int64(ldr.SymPlt(s))) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_PPC64_JMP_SLOT))) + rela.AddUint64(ctxt.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_PPC64_JMP_SLOT))) rela.AddUint64(ctxt.Arch, 0) } else { ctxt.Errorf(s, "addpltsym: unsupported binary format") @@ -1052,7 +1053,7 @@ func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilde // Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes // before the first symbol resolver stub. du := ldr.MakeSymbolUpdater(ctxt.Dynamic) - ld.Elfwritedynentsymplus(ctxt, du, ld.DT_PPC64_GLINK, glink.Sym(), glink.Size()-32) + ld.Elfwritedynentsymplus(ctxt, du, elf.DT_PPC64_GLINK, glink.Sym(), glink.Size()-32) return glink } diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go index 1236145fb1..c18e0540d8 100644 --- a/src/cmd/link/internal/riscv64/asm.go +++ b/src/cmd/link/internal/riscv64/asm.go @@ -11,20 +11,143 @@ import ( "cmd/link/internal/ld" "cmd/link/internal/loader" "cmd/link/internal/sym" + "debug/elf" "fmt" "log" + "sort" ) +// fakeLabelName matches the RISCV_FAKE_LABEL_NAME from binutils. +const fakeLabelName = ".L0 " + func gentext(ctxt *ld.Link, ldr *loader.Loader) { } +func genSymsLate(ctxt *ld.Link, ldr *loader.Loader) { + if ctxt.LinkMode != ld.LinkExternal { + return + } + + // Generate a local text symbol for each relocation target, as the + // R_RISCV_PCREL_LO12_* relocations generated by elfreloc1 need it. + if ctxt.Textp == nil { + log.Fatal("genSymsLate called before Textp has been assigned") + } + var hi20Syms []loader.Sym + for _, s := range ctxt.Textp { + relocs := ldr.Relocs(s) + for ri := 0; ri < relocs.Count(); ri++ { + r := relocs.At(ri) + if r.Type() != objabi.R_RISCV_PCREL_ITYPE && r.Type() != objabi.R_RISCV_PCREL_STYPE && + r.Type() != objabi.R_RISCV_TLS_IE_ITYPE && r.Type() != objabi.R_RISCV_TLS_IE_STYPE { + continue + } + if r.Off() == 0 && ldr.SymType(s) == sym.STEXT { + // Use the symbol for the function instead of creating + // an overlapping symbol. + continue + } + + // TODO(jsing): Consider generating ELF symbols without needing + // loader symbols, in order to reduce memory consumption. This + // would require changes to genelfsym so that it called + // putelfsym and putelfsyment as appropriate. + sb := ldr.MakeSymbolBuilder(fakeLabelName) + sb.SetType(sym.STEXT) + sb.SetValue(ldr.SymValue(s) + int64(r.Off())) + sb.SetLocal(true) + sb.SetReachable(true) + sb.SetVisibilityHidden(true) + sb.SetSect(ldr.SymSect(s)) + if outer := ldr.OuterSym(s); outer != 0 { + ldr.AddInteriorSym(outer, sb.Sym()) + } + hi20Syms = append(hi20Syms, sb.Sym()) + } + } + ctxt.Textp = append(ctxt.Textp, hi20Syms...) + ldr.SortSyms(ctxt.Textp) +} + +func findHI20Symbol(ctxt *ld.Link, ldr *loader.Loader, val int64) loader.Sym { + idx := sort.Search(len(ctxt.Textp), func(i int) bool { return ldr.SymValue(ctxt.Textp[i]) >= val }) + if idx >= len(ctxt.Textp) { + return 0 + } + if s := ctxt.Textp[idx]; ldr.SymValue(s) == val && ldr.SymType(s) == sym.STEXT { + return s + } + return 0 +} + func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool { - log.Fatalf("elfreloc1") - return false + elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) + switch r.Type { + case objabi.R_ADDR, objabi.R_DWARFSECREF: + out.Write64(uint64(sectoff)) + switch r.Size { + case 4: + out.Write64(uint64(elf.R_RISCV_32) | uint64(elfsym)<<32) + case 8: + out.Write64(uint64(elf.R_RISCV_64) | uint64(elfsym)<<32) + default: + ld.Errorf(nil, "unknown size %d for %v relocation", r.Size, r.Type) + return false + } + out.Write64(uint64(r.Xadd)) + + case objabi.R_CALLRISCV: + // Call relocations are currently handled via R_RISCV_PCREL_ITYPE. + // TODO(jsing): Consider generating elf.R_RISCV_CALL instead of a + // HI20/LO12_I pair. + + case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE: + // Find the text symbol for the AUIPC instruction targeted + // by this relocation. + relocs := ldr.Relocs(s) + offset := int64(relocs.At(ri).Off()) + hi20Sym := findHI20Symbol(ctxt, ldr, ldr.SymValue(s)+offset) + if hi20Sym == 0 { + ld.Errorf(nil, "failed to find text symbol for HI20 relocation at %d (%x)", sectoff, ldr.SymValue(s)+offset) + return false + } + hi20ElfSym := ld.ElfSymForReloc(ctxt, hi20Sym) + + // Emit two relocations - a R_RISCV_PCREL_HI20 relocation and a + // corresponding R_RISCV_PCREL_LO12_I or R_RISCV_PCREL_LO12_S relocation. + // Note that the LO12 relocation must point to a target that has a valid + // HI20 PC-relative relocation text symbol, which in turn points to the + // given symbol. For further details see the ELF specification for RISC-V: + // + // https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses + // + var hiRel, loRel elf.R_RISCV + switch r.Type { + case objabi.R_RISCV_PCREL_ITYPE: + hiRel, loRel = elf.R_RISCV_PCREL_HI20, elf.R_RISCV_PCREL_LO12_I + case objabi.R_RISCV_PCREL_STYPE: + hiRel, loRel = elf.R_RISCV_PCREL_HI20, elf.R_RISCV_PCREL_LO12_S + case objabi.R_RISCV_TLS_IE_ITYPE: + hiRel, loRel = elf.R_RISCV_TLS_GOT_HI20, elf.R_RISCV_PCREL_LO12_I + case objabi.R_RISCV_TLS_IE_STYPE: + hiRel, loRel = elf.R_RISCV_TLS_GOT_HI20, elf.R_RISCV_PCREL_LO12_S + } + out.Write64(uint64(sectoff)) + out.Write64(uint64(hiRel) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) + out.Write64(uint64(sectoff + 4)) + out.Write64(uint64(loRel) | uint64(hi20ElfSym)<<32) + out.Write64(uint64(0)) + + default: + return false + } + + return true } func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) { - log.Fatalf("elfsetuplt") + log.Fatalf("elfsetupplt") } func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool { @@ -33,13 +156,35 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe } func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (o int64, nExtReloc int, ok bool) { - rs := r.Sym() - rs = ldr.ResolveABIAlias(rs) + if target.IsExternal() { + switch r.Type() { + case objabi.R_CALLRISCV: + return val, 0, true + + case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE: + return val, 2, true + } + + return val, 0, false + } + + rs := ldr.ResolveABIAlias(r.Sym()) + switch r.Type() { case objabi.R_CALLRISCV: // Nothing to do. return val, 0, true + case objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE: + // TLS relocations are not currently handled for internal linking. + // For now, TLS is only used when cgo is in use and cgo currently + // requires external linking. However, we need to accept these + // relocations so that code containing TLS variables will link, + // even when they're not being used. For now, replace these + // instructions with EBREAK to detect accidental use. + const ebreakIns = 0x00100073 + return ebreakIns<<32 | ebreakIns, 0, true + case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE: pc := ldr.SymValue(s) + int64(r.Off()) off := ldr.SymValue(rs) + r.Add() - pc @@ -89,3 +234,11 @@ func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant log.Fatalf("archrelocvariant") return -1 } + +func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) { + switch r.Type() { + case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE: + return ld.ExtrelocViaOuterSym(ldr, r, s), true + } + return loader.ExtReloc{}, false +} diff --git a/src/cmd/link/internal/riscv64/obj.go b/src/cmd/link/internal/riscv64/obj.go index e66d3cd856..917324d922 100644 --- a/src/cmd/link/internal/riscv64/obj.go +++ b/src/cmd/link/internal/riscv64/obj.go @@ -23,9 +23,12 @@ func Init() (*sys.Arch, ld.Arch) { Archinit: archinit, Archreloc: archreloc, Archrelocvariant: archrelocvariant, + Extreloc: extreloc, Elfreloc1: elfreloc1, + ElfrelocSize: 24, Elfsetupplt: elfsetupplt, Gentext: gentext, + GenSymsLate: genSymsLate, Machoreloc1: machoreloc1, Linuxdynld: "/lib/ld.so.1", diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 645b7d4e28..78d2cc81e4 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -444,7 +444,7 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rela.AddAddrPlus(target.Arch, got.Sym(), got.Size()-8) sDynid := ldr.SymDynid(s) - rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(sDynid), uint32(elf.R_390_JMP_SLOT))) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_390_JMP_SLOT))) rela.AddUint64(target.Arch, 0) ldr.SetPlt(s, int32(plt.Size()-32)) diff --git a/src/cmd/link/internal/sym/symbol.go b/src/cmd/link/internal/sym/symbol.go index 1a4165ebf7..70cf36a87e 100644 --- a/src/cmd/link/internal/sym/symbol.go +++ b/src/cmd/link/internal/sym/symbol.go @@ -33,7 +33,3 @@ func VersionToABI(v int) (obj.ABI, bool) { } return ^obj.ABI(0), false } - -type Pcdata struct { - P []byte -} diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go index 3bd56a6e3a..31851fbb56 100644 --- a/src/cmd/link/internal/wasm/asm.go +++ b/src/cmd/link/internal/wasm/asm.go @@ -167,6 +167,9 @@ func asmb2(ctxt *ld.Link, ldr *loader.Loader) { off := int32(0) for ri := 0; ri < relocs.Count(); ri++ { r := relocs.At(ri) + if r.Siz() == 0 { + continue // skip marker relocations + } wfn.Write(P[off:r.Off()]) off = r.Off() rs := ldr.ResolveABIAlias(r.Sym()) diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 9b949ebbf8..af0ce11255 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -303,7 +303,7 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade ld.Adddynsym(ldr, target, syms, targ) rel := ldr.MakeSymbolUpdater(syms.Rel) rel.AddAddrPlus(target.Arch, s, int64(r.Off())) - rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_386_32))) + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(targ)), uint32(elf.R_386_32))) su := ldr.MakeSymbolUpdater(s) su.SetRelocType(rIdx, objabi.R_CONST) // write r->add during relocsym su.SetRelocSym(rIdx, 0) @@ -483,7 +483,7 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade rel.AddAddrPlus(target.Arch, got.Sym(), got.Size()-4) sDynid := ldr.SymDynid(s) - rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(sDynid), uint32(elf.R_386_JMP_SLOT))) + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(sDynid), uint32(elf.R_386_JMP_SLOT))) ldr.SetPlt(s, int32(plt.Size()-16)) } else { diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index 72ff01c932..158c670739 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -1,8 +1,13 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package main import ( "bufio" "bytes" + "cmd/internal/sys" "debug/macho" "internal/testenv" "io/ioutil" @@ -177,6 +182,7 @@ main.x: relocation target main.zero not defined func TestIssue33979(t *testing.T) { testenv.MustHaveGoBuild(t) testenv.MustHaveCGO(t) + testenv.MustInternalLink(t) // Skip test on platforms that do not support cgo internal linking. switch runtime.GOARCH { @@ -304,7 +310,7 @@ func TestBuildForTvOS(t *testing.T) { cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", ar, lib) cmd.Env = append(os.Environ(), "CGO_ENABLED=1", - "GOOS=darwin", + "GOOS=ios", "GOARCH=arm64", "CC="+strings.Join(CC, " "), "CGO_CFLAGS=", // ensure CGO_CFLAGS does not contain any flags. Issue #35459 @@ -591,7 +597,12 @@ func TestFuncAlign(t *testing.T) { } defer os.RemoveAll(tmpdir) - src := filepath.Join(tmpdir, "falign.go") + src := filepath.Join(tmpdir, "go.mod") + err = ioutil.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666) + if err != nil { + t.Fatal(err) + } + src = filepath.Join(tmpdir, "falign.go") err = ioutil.WriteFile(src, []byte(testFuncAlignSrc), 0666) if err != nil { t.Fatal(err) @@ -796,3 +807,121 @@ func TestContentAddressableSymbols(t *testing.T) { t.Errorf("command %s failed: %v\n%s", cmd, err, out) } } + +func TestReadOnly(t *testing.T) { + // Test that read-only data is indeed read-only. + testenv.MustHaveGoBuild(t) + + t.Parallel() + + src := filepath.Join("testdata", "testRO", "x.go") + cmd := exec.Command(testenv.GoToolPath(t), "run", src) + out, err := cmd.CombinedOutput() + if err == nil { + t.Errorf("running test program did not fail. output:\n%s", out) + } +} + +const testIssue38554Src = ` +package main + +type T [10<<20]byte + +//go:noinline +func f() T { + return T{} // compiler will make a large stmp symbol, but not used. +} + +func main() { + x := f() + println(x[1]) +} +` + +func TestIssue38554(t *testing.T) { + testenv.MustHaveGoBuild(t) + + t.Parallel() + + tmpdir, err := ioutil.TempDir("", "TestIssue38554") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "x.go") + err = ioutil.WriteFile(src, []byte(testIssue38554Src), 0666) + if err != nil { + t.Fatalf("failed to write source file: %v", err) + } + exe := filepath.Join(tmpdir, "x.exe") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("build failed: %v\n%s", err, out) + } + + fi, err := os.Stat(exe) + if err != nil { + t.Fatalf("failed to stat output file: %v", err) + } + + // The test program is not much different from a helloworld, which is + // typically a little over 1 MB. We allow 5 MB. If the bad stmp is live, + // it will be over 10 MB. + const want = 5 << 20 + if got := fi.Size(); got > want { + t.Errorf("binary too big: got %d, want < %d", got, want) + } +} + +const testIssue42396src = ` +package main + +//go:noinline +//go:nosplit +func callee(x int) { +} + +func main() { + callee(9) +} +` + +func TestIssue42396(t *testing.T) { + testenv.MustHaveGoBuild(t) + + if !sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) { + t.Skip("no race detector support") + } + + t.Parallel() + + tmpdir, err := ioutil.TempDir("", "TestIssue42396") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "main.go") + err = ioutil.WriteFile(src, []byte(testIssue42396src), 0666) + if err != nil { + t.Fatalf("failed to write source file: %v", err) + } + exe := filepath.Join(tmpdir, "main.exe") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-race", "-o", exe, src) + out, err := cmd.CombinedOutput() + if err == nil { + t.Fatalf("build unexpectedly succeeded") + } + + // Check to make sure that we see a reasonable error message + // and not a panic. + if strings.Contains(string(out), "panic:") { + t.Fatalf("build should not fail with panic:\n%s", out) + } + const want = "reference to undefined builtin" + if !strings.Contains(string(out), want) { + t.Fatalf("error message incorrect: expected it to contain %q but instead got:\n%s\n", want, out) + } +} diff --git a/src/cmd/link/testdata/testRO/x.go b/src/cmd/link/testdata/testRO/x.go new file mode 100644 index 0000000000..d77db6d563 --- /dev/null +++ b/src/cmd/link/testdata/testRO/x.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that read-only data is indeed read-only. This +// program attempts to modify read-only data, and it +// should fail. + +package main + +import "unsafe" + +var s = "hello" + +func main() { + println(s) + *(*struct { + p *byte + l int + })(unsafe.Pointer(&s)).p = 'H' + println(s) +} diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go index 9a257e0ed2..e0414e6b22 100644 --- a/src/cmd/nm/nm_cgo_test.go +++ b/src/cmd/nm/nm_cgo_test.go @@ -24,7 +24,7 @@ func canInternalLink() bool { } case "linux": switch runtime.GOARCH { - case "arm64", "mips64", "mips64le", "mips", "mipsle", "ppc64", "ppc64le": + case "arm64", "mips64", "mips64le", "mips", "mipsle", "ppc64", "ppc64le", "riscv64": return false } case "openbsd": diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go index 5d7fff0f99..0d51b07a44 100644 --- a/src/cmd/nm/nm_test.go +++ b/src/cmd/nm/nm_test.go @@ -8,7 +8,6 @@ import ( "fmt" "internal/obscuretestdata" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -31,7 +30,7 @@ func testMain(m *testing.M) int { return 0 } - tmpDir, err := ioutil.TempDir("", "TestNM") + tmpDir, err := os.MkdirTemp("", "TestNM") if err != nil { fmt.Println("TempDir failed:", err) return 2 @@ -88,7 +87,7 @@ func TestNonGoExecs(t *testing.T) { func testGoExec(t *testing.T, iscgo, isexternallinker bool) { t.Parallel() - tmpdir, err := ioutil.TempDir("", "TestGoExec") + tmpdir, err := os.MkdirTemp("", "TestGoExec") if err != nil { t.Fatal(err) } @@ -173,6 +172,9 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) { if runtime.GOOS == "windows" { return true } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + return true // On darwin/arm64 everything is PIE + } return false } @@ -219,7 +221,7 @@ func TestGoExec(t *testing.T) { func testGoLib(t *testing.T, iscgo bool) { t.Parallel() - tmpdir, err := ioutil.TempDir("", "TestGoLib") + tmpdir, err := os.MkdirTemp("", "TestGoLib") if err != nil { t.Fatal(err) } @@ -242,7 +244,7 @@ func testGoLib(t *testing.T, iscgo bool) { err = e } if err == nil { - err = ioutil.WriteFile(filepath.Join(libpath, "go.mod"), []byte("module mylib\n"), 0666) + err = os.WriteFile(filepath.Join(libpath, "go.mod"), []byte("module mylib\n"), 0666) } if err != nil { t.Fatal(err) @@ -283,7 +285,7 @@ func testGoLib(t *testing.T, iscgo bool) { if iscgo { syms = append(syms, symType{"B", "mylib.TestCgodata", false, false}) syms = append(syms, symType{"T", "mylib.TestCgofunc", false, false}) - if runtime.GOOS == "darwin" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") { + if runtime.GOOS == "darwin" || runtime.GOOS == "ios" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") { syms = append(syms, symType{"D", "_cgodata", true, false}) syms = append(syms, symType{"T", "_cgofunc", true, false}) } else if runtime.GOOS == "aix" { diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index 85d1a2efb0..edaca774f7 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -10,7 +10,6 @@ import ( "fmt" "go/build" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -39,7 +38,7 @@ func TestMain(m *testing.M) { func buildObjdump() error { var err error - tmp, err = ioutil.TempDir("", "TestObjDump") + tmp, err = os.MkdirTemp("", "TestObjDump") if err != nil { return fmt.Errorf("TempDir failed: %v", err) } @@ -106,6 +105,17 @@ var ppcGnuNeed = []string{ "cmpw", } +func mustHaveDisasm(t *testing.T) { + switch runtime.GOARCH { + case "mips", "mipsle", "mips64", "mips64le": + t.Skipf("skipping on %s, issue 12559", runtime.GOARCH) + case "riscv64": + t.Skipf("skipping on %s, issue 36738", runtime.GOARCH) + case "s390x": + t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) + } +} + var target = flag.String("target", "", "test disassembly of `goos/goarch` binary") // objdump is fully cross platform: it can handle binaries @@ -118,6 +128,7 @@ var target = flag.String("target", "", "test disassembly of `goos/goarch` binary // can handle that one. func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool, flags ...string) { + mustHaveDisasm(t) goarch := runtime.GOARCH if *target != "" { f := strings.Split(*target, "/") @@ -227,71 +238,38 @@ func testGoAndCgoDisasm(t *testing.T, printCode bool, printGnuAsm bool) { testDisasm(t, "fmthello.go", printCode, printGnuAsm) if build.Default.CgoEnabled { if runtime.GOOS == "aix" { - t.Skipf("skipping on %s, issue 40972", runtime.GOOS) + return // issue 40972 } testDisasm(t, "fmthellocgo.go", printCode, printGnuAsm) } } func TestDisasm(t *testing.T) { - switch runtime.GOARCH { - case "mips", "mipsle", "mips64", "mips64le": - t.Skipf("skipping on %s, issue 12559", runtime.GOARCH) - case "riscv64": - t.Skipf("skipping on %s, issue 36738", runtime.GOARCH) - case "s390x": - t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) - } testGoAndCgoDisasm(t, false, false) } func TestDisasmCode(t *testing.T) { - switch runtime.GOARCH { - case "mips", "mipsle", "mips64", "mips64le", "riscv64", "s390x": - t.Skipf("skipping on %s, issue 19160", runtime.GOARCH) - } testGoAndCgoDisasm(t, true, false) } func TestDisasmGnuAsm(t *testing.T) { - switch runtime.GOARCH { - case "mips", "mipsle", "mips64", "mips64le", "riscv64", "s390x": - t.Skipf("skipping on %s, issue 19160", runtime.GOARCH) - } testGoAndCgoDisasm(t, false, true) } func TestDisasmExtld(t *testing.T) { + testenv.MustHaveCGO(t) switch runtime.GOOS { case "plan9", "windows": t.Skipf("skipping on %s", runtime.GOOS) - } - switch runtime.GOARCH { - case "ppc64": - t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH) - case "mips64", "mips64le", "mips", "mipsle": - t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH) - case "riscv64": - t.Skipf("skipping on %s, no support for external linking, issue 36739", runtime.GOARCH) - case "s390x": - t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) - } - if !build.Default.CgoEnabled { - t.Skip("skipping because cgo is not enabled") + case "aix": + t.Skipf("skipping on AIX, see issue 40972") } t.Parallel() testDisasm(t, "fmthello.go", false, false, "-ldflags=-linkmode=external") } func TestDisasmGoobj(t *testing.T) { - switch runtime.GOARCH { - case "mips", "mipsle", "mips64", "mips64le": - t.Skipf("skipping on %s, issue 12559", runtime.GOARCH) - case "riscv64": - t.Skipf("skipping on %s, issue 36738", runtime.GOARCH) - case "s390x": - t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) - } + mustHaveDisasm(t) hello := filepath.Join(tmp, "hello.o") args := []string{"tool", "compile", "-o", hello} @@ -333,3 +311,42 @@ func TestDisasmGoobj(t *testing.T) { t.Logf("full disassembly:\n%s", text) } } + +func TestGoobjFileNumber(t *testing.T) { + // Test that file table in Go object file is parsed correctly. + testenv.MustHaveGoBuild(t) + mustHaveDisasm(t) + + t.Parallel() + + tmpdir, err := os.MkdirTemp("", "TestGoobjFileNumber") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + obj := filepath.Join(tmpdir, "p.a") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", obj) + cmd.Dir = filepath.Join("testdata/testfilenum") + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("build failed: %v\n%s", err, out) + } + + cmd = exec.Command(exe, obj) + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("objdump failed: %v\n%s", err, out) + } + + text := string(out) + for _, s := range []string{"a.go", "b.go", "c.go"} { + if !strings.Contains(text, s) { + t.Errorf("output missing '%s'", s) + } + } + + if t.Failed() { + t.Logf("output:\n%s", text) + } +} diff --git a/src/cmd/objdump/testdata/testfilenum/a.go b/src/cmd/objdump/testdata/testfilenum/a.go new file mode 100644 index 0000000000..2729ae0abf --- /dev/null +++ b/src/cmd/objdump/testdata/testfilenum/a.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func A() {} diff --git a/src/cmd/objdump/testdata/testfilenum/b.go b/src/cmd/objdump/testdata/testfilenum/b.go new file mode 100644 index 0000000000..a632aafe7b --- /dev/null +++ b/src/cmd/objdump/testdata/testfilenum/b.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func B() {} diff --git a/src/cmd/objdump/testdata/testfilenum/c.go b/src/cmd/objdump/testdata/testfilenum/c.go new file mode 100644 index 0000000000..d73efa7315 --- /dev/null +++ b/src/cmd/objdump/testdata/testfilenum/c.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +func C() {} diff --git a/src/cmd/objdump/testdata/testfilenum/go.mod b/src/cmd/objdump/testdata/testfilenum/go.mod new file mode 100644 index 0000000000..db432883a9 --- /dev/null +++ b/src/cmd/objdump/testdata/testfilenum/go.mod @@ -0,0 +1,3 @@ +module objdumptest + +go 1.16 diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go index c4e116becd..82546ea7dc 100644 --- a/src/cmd/pack/pack.go +++ b/src/cmd/pack/pack.go @@ -8,6 +8,7 @@ import ( "cmd/internal/archive" "fmt" "io" + "io/fs" "log" "os" "path/filepath" @@ -221,7 +222,7 @@ func (ar *Archive) addFiles() { // FileLike abstracts the few methods we need, so we can test without needing real files. type FileLike interface { Name() string - Stat() (os.FileInfo, error) + Stat() (fs.FileInfo, error) Read([]byte) (int, error) Close() error } diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go index 2108330742..218c7acda6 100644 --- a/src/cmd/pack/pack_test.go +++ b/src/cmd/pack/pack_test.go @@ -11,7 +11,7 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" + "io/fs" "os" "os/exec" "path/filepath" @@ -21,7 +21,7 @@ import ( // tmpDir creates a temporary directory and returns its name. func tmpDir(t *testing.T) string { - name, err := ioutil.TempDir("", "pack") + name, err := os.MkdirTemp("", "pack") if err != nil { t.Fatal(err) } @@ -157,7 +157,7 @@ func TestExtract(t *testing.T) { ar = openArchive(name, os.O_RDONLY, []string{goodbyeFile.name}) ar.scan(ar.extractContents) ar.a.File().Close() - data, err := ioutil.ReadFile(goodbyeFile.name) + data, err := os.ReadFile(goodbyeFile.name) if err != nil { t.Fatal(err) } @@ -182,7 +182,7 @@ func TestHello(t *testing.T) { println("hello world") } ` - err := ioutil.WriteFile(hello, []byte(prog), 0666) + err := os.WriteFile(hello, []byte(prog), 0666) if err != nil { t.Fatal(err) } @@ -250,7 +250,7 @@ func TestLargeDefs(t *testing.T) { println("ok") } ` - err = ioutil.WriteFile(main, []byte(prog), 0666) + err = os.WriteFile(main, []byte(prog), 0666) if err != nil { t.Fatal(err) } @@ -280,13 +280,13 @@ func TestIssue21703(t *testing.T) { defer os.RemoveAll(dir) const aSrc = `package a; const X = "\n!\n"` - err := ioutil.WriteFile(filepath.Join(dir, "a.go"), []byte(aSrc), 0666) + err := os.WriteFile(filepath.Join(dir, "a.go"), []byte(aSrc), 0666) if err != nil { t.Fatal(err) } const bSrc = `package b; import _ "a"` - err = ioutil.WriteFile(filepath.Join(dir, "b.go"), []byte(bSrc), 0666) + err = os.WriteFile(filepath.Join(dir, "b.go"), []byte(bSrc), 0666) if err != nil { t.Fatal(err) } @@ -327,11 +327,11 @@ var goodbyeFile = &FakeFile{ mode: 0644, } -// FakeFile implements FileLike and also os.FileInfo. +// FakeFile implements FileLike and also fs.FileInfo. type FakeFile struct { name string contents string - mode os.FileMode + mode fs.FileMode offset int } @@ -348,7 +348,7 @@ func (f *FakeFile) Name() string { return f.name } -func (f *FakeFile) Stat() (os.FileInfo, error) { +func (f *FakeFile) Stat() (fs.FileInfo, error) { return f, nil } @@ -365,13 +365,13 @@ func (f *FakeFile) Close() error { return nil } -// os.FileInfo methods. +// fs.FileInfo methods. func (f *FakeFile) Size() int64 { return int64(len(f.contents)) } -func (f *FakeFile) Mode() os.FileMode { +func (f *FakeFile) Mode() fs.FileMode { return f.mode } diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go index 903f9cc1db..11f91cbedb 100644 --- a/src/cmd/pprof/pprof.go +++ b/src/cmd/pprof/pprof.go @@ -13,7 +13,7 @@ import ( "crypto/tls" "debug/dwarf" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "os" @@ -94,7 +94,7 @@ func getProfile(source string, timeout time.Duration) (*profile.Profile, error) func statusCodeError(resp *http.Response) error { if resp.Header.Get("X-Go-Pprof") != "" && strings.Contains(resp.Header.Get("Content-Type"), "text/plain") { // error is from pprof endpoint - if body, err := ioutil.ReadAll(resp.Body); err == nil { + if body, err := io.ReadAll(resp.Body); err == nil { return fmt.Errorf("server response: %s - %s", resp.Status, body) } } @@ -171,7 +171,10 @@ func (*objTool) Demangle(names []string) (map[string]string, error) { return make(map[string]string), nil } -func (t *objTool) Disasm(file string, start, end uint64) ([]driver.Inst, error) { +func (t *objTool) Disasm(file string, start, end uint64, intelSyntax bool) ([]driver.Inst, error) { + if intelSyntax { + return nil, fmt.Errorf("printing assembly in Intel syntax is not supported") + } d, err := t.cachedDisasm(file) if err != nil { return nil, err diff --git a/src/cmd/trace/annotations_test.go b/src/cmd/trace/annotations_test.go index a9068d53c1..9c2d027366 100644 --- a/src/cmd/trace/annotations_test.go +++ b/src/cmd/trace/annotations_test.go @@ -12,7 +12,7 @@ import ( "flag" "fmt" traceparser "internal/trace" - "io/ioutil" + "os" "reflect" "runtime/debug" "runtime/trace" @@ -386,7 +386,7 @@ func saveTrace(buf *bytes.Buffer, name string) { if !*saveTraces { return } - if err := ioutil.WriteFile(name+".trace", buf.Bytes(), 0600); err != nil { + if err := os.WriteFile(name+".trace", buf.Bytes(), 0600); err != nil { panic(fmt.Errorf("failed to write trace file: %v", err)) } } diff --git a/src/cmd/trace/pprof.go b/src/cmd/trace/pprof.go index a31d71b013..a73ff5336a 100644 --- a/src/cmd/trace/pprof.go +++ b/src/cmd/trace/pprof.go @@ -11,7 +11,6 @@ import ( "fmt" "internal/trace" "io" - "io/ioutil" "net/http" "os" "os/exec" @@ -294,7 +293,7 @@ func serveSVGProfile(prof func(w io.Writer, r *http.Request) error) http.Handler return } - blockf, err := ioutil.TempFile("", "block") + blockf, err := os.CreateTemp("", "block") if err != nil { http.Error(w, fmt.Sprintf("failed to create temp file: %v", err), http.StatusInternalServerError) return diff --git a/src/cmd/trace/trace_test.go b/src/cmd/trace/trace_test.go index dd12e8cd20..ea0cc6f880 100644 --- a/src/cmd/trace/trace_test.go +++ b/src/cmd/trace/trace_test.go @@ -10,7 +10,7 @@ import ( "cmd/internal/traceviewer" "context" "internal/trace" - "io/ioutil" + "io" rtrace "runtime/trace" "strings" "sync" @@ -78,7 +78,7 @@ func TestGoroutineCount(t *testing.T) { // Use the default viewerDataTraceConsumer but replace // consumeViewerEvent to intercept the ViewerEvents for testing. - c := viewerDataTraceConsumer(ioutil.Discard, 0, 1<<63-1) + c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { if ev.Name == "Goroutines" { cnt := ev.Arg.(*goroutineCountersArg) @@ -131,7 +131,7 @@ func TestGoroutineFilter(t *testing.T) { gs: map[uint64]bool{10: true}, } - c := viewerDataTraceConsumer(ioutil.Discard, 0, 1<<63-1) + c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) if err := generateTrace(params, c); err != nil { t.Fatalf("generateTrace failed: %v", err) } @@ -163,7 +163,7 @@ func TestPreemptedMarkAssist(t *testing.T) { endTime: int64(1<<63 - 1), } - c := viewerDataTraceConsumer(ioutil.Discard, 0, 1<<63-1) + c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) marks := 0 c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { @@ -214,7 +214,7 @@ func TestFoo(t *testing.T) { tasks: []*taskDesc{task}, } - c := viewerDataTraceConsumer(ioutil.Discard, 0, 1<<63-1) + c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) var logBeforeTaskEnd, logAfterTaskEnd bool c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { diff --git a/src/cmd/trace/trace_unix_test.go b/src/cmd/trace/trace_unix_test.go index 645978e0f8..c569b40bb2 100644 --- a/src/cmd/trace/trace_unix_test.go +++ b/src/cmd/trace/trace_unix_test.go @@ -10,7 +10,7 @@ import ( "bytes" "cmd/internal/traceviewer" traceparser "internal/trace" - "io/ioutil" + "io" "runtime" "runtime/trace" "sync" @@ -83,7 +83,7 @@ func TestGoroutineInSyscall(t *testing.T) { // Check only one thread for the pipe read goroutine is // considered in-syscall. - c := viewerDataTraceConsumer(ioutil.Discard, 0, 1<<63-1) + c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { if ev.Name == "Threads" { arg := ev.Arg.(*threadCountersArg) diff --git a/src/cmd/vendor/github.com/google/pprof/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/driver/driver.go index 9bcbc8295a..e65bc2f417 100644 --- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go @@ -142,7 +142,7 @@ type ObjTool interface { // Disasm disassembles the named object file, starting at // the start address and stopping at (before) the end address. - Disasm(file string, start, end uint64) ([]Inst, error) + Disasm(file string, start, end uint64, intelSyntax bool) ([]Inst, error) } // An Inst is a single instruction in an assembly listing. @@ -269,8 +269,8 @@ func (f *internalObjFile) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, return pluginSyms, nil } -func (o *internalObjTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) { - insts, err := o.ObjTool.Disasm(file, start, end) +func (o *internalObjTool) Disasm(file string, start, end uint64, intelSyntax bool) ([]plugin.Inst, error) { + insts, err := o.ObjTool.Disasm(file, start, end, intelSyntax) if err != nil { return nil, err } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go index 967726d1fa..4b67cc4ab0 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go @@ -19,6 +19,7 @@ import ( "debug/elf" "debug/macho" "encoding/binary" + "errors" "fmt" "io" "os" @@ -26,6 +27,7 @@ import ( "path/filepath" "regexp" "runtime" + "strconv" "strings" "sync" @@ -39,6 +41,8 @@ type Binutils struct { rep *binrep } +var objdumpLLVMVerRE = regexp.MustCompile(`LLVM version (?:(\d*)\.(\d*)\.(\d*)|.*(trunk).*)`) + // binrep is an immutable representation for Binutils. It is atomically // replaced on every mutation to provide thread-safe access. type binrep struct { @@ -51,6 +55,7 @@ type binrep struct { nmFound bool objdump string objdumpFound bool + isLLVMObjdump bool // if fast, perform symbolization using nm (symbol names only), // instead of file-line detail from the slower addr2line. @@ -132,15 +137,103 @@ func initTools(b *binrep, config string) { } defaultPath := paths[""] - b.llvmSymbolizer, b.llvmSymbolizerFound = findExe("llvm-symbolizer", append(paths["llvm-symbolizer"], defaultPath...)) - b.addr2line, b.addr2lineFound = findExe("addr2line", append(paths["addr2line"], defaultPath...)) - if !b.addr2lineFound { - // On MacOS, brew installs addr2line under gaddr2line name, so search for - // that if the tool is not found by its default name. - b.addr2line, b.addr2lineFound = findExe("gaddr2line", append(paths["addr2line"], defaultPath...)) + b.llvmSymbolizer, b.llvmSymbolizerFound = chooseExe([]string{"llvm-symbolizer"}, []string{}, append(paths["llvm-symbolizer"], defaultPath...)) + b.addr2line, b.addr2lineFound = chooseExe([]string{"addr2line"}, []string{"gaddr2line"}, append(paths["addr2line"], defaultPath...)) + // The "-n" option is supported by LLVM since 2011. The output of llvm-nm + // and GNU nm with "-n" option is interchangeable for our purposes, so we do + // not need to differrentiate them. + b.nm, b.nmFound = chooseExe([]string{"llvm-nm", "nm"}, []string{"gnm"}, append(paths["nm"], defaultPath...)) + b.objdump, b.objdumpFound, b.isLLVMObjdump = findObjdump(append(paths["objdump"], defaultPath...)) +} + +// findObjdump finds and returns path to preferred objdump binary. +// Order of preference is: llvm-objdump, objdump. +// On MacOS only, also looks for gobjdump with least preference. +// Accepts a list of paths and returns: +// a string with path to the preferred objdump binary if found, +// or an empty string if not found; +// a boolean if any acceptable objdump was found; +// a boolean indicating if it is an LLVM objdump. +func findObjdump(paths []string) (string, bool, bool) { + objdumpNames := []string{"llvm-objdump", "objdump"} + if runtime.GOOS == "darwin" { + objdumpNames = append(objdumpNames, "gobjdump") + } + + for _, objdumpName := range objdumpNames { + if objdump, objdumpFound := findExe(objdumpName, paths); objdumpFound { + cmdOut, err := exec.Command(objdump, "--version").Output() + if err != nil { + continue + } + if isLLVMObjdump(string(cmdOut)) { + return objdump, true, true + } + if isBuObjdump(string(cmdOut)) { + return objdump, true, false + } + } + } + return "", false, false +} + +// chooseExe finds and returns path to preferred binary. names is a list of +// names to search on both Linux and OSX. osxNames is a list of names specific +// to OSX. names always has a higher priority than osxNames. The order of +// the name within each list decides its priority (e.g. the first name has a +// higher priority than the second name in the list). +// +// It returns a string with path to the binary and a boolean indicating if any +// acceptable binary was found. +func chooseExe(names, osxNames []string, paths []string) (string, bool) { + if runtime.GOOS == "darwin" { + names = append(names, osxNames...) + } + for _, name := range names { + if binary, found := findExe(name, paths); found { + return binary, true + } + } + return "", false +} + +// isLLVMObjdump accepts a string with path to an objdump binary, +// and returns a boolean indicating if the given binary is an LLVM +// objdump binary of an acceptable version. +func isLLVMObjdump(output string) bool { + fields := objdumpLLVMVerRE.FindStringSubmatch(output) + if len(fields) != 5 { + return false + } + if fields[4] == "trunk" { + return true + } + verMajor, err := strconv.Atoi(fields[1]) + if err != nil { + return false + } + verPatch, err := strconv.Atoi(fields[3]) + if err != nil { + return false + } + if runtime.GOOS == "linux" && verMajor >= 8 { + // Ensure LLVM objdump is at least version 8.0 on Linux. + // Some flags, like --demangle, and double dashes for options are + // not supported by previous versions. + return true } - b.nm, b.nmFound = findExe("nm", append(paths["nm"], defaultPath...)) - b.objdump, b.objdumpFound = findExe("objdump", append(paths["objdump"], defaultPath...)) + if runtime.GOOS == "darwin" { + // Ensure LLVM objdump is at least version 10.0.1 on MacOS. + return verMajor > 10 || (verMajor == 10 && verPatch >= 1) + } + return false +} + +// isBuObjdump accepts a string with path to an objdump binary, +// and returns a boolean indicating if the given binary is a GNU +// binutils objdump binary. No version check is performed. +func isBuObjdump(output string) bool { + return strings.Contains(output, "GNU objdump") } // findExe looks for an executable command on a set of paths. @@ -157,12 +250,25 @@ func findExe(cmd string, paths []string) (string, bool) { // Disasm returns the assembly instructions for the specified address range // of a binary. -func (bu *Binutils) Disasm(file string, start, end uint64) ([]plugin.Inst, error) { +func (bu *Binutils) Disasm(file string, start, end uint64, intelSyntax bool) ([]plugin.Inst, error) { b := bu.get() - cmd := exec.Command(b.objdump, "-d", "-C", "--no-show-raw-insn", "-l", - fmt.Sprintf("--start-address=%#x", start), - fmt.Sprintf("--stop-address=%#x", end), - file) + if !b.objdumpFound { + return nil, errors.New("cannot disasm: no objdump tool available") + } + args := []string{"--disassemble-all", "--demangle", "--no-show-raw-insn", + "--line-numbers", fmt.Sprintf("--start-address=%#x", start), + fmt.Sprintf("--stop-address=%#x", end)} + + if intelSyntax { + if b.isLLVMObjdump { + args = append(args, "--x86-asm-syntax=intel") + } else { + args = append(args, "-M", "intel") + } + } + + args = append(args, file) + cmd := exec.Command(b.objdump, args...) out, err := cmd.Output() if err != nil { return nil, fmt.Errorf("%v: %v", cmd.Args, err) diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go index 28c89aa163..d0be614bdc 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go @@ -25,10 +25,11 @@ import ( ) var ( - nmOutputRE = regexp.MustCompile(`^\s*([[:xdigit:]]+)\s+(.)\s+(.*)`) - objdumpAsmOutputRE = regexp.MustCompile(`^\s*([[:xdigit:]]+):\s+(.*)`) - objdumpOutputFileLine = regexp.MustCompile(`^(.*):([0-9]+)`) - objdumpOutputFunction = regexp.MustCompile(`^(\S.*)\(\):`) + nmOutputRE = regexp.MustCompile(`^\s*([[:xdigit:]]+)\s+(.)\s+(.*)`) + objdumpAsmOutputRE = regexp.MustCompile(`^\s*([[:xdigit:]]+):\s+(.*)`) + objdumpOutputFileLine = regexp.MustCompile(`^;?\s?(.*):([0-9]+)`) + objdumpOutputFunction = regexp.MustCompile(`^;?\s?(\S.*)\(\):`) + objdumpOutputFunctionLLVM = regexp.MustCompile(`^([[:xdigit:]]+)?\s?(.*):`) ) func findSymbols(syms []byte, file string, r *regexp.Regexp, address uint64) ([]*plugin.Sym, error) { @@ -143,6 +144,11 @@ func disassemble(asm []byte) ([]plugin.Inst, error) { if fields := objdumpOutputFunction.FindStringSubmatch(input); len(fields) == 2 { function = fields[1] continue + } else { + if fields := objdumpOutputFunctionLLVM.FindStringSubmatch(input); len(fields) == 3 { + function = fields[2] + continue + } } // Reset on unrecognized lines. function, file, line = "", "", 0 diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go index 9fc1eea1f0..492400c5f3 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go @@ -69,8 +69,9 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { flagHTTP := flag.String("http", "", "Present interactive web UI at the specified http host:port") flagNoBrowser := flag.Bool("no_browser", false, "Skip opening a browswer for the interactive web UI") - // Flags used during command processing - installedFlags := installFlags(flag) + // Flags that set configuration properties. + cfg := currentConfig() + configFlagSetter := installConfigFlags(flag, &cfg) flagCommands := make(map[string]*bool) flagParamCommands := make(map[string]*string) @@ -107,8 +108,8 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { } } - // Report conflicting options - if err := updateFlags(installedFlags); err != nil { + // Apply any specified flags to cfg. + if err := configFlagSetter(); err != nil { return nil, nil, err } @@ -124,7 +125,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { return nil, nil, errors.New("-no_browser only makes sense with -http") } - si := pprofVariables["sample_index"].value + si := cfg.SampleIndex si = sampleIndex(flagTotalDelay, si, "delay", "-total_delay", o.UI) si = sampleIndex(flagMeanDelay, si, "delay", "-mean_delay", o.UI) si = sampleIndex(flagContentions, si, "contentions", "-contentions", o.UI) @@ -132,10 +133,10 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { si = sampleIndex(flagInUseObjects, si, "inuse_objects", "-inuse_objects", o.UI) si = sampleIndex(flagAllocSpace, si, "alloc_space", "-alloc_space", o.UI) si = sampleIndex(flagAllocObjects, si, "alloc_objects", "-alloc_objects", o.UI) - pprofVariables.set("sample_index", si) + cfg.SampleIndex = si if *flagMeanDelay { - pprofVariables.set("mean", "true") + cfg.Mean = true } source := &source{ @@ -154,7 +155,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { return nil, nil, err } - normalize := pprofVariables["normalize"].boolValue() + normalize := cfg.Normalize if normalize && len(source.Base) == 0 { return nil, nil, errors.New("must have base profile to normalize by") } @@ -163,6 +164,8 @@ func parseFlags(o *plugin.Options) (*source, []string, error) { if bu, ok := o.Obj.(*binutils.Binutils); ok { bu.SetTools(*flagTools) } + + setCurrentConfig(cfg) return source, cmd, nil } @@ -194,66 +197,72 @@ func dropEmpty(list []*string) []string { return l } -// installFlags creates command line flags for pprof variables. -func installFlags(flag plugin.FlagSet) flagsInstalled { - f := flagsInstalled{ - ints: make(map[string]*int), - bools: make(map[string]*bool), - floats: make(map[string]*float64), - strings: make(map[string]*string), - } - for n, v := range pprofVariables { - switch v.kind { - case boolKind: - if v.group != "" { - // Set all radio variables to false to identify conflicts. - f.bools[n] = flag.Bool(n, false, v.help) +// installConfigFlags creates command line flags for configuration +// fields and returns a function which can be called after flags have +// been parsed to copy any flags specified on the command line to +// *cfg. +func installConfigFlags(flag plugin.FlagSet, cfg *config) func() error { + // List of functions for setting the different parts of a config. + var setters []func() + var err error // Holds any errors encountered while running setters. + + for _, field := range configFields { + n := field.name + help := configHelp[n] + var setter func() + switch ptr := cfg.fieldPtr(field).(type) { + case *bool: + f := flag.Bool(n, *ptr, help) + setter = func() { *ptr = *f } + case *int: + f := flag.Int(n, *ptr, help) + setter = func() { *ptr = *f } + case *float64: + f := flag.Float64(n, *ptr, help) + setter = func() { *ptr = *f } + case *string: + if len(field.choices) == 0 { + f := flag.String(n, *ptr, help) + setter = func() { *ptr = *f } } else { - f.bools[n] = flag.Bool(n, v.boolValue(), v.help) + // Make a separate flag per possible choice. + // Set all flags to initially false so we can + // identify conflicts. + bools := make(map[string]*bool) + for _, choice := range field.choices { + bools[choice] = flag.Bool(choice, false, configHelp[choice]) + } + setter = func() { + var set []string + for k, v := range bools { + if *v { + set = append(set, k) + } + } + switch len(set) { + case 0: + // Leave as default value. + case 1: + *ptr = set[0] + default: + err = fmt.Errorf("conflicting options set: %v", set) + } + } } - case intKind: - f.ints[n] = flag.Int(n, v.intValue(), v.help) - case floatKind: - f.floats[n] = flag.Float64(n, v.floatValue(), v.help) - case stringKind: - f.strings[n] = flag.String(n, v.value, v.help) } + setters = append(setters, setter) } - return f -} -// updateFlags updates the pprof variables according to the flags -// parsed in the command line. -func updateFlags(f flagsInstalled) error { - vars := pprofVariables - groups := map[string]string{} - for n, v := range f.bools { - vars.set(n, fmt.Sprint(*v)) - if *v { - g := vars[n].group - if g != "" && groups[g] != "" { - return fmt.Errorf("conflicting options %q and %q set", n, groups[g]) + return func() error { + // Apply the setter for every flag. + for _, setter := range setters { + setter() + if err != nil { + return err } - groups[g] = n } + return nil } - for n, v := range f.ints { - vars.set(n, fmt.Sprint(*v)) - } - for n, v := range f.floats { - vars.set(n, fmt.Sprint(*v)) - } - for n, v := range f.strings { - vars.set(n, *v) - } - return nil -} - -type flagsInstalled struct { - ints map[string]*int - bools map[string]*bool - floats map[string]*float64 - strings map[string]*string } // isBuildID determines if the profile may contain a build ID, by diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go index f52471490a..4397e253e0 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go @@ -22,7 +22,6 @@ import ( "os/exec" "runtime" "sort" - "strconv" "strings" "time" @@ -70,9 +69,7 @@ func AddCommand(cmd string, format int, post PostProcessor, desc, usage string) // SetVariableDefault sets the default value for a pprof // variable. This enables extensions to set their own defaults. func SetVariableDefault(variable, value string) { - if v := pprofVariables[variable]; v != nil { - v.value = value - } + configure(variable, value) } // PostProcessor is a function that applies post-processing to the report output @@ -124,130 +121,132 @@ var pprofCommands = commands{ "weblist": {report.WebList, nil, invokeVisualizer("html", browsers()), true, "Display annotated source in a web browser", listHelp("weblist", false)}, } -// pprofVariables are the configuration parameters that affect the -// reported generated by pprof. -var pprofVariables = variables{ +// configHelp contains help text per configuration parameter. +var configHelp = map[string]string{ // Filename for file-based output formats, stdout by default. - "output": &variable{stringKind, "", "", helpText("Output filename for file-based outputs")}, + "output": helpText("Output filename for file-based outputs"), // Comparisons. - "drop_negative": &variable{boolKind, "f", "", helpText( + "drop_negative": helpText( "Ignore negative differences", - "Do not show any locations with values <0.")}, + "Do not show any locations with values <0."), // Graph handling options. - "call_tree": &variable{boolKind, "f", "", helpText( + "call_tree": helpText( "Create a context-sensitive call tree", - "Treat locations reached through different paths as separate.")}, + "Treat locations reached through different paths as separate."), // Display options. - "relative_percentages": &variable{boolKind, "f", "", helpText( + "relative_percentages": helpText( "Show percentages relative to focused subgraph", "If unset, percentages are relative to full graph before focusing", - "to facilitate comparison with original graph.")}, - "unit": &variable{stringKind, "minimum", "", helpText( + "to facilitate comparison with original graph."), + "unit": helpText( "Measurement units to display", "Scale the sample values to this unit.", "For time-based profiles, use seconds, milliseconds, nanoseconds, etc.", "For memory profiles, use megabytes, kilobytes, bytes, etc.", - "Using auto will scale each value independently to the most natural unit.")}, - "compact_labels": &variable{boolKind, "f", "", "Show minimal headers"}, - "source_path": &variable{stringKind, "", "", "Search path for source files"}, - "trim_path": &variable{stringKind, "", "", "Path to trim from source paths before search"}, + "Using auto will scale each value independently to the most natural unit."), + "compact_labels": "Show minimal headers", + "source_path": "Search path for source files", + "trim_path": "Path to trim from source paths before search", + "intel_syntax": helpText( + "Show assembly in Intel syntax", + "Only applicable to commands `disasm` and `weblist`"), // Filtering options - "nodecount": &variable{intKind, "-1", "", helpText( + "nodecount": helpText( "Max number of nodes to show", "Uses heuristics to limit the number of locations to be displayed.", - "On graphs, dotted edges represent paths through nodes that have been removed.")}, - "nodefraction": &variable{floatKind, "0.005", "", "Hide nodes below <f>*total"}, - "edgefraction": &variable{floatKind, "0.001", "", "Hide edges below <f>*total"}, - "trim": &variable{boolKind, "t", "", helpText( + "On graphs, dotted edges represent paths through nodes that have been removed."), + "nodefraction": "Hide nodes below <f>*total", + "edgefraction": "Hide edges below <f>*total", + "trim": helpText( "Honor nodefraction/edgefraction/nodecount defaults", - "Set to false to get the full profile, without any trimming.")}, - "focus": &variable{stringKind, "", "", helpText( + "Set to false to get the full profile, without any trimming."), + "focus": helpText( "Restricts to samples going through a node matching regexp", "Discard samples that do not include a node matching this regexp.", - "Matching includes the function name, filename or object name.")}, - "ignore": &variable{stringKind, "", "", helpText( + "Matching includes the function name, filename or object name."), + "ignore": helpText( "Skips paths going through any nodes matching regexp", "If set, discard samples that include a node matching this regexp.", - "Matching includes the function name, filename or object name.")}, - "prune_from": &variable{stringKind, "", "", helpText( + "Matching includes the function name, filename or object name."), + "prune_from": helpText( "Drops any functions below the matched frame.", "If set, any frames matching the specified regexp and any frames", - "below it will be dropped from each sample.")}, - "hide": &variable{stringKind, "", "", helpText( + "below it will be dropped from each sample."), + "hide": helpText( "Skips nodes matching regexp", "Discard nodes that match this location.", "Other nodes from samples that include this location will be shown.", - "Matching includes the function name, filename or object name.")}, - "show": &variable{stringKind, "", "", helpText( + "Matching includes the function name, filename or object name."), + "show": helpText( "Only show nodes matching regexp", "If set, only show nodes that match this location.", - "Matching includes the function name, filename or object name.")}, - "show_from": &variable{stringKind, "", "", helpText( + "Matching includes the function name, filename or object name."), + "show_from": helpText( "Drops functions above the highest matched frame.", "If set, all frames above the highest match are dropped from every sample.", - "Matching includes the function name, filename or object name.")}, - "tagfocus": &variable{stringKind, "", "", helpText( + "Matching includes the function name, filename or object name."), + "tagfocus": helpText( "Restricts to samples with tags in range or matched by regexp", "Use name=value syntax to limit the matching to a specific tag.", "Numeric tag filter examples: 1kb, 1kb:10kb, memory=32mb:", - "String tag filter examples: foo, foo.*bar, mytag=foo.*bar")}, - "tagignore": &variable{stringKind, "", "", helpText( + "String tag filter examples: foo, foo.*bar, mytag=foo.*bar"), + "tagignore": helpText( "Discard samples with tags in range or matched by regexp", "Use name=value syntax to limit the matching to a specific tag.", "Numeric tag filter examples: 1kb, 1kb:10kb, memory=32mb:", - "String tag filter examples: foo, foo.*bar, mytag=foo.*bar")}, - "tagshow": &variable{stringKind, "", "", helpText( + "String tag filter examples: foo, foo.*bar, mytag=foo.*bar"), + "tagshow": helpText( "Only consider tags matching this regexp", - "Discard tags that do not match this regexp")}, - "taghide": &variable{stringKind, "", "", helpText( + "Discard tags that do not match this regexp"), + "taghide": helpText( "Skip tags matching this regexp", - "Discard tags that match this regexp")}, + "Discard tags that match this regexp"), // Heap profile options - "divide_by": &variable{floatKind, "1", "", helpText( + "divide_by": helpText( "Ratio to divide all samples before visualization", - "Divide all samples values by a constant, eg the number of processors or jobs.")}, - "mean": &variable{boolKind, "f", "", helpText( + "Divide all samples values by a constant, eg the number of processors or jobs."), + "mean": helpText( "Average sample value over first value (count)", "For memory profiles, report average memory per allocation.", - "For time-based profiles, report average time per event.")}, - "sample_index": &variable{stringKind, "", "", helpText( + "For time-based profiles, report average time per event."), + "sample_index": helpText( "Sample value to report (0-based index or name)", "Profiles contain multiple values per sample.", - "Use sample_index=i to select the ith value (starting at 0).")}, - "normalize": &variable{boolKind, "f", "", helpText( - "Scales profile based on the base profile.")}, + "Use sample_index=i to select the ith value (starting at 0)."), + "normalize": helpText( + "Scales profile based on the base profile."), // Data sorting criteria - "flat": &variable{boolKind, "t", "cumulative", helpText("Sort entries based on own weight")}, - "cum": &variable{boolKind, "f", "cumulative", helpText("Sort entries based on cumulative weight")}, + "flat": helpText("Sort entries based on own weight"), + "cum": helpText("Sort entries based on cumulative weight"), // Output granularity - "functions": &variable{boolKind, "t", "granularity", helpText( + "functions": helpText( "Aggregate at the function level.", - "Ignores the filename where the function was defined.")}, - "filefunctions": &variable{boolKind, "t", "granularity", helpText( + "Ignores the filename where the function was defined."), + "filefunctions": helpText( "Aggregate at the function level.", - "Takes into account the filename where the function was defined.")}, - "files": &variable{boolKind, "f", "granularity", "Aggregate at the file level."}, - "lines": &variable{boolKind, "f", "granularity", "Aggregate at the source code line level."}, - "addresses": &variable{boolKind, "f", "granularity", helpText( + "Takes into account the filename where the function was defined."), + "files": "Aggregate at the file level.", + "lines": "Aggregate at the source code line level.", + "addresses": helpText( "Aggregate at the address level.", - "Includes functions' addresses in the output.")}, - "noinlines": &variable{boolKind, "f", "", helpText( + "Includes functions' addresses in the output."), + "noinlines": helpText( "Ignore inlines.", - "Attributes inlined functions to their first out-of-line caller.")}, + "Attributes inlined functions to their first out-of-line caller."), } func helpText(s ...string) string { return strings.Join(s, "\n") + "\n" } -// usage returns a string describing the pprof commands and variables. -// if commandLine is set, the output reflect cli usage. +// usage returns a string describing the pprof commands and configuration +// options. if commandLine is set, the output reflect cli usage. func usage(commandLine bool) string { var prefix string if commandLine { @@ -269,40 +268,33 @@ func usage(commandLine bool) string { } else { help = " Commands:\n" commands = append(commands, fmtHelp("o/options", "List options and their current values")) - commands = append(commands, fmtHelp("quit/exit/^D", "Exit pprof")) + commands = append(commands, fmtHelp("q/quit/exit/^D", "Exit pprof")) } help = help + strings.Join(commands, "\n") + "\n\n" + " Options:\n" - // Print help for variables after sorting them. - // Collect radio variables by their group name to print them together. - radioOptions := make(map[string][]string) + // Print help for configuration options after sorting them. + // Collect choices for multi-choice options print them together. var variables []string - for name, vr := range pprofVariables { - if vr.group != "" { - radioOptions[vr.group] = append(radioOptions[vr.group], name) + var radioStrings []string + for _, f := range configFields { + if len(f.choices) == 0 { + variables = append(variables, fmtHelp(prefix+f.name, configHelp[f.name])) continue } - variables = append(variables, fmtHelp(prefix+name, vr.help)) - } - sort.Strings(variables) - - help = help + strings.Join(variables, "\n") + "\n\n" + - " Option groups (only set one per group):\n" - - var radioStrings []string - for radio, ops := range radioOptions { - sort.Strings(ops) - s := []string{fmtHelp(radio, "")} - for _, op := range ops { - s = append(s, " "+fmtHelp(prefix+op, pprofVariables[op].help)) + // Format help for for this group. + s := []string{fmtHelp(f.name, "")} + for _, choice := range f.choices { + s = append(s, " "+fmtHelp(prefix+choice, configHelp[choice])) } - radioStrings = append(radioStrings, strings.Join(s, "\n")) } + sort.Strings(variables) sort.Strings(radioStrings) - return help + strings.Join(radioStrings, "\n") + return help + strings.Join(variables, "\n") + "\n\n" + + " Option groups (only set one per group):\n" + + strings.Join(radioStrings, "\n") } func reportHelp(c string, cum, redirect bool) string { @@ -445,105 +437,8 @@ func invokeVisualizer(suffix string, visualizers []string) PostProcessor { } } -// variables describe the configuration parameters recognized by pprof. -type variables map[string]*variable - -// variable is a single configuration parameter. -type variable struct { - kind int // How to interpret the value, must be one of the enums below. - value string // Effective value. Only values appropriate for the Kind should be set. - group string // boolKind variables with the same Group != "" cannot be set simultaneously. - help string // Text describing the variable, in multiple lines separated by newline. -} - -const ( - // variable.kind must be one of these variables. - boolKind = iota - intKind - floatKind - stringKind -) - -// set updates the value of a variable, checking that the value is -// suitable for the variable Kind. -func (vars variables) set(name, value string) error { - v := vars[name] - if v == nil { - return fmt.Errorf("no variable %s", name) - } - var err error - switch v.kind { - case boolKind: - var b bool - if b, err = stringToBool(value); err == nil { - if v.group != "" && !b { - err = fmt.Errorf("%q can only be set to true", name) - } - } - case intKind: - _, err = strconv.Atoi(value) - case floatKind: - _, err = strconv.ParseFloat(value, 64) - case stringKind: - // Remove quotes, particularly useful for empty values. - if len(value) > 1 && strings.HasPrefix(value, `"`) && strings.HasSuffix(value, `"`) { - value = value[1 : len(value)-1] - } - } - if err != nil { - return err - } - vars[name].value = value - if group := vars[name].group; group != "" { - for vname, vvar := range vars { - if vvar.group == group && vname != name { - vvar.value = "f" - } - } - } - return err -} - -// boolValue returns the value of a boolean variable. -func (v *variable) boolValue() bool { - b, err := stringToBool(v.value) - if err != nil { - panic("unexpected value " + v.value + " for bool ") - } - return b -} - -// intValue returns the value of an intKind variable. -func (v *variable) intValue() int { - i, err := strconv.Atoi(v.value) - if err != nil { - panic("unexpected value " + v.value + " for int ") - } - return i -} - -// floatValue returns the value of a Float variable. -func (v *variable) floatValue() float64 { - f, err := strconv.ParseFloat(v.value, 64) - if err != nil { - panic("unexpected value " + v.value + " for float ") - } - return f -} - -// stringValue returns a canonical representation for a variable. -func (v *variable) stringValue() string { - switch v.kind { - case boolKind: - return fmt.Sprint(v.boolValue()) - case intKind: - return fmt.Sprint(v.intValue()) - case floatKind: - return fmt.Sprint(v.floatValue()) - } - return v.value -} - +// stringToBool is a custom parser for bools. We avoid using strconv.ParseBool +// to remain compatible with old pprof behavior (e.g., treating "" as true). func stringToBool(s string) (bool, error) { switch strings.ToLower(s) { case "true", "t", "yes", "y", "1", "": @@ -554,13 +449,3 @@ func stringToBool(s string) (bool, error) { return false, fmt.Errorf(`illegal value "%s" for bool variable`, s) } } - -// makeCopy returns a duplicate of a set of shell variables. -func (vars variables) makeCopy() variables { - varscopy := make(variables, len(vars)) - for n, v := range vars { - vcopy := *v - varscopy[n] = &vcopy - } - return varscopy -} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go new file mode 100644 index 0000000000..b3f82f22c9 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go @@ -0,0 +1,367 @@ +package driver + +import ( + "fmt" + "net/url" + "reflect" + "strconv" + "strings" + "sync" +) + +// config holds settings for a single named config. +// The JSON tag name for a field is used both for JSON encoding and as +// a named variable. +type config struct { + // Filename for file-based output formats, stdout by default. + Output string `json:"-"` + + // Display options. + CallTree bool `json:"call_tree,omitempty"` + RelativePercentages bool `json:"relative_percentages,omitempty"` + Unit string `json:"unit,omitempty"` + CompactLabels bool `json:"compact_labels,omitempty"` + SourcePath string `json:"-"` + TrimPath string `json:"-"` + IntelSyntax bool `json:"intel_syntax,omitempty"` + Mean bool `json:"mean,omitempty"` + SampleIndex string `json:"-"` + DivideBy float64 `json:"-"` + Normalize bool `json:"normalize,omitempty"` + Sort string `json:"sort,omitempty"` + + // Filtering options + DropNegative bool `json:"drop_negative,omitempty"` + NodeCount int `json:"nodecount,omitempty"` + NodeFraction float64 `json:"nodefraction,omitempty"` + EdgeFraction float64 `json:"edgefraction,omitempty"` + Trim bool `json:"trim,omitempty"` + Focus string `json:"focus,omitempty"` + Ignore string `json:"ignore,omitempty"` + PruneFrom string `json:"prune_from,omitempty"` + Hide string `json:"hide,omitempty"` + Show string `json:"show,omitempty"` + ShowFrom string `json:"show_from,omitempty"` + TagFocus string `json:"tagfocus,omitempty"` + TagIgnore string `json:"tagignore,omitempty"` + TagShow string `json:"tagshow,omitempty"` + TagHide string `json:"taghide,omitempty"` + NoInlines bool `json:"noinlines,omitempty"` + + // Output granularity + Granularity string `json:"granularity,omitempty"` +} + +// defaultConfig returns the default configuration values; it is unaffected by +// flags and interactive assignments. +func defaultConfig() config { + return config{ + Unit: "minimum", + NodeCount: -1, + NodeFraction: 0.005, + EdgeFraction: 0.001, + Trim: true, + DivideBy: 1.0, + Sort: "flat", + Granularity: "functions", + } +} + +// currentConfig holds the current configuration values; it is affected by +// flags and interactive assignments. +var currentCfg = defaultConfig() +var currentMu sync.Mutex + +func currentConfig() config { + currentMu.Lock() + defer currentMu.Unlock() + return currentCfg +} + +func setCurrentConfig(cfg config) { + currentMu.Lock() + defer currentMu.Unlock() + currentCfg = cfg +} + +// configField contains metadata for a single configuration field. +type configField struct { + name string // JSON field name/key in variables + urlparam string // URL parameter name + saved bool // Is field saved in settings? + field reflect.StructField // Field in config + choices []string // Name Of variables in group + defaultValue string // Default value for this field. +} + +var ( + configFields []configField // Precomputed metadata per config field + + // configFieldMap holds an entry for every config field as well as an + // entry for every valid choice for a multi-choice field. + configFieldMap map[string]configField +) + +func init() { + // Config names for fields that are not saved in settings and therefore + // do not have a JSON name. + notSaved := map[string]string{ + // Not saved in settings, but present in URLs. + "SampleIndex": "sample_index", + + // Following fields are also not placed in URLs. + "Output": "output", + "SourcePath": "source_path", + "TrimPath": "trim_path", + "DivideBy": "divide_by", + } + + // choices holds the list of allowed values for config fields that can + // take on one of a bounded set of values. + choices := map[string][]string{ + "sort": {"cum", "flat"}, + "granularity": {"functions", "filefunctions", "files", "lines", "addresses"}, + } + + // urlparam holds the mapping from a config field name to the URL + // parameter used to hold that config field. If no entry is present for + // a name, the corresponding field is not saved in URLs. + urlparam := map[string]string{ + "drop_negative": "dropneg", + "call_tree": "calltree", + "relative_percentages": "rel", + "unit": "unit", + "compact_labels": "compact", + "intel_syntax": "intel", + "nodecount": "n", + "nodefraction": "nf", + "edgefraction": "ef", + "trim": "trim", + "focus": "f", + "ignore": "i", + "prune_from": "prunefrom", + "hide": "h", + "show": "s", + "show_from": "sf", + "tagfocus": "tf", + "tagignore": "ti", + "tagshow": "ts", + "taghide": "th", + "mean": "mean", + "sample_index": "si", + "normalize": "norm", + "sort": "sort", + "granularity": "g", + "noinlines": "noinlines", + } + + def := defaultConfig() + configFieldMap = map[string]configField{} + t := reflect.TypeOf(config{}) + for i, n := 0, t.NumField(); i < n; i++ { + field := t.Field(i) + js := strings.Split(field.Tag.Get("json"), ",") + if len(js) == 0 { + continue + } + // Get the configuration name for this field. + name := js[0] + if name == "-" { + name = notSaved[field.Name] + if name == "" { + // Not a configurable field. + continue + } + } + f := configField{ + name: name, + urlparam: urlparam[name], + saved: (name == js[0]), + field: field, + choices: choices[name], + } + f.defaultValue = def.get(f) + configFields = append(configFields, f) + configFieldMap[f.name] = f + for _, choice := range f.choices { + configFieldMap[choice] = f + } + } +} + +// fieldPtr returns a pointer to the field identified by f in *cfg. +func (cfg *config) fieldPtr(f configField) interface{} { + // reflect.ValueOf: converts to reflect.Value + // Elem: dereferences cfg to make *cfg + // FieldByIndex: fetches the field + // Addr: takes address of field + // Interface: converts back from reflect.Value to a regular value + return reflect.ValueOf(cfg).Elem().FieldByIndex(f.field.Index).Addr().Interface() +} + +// get returns the value of field f in cfg. +func (cfg *config) get(f configField) string { + switch ptr := cfg.fieldPtr(f).(type) { + case *string: + return *ptr + case *int: + return fmt.Sprint(*ptr) + case *float64: + return fmt.Sprint(*ptr) + case *bool: + return fmt.Sprint(*ptr) + } + panic(fmt.Sprintf("unsupported config field type %v", f.field.Type)) +} + +// set sets the value of field f in cfg to value. +func (cfg *config) set(f configField, value string) error { + switch ptr := cfg.fieldPtr(f).(type) { + case *string: + if len(f.choices) > 0 { + // Verify that value is one of the allowed choices. + for _, choice := range f.choices { + if choice == value { + *ptr = value + return nil + } + } + return fmt.Errorf("invalid %q value %q", f.name, value) + } + *ptr = value + case *int: + v, err := strconv.Atoi(value) + if err != nil { + return err + } + *ptr = v + case *float64: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return err + } + *ptr = v + case *bool: + v, err := stringToBool(value) + if err != nil { + return err + } + *ptr = v + default: + panic(fmt.Sprintf("unsupported config field type %v", f.field.Type)) + } + return nil +} + +// isConfigurable returns true if name is either the name of a config field, or +// a valid value for a multi-choice config field. +func isConfigurable(name string) bool { + _, ok := configFieldMap[name] + return ok +} + +// isBoolConfig returns true if name is either name of a boolean config field, +// or a valid value for a multi-choice config field. +func isBoolConfig(name string) bool { + f, ok := configFieldMap[name] + if !ok { + return false + } + if name != f.name { + return true // name must be one possible value for the field + } + var cfg config + _, ok = cfg.fieldPtr(f).(*bool) + return ok +} + +// completeConfig returns the list of configurable names starting with prefix. +func completeConfig(prefix string) []string { + var result []string + for v := range configFieldMap { + if strings.HasPrefix(v, prefix) { + result = append(result, v) + } + } + return result +} + +// configure stores the name=value mapping into the current config, correctly +// handling the case when name identifies a particular choice in a field. +func configure(name, value string) error { + currentMu.Lock() + defer currentMu.Unlock() + f, ok := configFieldMap[name] + if !ok { + return fmt.Errorf("unknown config field %q", name) + } + if f.name == name { + return currentCfg.set(f, value) + } + // name must be one of the choices. If value is true, set field-value + // to name. + if v, err := strconv.ParseBool(value); v && err == nil { + return currentCfg.set(f, name) + } + return fmt.Errorf("unknown config field %q", name) +} + +// resetTransient sets all transient fields in *cfg to their currently +// configured values. +func (cfg *config) resetTransient() { + current := currentConfig() + cfg.Output = current.Output + cfg.SourcePath = current.SourcePath + cfg.TrimPath = current.TrimPath + cfg.DivideBy = current.DivideBy + cfg.SampleIndex = current.SampleIndex +} + +// applyURL updates *cfg based on params. +func (cfg *config) applyURL(params url.Values) error { + for _, f := range configFields { + var value string + if f.urlparam != "" { + value = params.Get(f.urlparam) + } + if value == "" { + continue + } + if err := cfg.set(f, value); err != nil { + return fmt.Errorf("error setting config field %s: %v", f.name, err) + } + } + return nil +} + +// makeURL returns a URL based on initialURL that contains the config contents +// as parameters. The second result is true iff a parameter value was changed. +func (cfg *config) makeURL(initialURL url.URL) (url.URL, bool) { + q := initialURL.Query() + changed := false + for _, f := range configFields { + if f.urlparam == "" || !f.saved { + continue + } + v := cfg.get(f) + if v == f.defaultValue { + v = "" // URL for of default value is the empty string. + } else if f.field.Type.Kind() == reflect.Bool { + // Shorten bool values to "f" or "t" + v = v[:1] + } + if q.Get(f.urlparam) == v { + continue + } + changed = true + if v == "" { + q.Del(f.urlparam) + } else { + q.Set(f.urlparam, v) + } + } + if changed { + initialURL.RawQuery = q.Encode() + } + return initialURL, changed +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go index 1be749aa32..878f2e1ead 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go @@ -50,7 +50,7 @@ func PProf(eo *plugin.Options) error { } if cmd != nil { - return generateReport(p, cmd, pprofVariables, o) + return generateReport(p, cmd, currentConfig(), o) } if src.HTTPHostport != "" { @@ -59,7 +59,7 @@ func PProf(eo *plugin.Options) error { return interactive(p, o) } -func generateRawReport(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) (*command, *report.Report, error) { +func generateRawReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Options) (*command, *report.Report, error) { p = p.Copy() // Prevent modification to the incoming profile. // Identify units of numeric tags in profile. @@ -71,16 +71,16 @@ func generateRawReport(p *profile.Profile, cmd []string, vars variables, o *plug panic("unexpected nil command") } - vars = applyCommandOverrides(cmd[0], c.format, vars) + cfg = applyCommandOverrides(cmd[0], c.format, cfg) // Delay focus after configuring report to get percentages on all samples. - relative := vars["relative_percentages"].boolValue() + relative := cfg.RelativePercentages if relative { - if err := applyFocus(p, numLabelUnits, vars, o.UI); err != nil { + if err := applyFocus(p, numLabelUnits, cfg, o.UI); err != nil { return nil, nil, err } } - ropt, err := reportOptions(p, numLabelUnits, vars) + ropt, err := reportOptions(p, numLabelUnits, cfg) if err != nil { return nil, nil, err } @@ -95,19 +95,19 @@ func generateRawReport(p *profile.Profile, cmd []string, vars variables, o *plug rpt := report.New(p, ropt) if !relative { - if err := applyFocus(p, numLabelUnits, vars, o.UI); err != nil { + if err := applyFocus(p, numLabelUnits, cfg, o.UI); err != nil { return nil, nil, err } } - if err := aggregate(p, vars); err != nil { + if err := aggregate(p, cfg); err != nil { return nil, nil, err } return c, rpt, nil } -func generateReport(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) error { - c, rpt, err := generateRawReport(p, cmd, vars, o) +func generateReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Options) error { + c, rpt, err := generateRawReport(p, cmd, cfg, o) if err != nil { return err } @@ -129,7 +129,7 @@ func generateReport(p *profile.Profile, cmd []string, vars variables, o *plugin. } // If no output is specified, use default visualizer. - output := vars["output"].value + output := cfg.Output if output == "" { if c.visualizer != nil { return c.visualizer(src, os.Stdout, o.UI) @@ -151,7 +151,7 @@ func generateReport(p *profile.Profile, cmd []string, vars variables, o *plugin. return out.Close() } -func applyCommandOverrides(cmd string, outputFormat int, v variables) variables { +func applyCommandOverrides(cmd string, outputFormat int, cfg config) config { // Some report types override the trim flag to false below. This is to make // sure the default heuristics of excluding insignificant nodes and edges // from the call graph do not apply. One example where it is important is @@ -160,55 +160,55 @@ func applyCommandOverrides(cmd string, outputFormat int, v variables) variables // data is selected. So, with trimming enabled, the report could end up // showing no data if the specified function is "uninteresting" as far as the // trimming is concerned. - trim := v["trim"].boolValue() + trim := cfg.Trim switch cmd { case "disasm", "weblist": trim = false - v.set("addresses", "t") + cfg.Granularity = "addresses" // Force the 'noinlines' mode so that source locations for a given address // collapse and there is only one for the given address. Without this // cumulative metrics would be double-counted when annotating the assembly. // This is because the merge is done by address and in case of an inlined // stack each of the inlined entries is a separate callgraph node. - v.set("noinlines", "t") + cfg.NoInlines = true case "peek": trim = false case "list": trim = false - v.set("lines", "t") + cfg.Granularity = "lines" // Do not force 'noinlines' to be false so that specifying // "-list foo -noinlines" is supported and works as expected. case "text", "top", "topproto": - if v["nodecount"].intValue() == -1 { - v.set("nodecount", "0") + if cfg.NodeCount == -1 { + cfg.NodeCount = 0 } default: - if v["nodecount"].intValue() == -1 { - v.set("nodecount", "80") + if cfg.NodeCount == -1 { + cfg.NodeCount = 80 } } switch outputFormat { case report.Proto, report.Raw, report.Callgrind: trim = false - v.set("addresses", "t") - v.set("noinlines", "f") + cfg.Granularity = "addresses" + cfg.NoInlines = false } if !trim { - v.set("nodecount", "0") - v.set("nodefraction", "0") - v.set("edgefraction", "0") + cfg.NodeCount = 0 + cfg.NodeFraction = 0 + cfg.EdgeFraction = 0 } - return v + return cfg } -func aggregate(prof *profile.Profile, v variables) error { +func aggregate(prof *profile.Profile, cfg config) error { var function, filename, linenumber, address bool - inlines := !v["noinlines"].boolValue() - switch { - case v["addresses"].boolValue(): + inlines := !cfg.NoInlines + switch cfg.Granularity { + case "addresses": if inlines { return nil } @@ -216,15 +216,15 @@ func aggregate(prof *profile.Profile, v variables) error { filename = true linenumber = true address = true - case v["lines"].boolValue(): + case "lines": function = true filename = true linenumber = true - case v["files"].boolValue(): + case "files": filename = true - case v["functions"].boolValue(): + case "functions": function = true - case v["filefunctions"].boolValue(): + case "filefunctions": function = true filename = true default: @@ -233,8 +233,8 @@ func aggregate(prof *profile.Profile, v variables) error { return prof.Aggregate(inlines, function, filename, linenumber, address) } -func reportOptions(p *profile.Profile, numLabelUnits map[string]string, vars variables) (*report.Options, error) { - si, mean := vars["sample_index"].value, vars["mean"].boolValue() +func reportOptions(p *profile.Profile, numLabelUnits map[string]string, cfg config) (*report.Options, error) { + si, mean := cfg.SampleIndex, cfg.Mean value, meanDiv, sample, err := sampleFormat(p, si, mean) if err != nil { return nil, err @@ -245,29 +245,37 @@ func reportOptions(p *profile.Profile, numLabelUnits map[string]string, vars var stype = "mean_" + stype } - if vars["divide_by"].floatValue() == 0 { + if cfg.DivideBy == 0 { return nil, fmt.Errorf("zero divisor specified") } var filters []string - for _, k := range []string{"focus", "ignore", "hide", "show", "show_from", "tagfocus", "tagignore", "tagshow", "taghide"} { - v := vars[k].value + addFilter := func(k string, v string) { if v != "" { filters = append(filters, k+"="+v) } } + addFilter("focus", cfg.Focus) + addFilter("ignore", cfg.Ignore) + addFilter("hide", cfg.Hide) + addFilter("show", cfg.Show) + addFilter("show_from", cfg.ShowFrom) + addFilter("tagfocus", cfg.TagFocus) + addFilter("tagignore", cfg.TagIgnore) + addFilter("tagshow", cfg.TagShow) + addFilter("taghide", cfg.TagHide) ropt := &report.Options{ - CumSort: vars["cum"].boolValue(), - CallTree: vars["call_tree"].boolValue(), - DropNegative: vars["drop_negative"].boolValue(), + CumSort: cfg.Sort == "cum", + CallTree: cfg.CallTree, + DropNegative: cfg.DropNegative, - CompactLabels: vars["compact_labels"].boolValue(), - Ratio: 1 / vars["divide_by"].floatValue(), + CompactLabels: cfg.CompactLabels, + Ratio: 1 / cfg.DivideBy, - NodeCount: vars["nodecount"].intValue(), - NodeFraction: vars["nodefraction"].floatValue(), - EdgeFraction: vars["edgefraction"].floatValue(), + NodeCount: cfg.NodeCount, + NodeFraction: cfg.NodeFraction, + EdgeFraction: cfg.EdgeFraction, ActiveFilters: filters, NumLabelUnits: numLabelUnits, @@ -277,10 +285,12 @@ func reportOptions(p *profile.Profile, numLabelUnits map[string]string, vars var SampleType: stype, SampleUnit: sample.Unit, - OutputUnit: vars["unit"].value, + OutputUnit: cfg.Unit, - SourcePath: vars["source_path"].stringValue(), - TrimPath: vars["trim_path"].stringValue(), + SourcePath: cfg.SourcePath, + TrimPath: cfg.TrimPath, + + IntelSyntax: cfg.IntelSyntax, } if len(p.Mapping) > 0 && p.Mapping[0].File != "" { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go index af7b8d478a..fd05adb146 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go @@ -28,15 +28,15 @@ import ( var tagFilterRangeRx = regexp.MustCompile("([+-]?[[:digit:]]+)([[:alpha:]]+)?") // applyFocus filters samples based on the focus/ignore options -func applyFocus(prof *profile.Profile, numLabelUnits map[string]string, v variables, ui plugin.UI) error { - focus, err := compileRegexOption("focus", v["focus"].value, nil) - ignore, err := compileRegexOption("ignore", v["ignore"].value, err) - hide, err := compileRegexOption("hide", v["hide"].value, err) - show, err := compileRegexOption("show", v["show"].value, err) - showfrom, err := compileRegexOption("show_from", v["show_from"].value, err) - tagfocus, err := compileTagFilter("tagfocus", v["tagfocus"].value, numLabelUnits, ui, err) - tagignore, err := compileTagFilter("tagignore", v["tagignore"].value, numLabelUnits, ui, err) - prunefrom, err := compileRegexOption("prune_from", v["prune_from"].value, err) +func applyFocus(prof *profile.Profile, numLabelUnits map[string]string, cfg config, ui plugin.UI) error { + focus, err := compileRegexOption("focus", cfg.Focus, nil) + ignore, err := compileRegexOption("ignore", cfg.Ignore, err) + hide, err := compileRegexOption("hide", cfg.Hide, err) + show, err := compileRegexOption("show", cfg.Show, err) + showfrom, err := compileRegexOption("show_from", cfg.ShowFrom, err) + tagfocus, err := compileTagFilter("tagfocus", cfg.TagFocus, numLabelUnits, ui, err) + tagignore, err := compileTagFilter("tagignore", cfg.TagIgnore, numLabelUnits, ui, err) + prunefrom, err := compileRegexOption("prune_from", cfg.PruneFrom, err) if err != nil { return err } @@ -54,11 +54,11 @@ func applyFocus(prof *profile.Profile, numLabelUnits map[string]string, v variab warnNoMatches(tagfocus == nil || tfm, "TagFocus", ui) warnNoMatches(tagignore == nil || tim, "TagIgnore", ui) - tagshow, err := compileRegexOption("tagshow", v["tagshow"].value, err) - taghide, err := compileRegexOption("taghide", v["taghide"].value, err) + tagshow, err := compileRegexOption("tagshow", cfg.TagShow, err) + taghide, err := compileRegexOption("taghide", cfg.TagHide, err) tns, tnh := prof.FilterTagsByName(tagshow, taghide) warnNoMatches(tagshow == nil || tns, "TagShow", ui) - warnNoMatches(tagignore == nil || tnh, "TagHide", ui) + warnNoMatches(taghide == nil || tnh, "TagHide", ui) if prunefrom != nil { prof.PruneFrom(prunefrom) diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go index 13613cff86..fbeb765dbc 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go @@ -38,7 +38,10 @@ type treeNode struct { func (ui *webInterface) flamegraph(w http.ResponseWriter, req *http.Request) { // Force the call tree so that the graph is a tree. // Also do not trim the tree so that the flame graph contains all functions. - rpt, errList := ui.makeReport(w, req, []string{"svg"}, "call_tree", "true", "trim", "false") + rpt, errList := ui.makeReport(w, req, []string{"svg"}, func(cfg *config) { + cfg.CallTree = true + cfg.Trim = false + }) if rpt == nil { return // error already reported } @@ -96,7 +99,7 @@ func (ui *webInterface) flamegraph(w http.ResponseWriter, req *http.Request) { return } - ui.render(w, "flamegraph", rpt, errList, config.Labels, webArgs{ + ui.render(w, req, "flamegraph", rpt, errList, config.Labels, webArgs{ FlameGraph: template.JS(b), Nodes: nodeArr, }) diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go index 3a458b0b77..777fb90bfb 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go @@ -34,17 +34,14 @@ var tailDigitsRE = regexp.MustCompile("[0-9]+$") func interactive(p *profile.Profile, o *plugin.Options) error { // Enter command processing loop. o.UI.SetAutoComplete(newCompleter(functionNames(p))) - pprofVariables.set("compact_labels", "true") - pprofVariables["sample_index"].help += fmt.Sprintf("Or use sample_index=name, with name in %v.\n", sampleTypes(p)) + configure("compact_labels", "true") + configHelp["sample_index"] += fmt.Sprintf("Or use sample_index=name, with name in %v.\n", sampleTypes(p)) // Do not wait for the visualizer to complete, to allow multiple // graphs to be visualized simultaneously. interactiveMode = true shortcuts := profileShortcuts(p) - // Get all groups in pprofVariables to allow for clearer error messages. - groups := groupOptions(pprofVariables) - greetings(p, o.UI) for { input, err := o.UI.ReadLine("(pprof) ") @@ -69,7 +66,12 @@ func interactive(p *profile.Profile, o *plugin.Options) error { } value = strings.TrimSpace(value) } - if v := pprofVariables[name]; v != nil { + if isConfigurable(name) { + // All non-bool options require inputs + if len(s) == 1 && !isBoolConfig(name) { + o.UI.PrintErr(fmt.Errorf("please specify a value, e.g. %s=<val>", name)) + continue + } if name == "sample_index" { // Error check sample_index=xxx to ensure xxx is a valid sample type. index, err := p.SampleIndexByName(value) @@ -77,22 +79,16 @@ func interactive(p *profile.Profile, o *plugin.Options) error { o.UI.PrintErr(err) continue } + if index < 0 || index >= len(p.SampleType) { + o.UI.PrintErr(fmt.Errorf("invalid sample_index %q", value)) + continue + } value = p.SampleType[index].Type } - if err := pprofVariables.set(name, value); err != nil { - o.UI.PrintErr(err) - } - continue - } - // Allow group=variable syntax by converting into variable="". - if v := pprofVariables[value]; v != nil && v.group == name { - if err := pprofVariables.set(value, ""); err != nil { + if err := configure(name, value); err != nil { o.UI.PrintErr(err) } continue - } else if okValues := groups[name]; okValues != nil { - o.UI.PrintErr(fmt.Errorf("unrecognized value for %s: %q. Use one of %s", name, value, strings.Join(okValues, ", "))) - continue } } @@ -105,16 +101,16 @@ func interactive(p *profile.Profile, o *plugin.Options) error { case "o", "options": printCurrentOptions(p, o.UI) continue - case "exit", "quit": + case "exit", "quit", "q": return nil case "help": commandHelp(strings.Join(tokens[1:], " "), o.UI) continue } - args, vars, err := parseCommandLine(tokens) + args, cfg, err := parseCommandLine(tokens) if err == nil { - err = generateReportWrapper(p, args, vars, o) + err = generateReportWrapper(p, args, cfg, o) } if err != nil { @@ -124,30 +120,13 @@ func interactive(p *profile.Profile, o *plugin.Options) error { } } -// groupOptions returns a map containing all non-empty groups -// mapped to an array of the option names in that group in -// sorted order. -func groupOptions(vars variables) map[string][]string { - groups := make(map[string][]string) - for name, option := range vars { - group := option.group - if group != "" { - groups[group] = append(groups[group], name) - } - } - for _, names := range groups { - sort.Strings(names) - } - return groups -} - var generateReportWrapper = generateReport // For testing purposes. // greetings prints a brief welcome and some overall profile // information before accepting interactive commands. func greetings(p *profile.Profile, ui plugin.UI) { numLabelUnits := identifyNumLabelUnits(p, ui) - ropt, err := reportOptions(p, numLabelUnits, pprofVariables) + ropt, err := reportOptions(p, numLabelUnits, currentConfig()) if err == nil { rpt := report.New(p, ropt) ui.Print(strings.Join(report.ProfileLabels(rpt), "\n")) @@ -200,27 +179,16 @@ func sampleTypes(p *profile.Profile) []string { func printCurrentOptions(p *profile.Profile, ui plugin.UI) { var args []string - type groupInfo struct { - set string - values []string - } - groups := make(map[string]*groupInfo) - for n, o := range pprofVariables { - v := o.stringValue() + current := currentConfig() + for _, f := range configFields { + n := f.name + v := current.get(f) comment := "" - if g := o.group; g != "" { - gi, ok := groups[g] - if !ok { - gi = &groupInfo{} - groups[g] = gi - } - if o.boolValue() { - gi.set = n - } - gi.values = append(gi.values, n) - continue - } switch { + case len(f.choices) > 0: + values := append([]string{}, f.choices...) + sort.Strings(values) + comment = "[" + strings.Join(values, " | ") + "]" case n == "sample_index": st := sampleTypes(p) if v == "" { @@ -242,18 +210,13 @@ func printCurrentOptions(p *profile.Profile, ui plugin.UI) { } args = append(args, fmt.Sprintf(" %-25s = %-20s %s", n, v, comment)) } - for g, vars := range groups { - sort.Strings(vars.values) - comment := commentStart + " [" + strings.Join(vars.values, " | ") + "]" - args = append(args, fmt.Sprintf(" %-25s = %-20s %s", g, vars.set, comment)) - } sort.Strings(args) ui.Print(strings.Join(args, "\n")) } // parseCommandLine parses a command and returns the pprof command to -// execute and a set of variables for the report. -func parseCommandLine(input []string) ([]string, variables, error) { +// execute and the configuration to use for the report. +func parseCommandLine(input []string) ([]string, config, error) { cmd, args := input[:1], input[1:] name := cmd[0] @@ -267,25 +230,32 @@ func parseCommandLine(input []string) ([]string, variables, error) { } } if c == nil { - return nil, nil, fmt.Errorf("unrecognized command: %q", name) + if _, ok := configHelp[name]; ok { + value := "<val>" + if len(args) > 0 { + value = args[0] + } + return nil, config{}, fmt.Errorf("did you mean: %s=%s", name, value) + } + return nil, config{}, fmt.Errorf("unrecognized command: %q", name) } if c.hasParam { if len(args) == 0 { - return nil, nil, fmt.Errorf("command %s requires an argument", name) + return nil, config{}, fmt.Errorf("command %s requires an argument", name) } cmd = append(cmd, args[0]) args = args[1:] } - // Copy the variables as options set in the command line are not persistent. - vcopy := pprofVariables.makeCopy() + // Copy config since options set in the command line should not persist. + vcopy := currentConfig() var focus, ignore string for i := 0; i < len(args); i++ { t := args[i] - if _, err := strconv.ParseInt(t, 10, 32); err == nil { - vcopy.set("nodecount", t) + if n, err := strconv.ParseInt(t, 10, 32); err == nil { + vcopy.NodeCount = int(n) continue } switch t[0] { @@ -294,14 +264,14 @@ func parseCommandLine(input []string) ([]string, variables, error) { if outputFile == "" { i++ if i >= len(args) { - return nil, nil, fmt.Errorf("unexpected end of line after >") + return nil, config{}, fmt.Errorf("unexpected end of line after >") } outputFile = args[i] } - vcopy.set("output", outputFile) + vcopy.Output = outputFile case '-': if t == "--cum" || t == "-cum" { - vcopy.set("cum", "t") + vcopy.Sort = "cum" continue } ignore = catRegex(ignore, t[1:]) @@ -311,30 +281,27 @@ func parseCommandLine(input []string) ([]string, variables, error) { } if name == "tags" { - updateFocusIgnore(vcopy, "tag", focus, ignore) + if focus != "" { + vcopy.TagFocus = focus + } + if ignore != "" { + vcopy.TagIgnore = ignore + } } else { - updateFocusIgnore(vcopy, "", focus, ignore) + if focus != "" { + vcopy.Focus = focus + } + if ignore != "" { + vcopy.Ignore = ignore + } } - - if vcopy["nodecount"].intValue() == -1 && (name == "text" || name == "top") { - vcopy.set("nodecount", "10") + if vcopy.NodeCount == -1 && (name == "text" || name == "top") { + vcopy.NodeCount = 10 } return cmd, vcopy, nil } -func updateFocusIgnore(v variables, prefix, f, i string) { - if f != "" { - focus := prefix + "focus" - v.set(focus, catRegex(v[focus].value, f)) - } - - if i != "" { - ignore := prefix + "ignore" - v.set(ignore, catRegex(v[ignore].value, i)) - } -} - func catRegex(a, b string) string { if a != "" && b != "" { return a + "|" + b @@ -362,8 +329,8 @@ func commandHelp(args string, ui plugin.UI) { return } - if v := pprofVariables[args]; v != nil { - ui.Print(v.help + "\n") + if help, ok := configHelp[args]; ok { + ui.Print(help + "\n") return } @@ -373,18 +340,17 @@ func commandHelp(args string, ui plugin.UI) { // newCompleter creates an autocompletion function for a set of commands. func newCompleter(fns []string) func(string) string { return func(line string) string { - v := pprofVariables switch tokens := strings.Fields(line); len(tokens) { case 0: // Nothing to complete case 1: // Single token -- complete command name - if match := matchVariableOrCommand(v, tokens[0]); match != "" { + if match := matchVariableOrCommand(tokens[0]); match != "" { return match } case 2: if tokens[0] == "help" { - if match := matchVariableOrCommand(v, tokens[1]); match != "" { + if match := matchVariableOrCommand(tokens[1]); match != "" { return tokens[0] + " " + match } return line @@ -408,26 +374,19 @@ func newCompleter(fns []string) func(string) string { } // matchVariableOrCommand attempts to match a string token to the prefix of a Command. -func matchVariableOrCommand(v variables, token string) string { +func matchVariableOrCommand(token string) string { token = strings.ToLower(token) - found := "" + var matches []string for cmd := range pprofCommands { if strings.HasPrefix(cmd, token) { - if found != "" { - return "" - } - found = cmd + matches = append(matches, cmd) } } - for variable := range v { - if strings.HasPrefix(variable, token) { - if found != "" { - return "" - } - found = variable - } + matches = append(matches, completeConfig(token)...) + if len(matches) == 1 { + return matches[0] } - return found + return "" } // functionCompleter replaces provided substring with a function diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go new file mode 100644 index 0000000000..f72314b185 --- /dev/null +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go @@ -0,0 +1,157 @@ +package driver + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + "os" + "path/filepath" +) + +// settings holds pprof settings. +type settings struct { + // Configs holds a list of named UI configurations. + Configs []namedConfig `json:"configs"` +} + +// namedConfig associates a name with a config. +type namedConfig struct { + Name string `json:"name"` + config +} + +// settingsFileName returns the name of the file where settings should be saved. +func settingsFileName() (string, error) { + // Return "pprof/settings.json" under os.UserConfigDir(). + dir, err := os.UserConfigDir() + if err != nil { + return "", err + } + return filepath.Join(dir, "pprof", "settings.json"), nil +} + +// readSettings reads settings from fname. +func readSettings(fname string) (*settings, error) { + data, err := ioutil.ReadFile(fname) + if err != nil { + if os.IsNotExist(err) { + return &settings{}, nil + } + return nil, fmt.Errorf("could not read settings: %w", err) + } + settings := &settings{} + if err := json.Unmarshal(data, settings); err != nil { + return nil, fmt.Errorf("could not parse settings: %w", err) + } + for i := range settings.Configs { + settings.Configs[i].resetTransient() + } + return settings, nil +} + +// writeSettings saves settings to fname. +func writeSettings(fname string, settings *settings) error { + data, err := json.MarshalIndent(settings, "", " ") + if err != nil { + return fmt.Errorf("could not encode settings: %w", err) + } + + // create the settings directory if it does not exist + // XDG specifies permissions 0700 when creating settings dirs: + // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil { + return fmt.Errorf("failed to create settings directory: %w", err) + } + + if err := ioutil.WriteFile(fname, data, 0644); err != nil { + return fmt.Errorf("failed to write settings: %w", err) + } + return nil +} + +// configMenuEntry holds information for a single config menu entry. +type configMenuEntry struct { + Name string + URL string + Current bool // Is this the currently selected config? + UserConfig bool // Is this a user-provided config? +} + +// configMenu returns a list of items to add to a menu in the web UI. +func configMenu(fname string, url url.URL) []configMenuEntry { + // Start with system configs. + configs := []namedConfig{{Name: "Default", config: defaultConfig()}} + if settings, err := readSettings(fname); err == nil { + // Add user configs. + configs = append(configs, settings.Configs...) + } + + // Convert to menu entries. + result := make([]configMenuEntry, len(configs)) + lastMatch := -1 + for i, cfg := range configs { + dst, changed := cfg.config.makeURL(url) + if !changed { + lastMatch = i + } + result[i] = configMenuEntry{ + Name: cfg.Name, + URL: dst.String(), + UserConfig: (i != 0), + } + } + // Mark the last matching config as currennt + if lastMatch >= 0 { + result[lastMatch].Current = true + } + return result +} + +// editSettings edits settings by applying fn to them. +func editSettings(fname string, fn func(s *settings) error) error { + settings, err := readSettings(fname) + if err != nil { + return err + } + if err := fn(settings); err != nil { + return err + } + return writeSettings(fname, settings) +} + +// setConfig saves the config specified in request to fname. +func setConfig(fname string, request url.URL) error { + q := request.Query() + name := q.Get("config") + if name == "" { + return fmt.Errorf("invalid config name") + } + cfg := currentConfig() + if err := cfg.applyURL(q); err != nil { + return err + } + return editSettings(fname, func(s *settings) error { + for i, c := range s.Configs { + if c.Name == name { + s.Configs[i].config = cfg + return nil + } + } + s.Configs = append(s.Configs, namedConfig{Name: name, config: cfg}) + return nil + }) +} + +// removeConfig removes config from fname. +func removeConfig(fname, config string) error { + return editSettings(fname, func(s *settings) error { + for i, c := range s.Configs { + if c.Name == config { + s.Configs = append(s.Configs[:i], s.Configs[i+1:]...) + return nil + } + } + return fmt.Errorf("config %s not found", config) + }) +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/tempfile.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/tempfile.go index 28679f1c15..b6c8776ff8 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/tempfile.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/tempfile.go @@ -24,9 +24,11 @@ import ( // newTempFile returns a new output file in dir with the provided prefix and suffix. func newTempFile(dir, prefix, suffix string) (*os.File, error) { for index := 1; index < 10000; index++ { - path := filepath.Join(dir, fmt.Sprintf("%s%03d%s", prefix, index, suffix)) - if _, err := os.Stat(path); err != nil { - return os.Create(path) + switch f, err := os.OpenFile(filepath.Join(dir, fmt.Sprintf("%s%03d%s", prefix, index, suffix)), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666); { + case err == nil: + return f, nil + case !os.IsExist(err): + return nil, err } } // Give up @@ -44,11 +46,15 @@ func deferDeleteTempFile(path string) { } // cleanupTempFiles removes any temporary files selected for deferred cleaning. -func cleanupTempFiles() { +func cleanupTempFiles() error { tempFilesMu.Lock() + defer tempFilesMu.Unlock() + var lastErr error for _, f := range tempFiles { - os.Remove(f) + if err := os.Remove(f); err != nil { + lastErr = err + } } tempFiles = nil - tempFilesMu.Unlock() + return lastErr } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go index 89b8882a6b..4f7610c7e5 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go @@ -166,6 +166,73 @@ a { color: gray; pointer-events: none; } +.menu-check-mark { + position: absolute; + left: 2px; +} +.menu-delete-btn { + position: absolute; + right: 2px; +} + +{{/* Used to disable events when a modal dialog is displayed */}} +#dialog-overlay { + display: none; + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + background-color: rgba(1,1,1,0.1); +} + +.dialog { + {{/* Displayed centered horizontally near the top */}} + display: none; + position: fixed; + margin: 0px; + top: 60px; + left: 50%; + transform: translateX(-50%); + + z-index: 3; + font-size: 125%; + background-color: #ffffff; + box-shadow: 0 1px 5px rgba(0,0,0,.3); +} +.dialog-header { + font-size: 120%; + border-bottom: 1px solid #CCCCCC; + width: 100%; + text-align: center; + background: #EEEEEE; + user-select: none; +} +.dialog-footer { + border-top: 1px solid #CCCCCC; + width: 100%; + text-align: right; + padding: 10px; +} +.dialog-error { + margin: 10px; + color: red; +} +.dialog input { + margin: 10px; + font-size: inherit; +} +.dialog button { + margin-left: 10px; + font-size: inherit; +} +#save-dialog, #delete-dialog { + width: 50%; + max-width: 20em; +} +#delete-prompt { + padding: 10px; +} #content { overflow-y: scroll; @@ -200,6 +267,8 @@ table thead { font-family: 'Roboto Medium', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; } table tr th { + position: sticky; + top: 0; background-color: #ddd; text-align: right; padding: .3em .5em; @@ -282,6 +351,24 @@ table tr td { </div> </div> + <div id="config" class="menu-item"> + <div class="menu-name"> + Config + <i class="downArrow"></i> + </div> + <div class="submenu"> + <a title="{{.Help.save_config}}" id="save-config">Save as ...</a> + <hr> + {{range .Configs}} + <a href="{{.URL}}"> + {{if .Current}}<span class="menu-check-mark">✓</span>{{end}} + {{.Name}} + {{if .UserConfig}}<span class="menu-delete-btn" data-config={{.Name}}>🗙</span>{{end}} + </a> + {{end}} + </div> + </div> + <div> <input id="search" type="text" placeholder="Search regexp" autocomplete="off" autocapitalize="none" size=40> </div> @@ -294,6 +381,31 @@ table tr td { </div> </div> +<div id="dialog-overlay"></div> + +<div class="dialog" id="save-dialog"> + <div class="dialog-header">Save options as</div> + <datalist id="config-list"> + {{range .Configs}}{{if .UserConfig}}<option value="{{.Name}}" />{{end}}{{end}} + </datalist> + <input id="save-name" type="text" list="config-list" placeholder="New config" /> + <div class="dialog-footer"> + <span class="dialog-error" id="save-error"></span> + <button id="save-cancel">Cancel</button> + <button id="save-confirm">Save</button> + </div> +</div> + +<div class="dialog" id="delete-dialog"> + <div class="dialog-header" id="delete-dialog-title">Delete config</div> + <div id="delete-prompt"></div> + <div class="dialog-footer"> + <span class="dialog-error" id="delete-error"></span> + <button id="delete-cancel">Cancel</button> + <button id="delete-confirm">Delete</button> + </div> +</div> + <div id="errors">{{range .Errors}}<div>{{.}}</div>{{end}}</div> {{end}} @@ -583,6 +695,131 @@ function initMenus() { }, { passive: true, capture: true }); } +function sendURL(method, url, done) { + fetch(url.toString(), {method: method}) + .then((response) => { done(response.ok); }) + .catch((error) => { done(false); }); +} + +// Initialize handlers for saving/loading configurations. +function initConfigManager() { + 'use strict'; + + // Initialize various elements. + function elem(id) { + const result = document.getElementById(id); + if (!result) console.warn('element ' + id + ' not found'); + return result; + } + const overlay = elem('dialog-overlay'); + const saveDialog = elem('save-dialog'); + const saveInput = elem('save-name'); + const saveError = elem('save-error'); + const delDialog = elem('delete-dialog'); + const delPrompt = elem('delete-prompt'); + const delError = elem('delete-error'); + + let currentDialog = null; + let currentDeleteTarget = null; + + function showDialog(dialog) { + if (currentDialog != null) { + overlay.style.display = 'none'; + currentDialog.style.display = 'none'; + } + currentDialog = dialog; + if (dialog != null) { + overlay.style.display = 'block'; + dialog.style.display = 'block'; + } + } + + function cancelDialog(e) { + showDialog(null); + } + + // Show dialog for saving the current config. + function showSaveDialog(e) { + saveError.innerText = ''; + showDialog(saveDialog); + saveInput.focus(); + } + + // Commit save config. + function commitSave(e) { + const name = saveInput.value; + const url = new URL(document.URL); + // Set path relative to existing path. + url.pathname = new URL('./saveconfig', document.URL).pathname; + url.searchParams.set('config', name); + saveError.innerText = ''; + sendURL('POST', url, (ok) => { + if (!ok) { + saveError.innerText = 'Save failed'; + } else { + showDialog(null); + location.reload(); // Reload to show updated config menu + } + }); + } + + function handleSaveInputKey(e) { + if (e.key === 'Enter') commitSave(e); + } + + function deleteConfig(e, elem) { + e.preventDefault(); + const config = elem.dataset.config; + delPrompt.innerText = 'Delete ' + config + '?'; + currentDeleteTarget = elem; + showDialog(delDialog); + } + + function commitDelete(e, elem) { + if (!currentDeleteTarget) return; + const config = currentDeleteTarget.dataset.config; + const url = new URL('./deleteconfig', document.URL); + url.searchParams.set('config', config); + delError.innerText = ''; + sendURL('DELETE', url, (ok) => { + if (!ok) { + delError.innerText = 'Delete failed'; + return; + } + showDialog(null); + // Remove menu entry for this config. + if (currentDeleteTarget && currentDeleteTarget.parentElement) { + currentDeleteTarget.parentElement.remove(); + } + }); + } + + // Bind event on elem to fn. + function bind(event, elem, fn) { + if (elem == null) return; + elem.addEventListener(event, fn); + if (event == 'click') { + // Also enable via touch. + elem.addEventListener('touchstart', fn); + } + } + + bind('click', elem('save-config'), showSaveDialog); + bind('click', elem('save-cancel'), cancelDialog); + bind('click', elem('save-confirm'), commitSave); + bind('keydown', saveInput, handleSaveInputKey); + + bind('click', elem('delete-cancel'), cancelDialog); + bind('click', elem('delete-confirm'), commitDelete); + + // Activate deletion button for all config entries in menu. + for (const del of Array.from(document.getElementsByClassName('menu-delete-btn'))) { + bind('click', del, (e) => { + deleteConfig(e, del); + }); + } +} + function viewer(baseUrl, nodes) { 'use strict'; @@ -875,6 +1112,7 @@ function viewer(baseUrl, nodes) { } addAction('details', handleDetails); + initConfigManager(); search.addEventListener('input', handleSearch); search.addEventListener('keydown', handleKey); diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go index 4006085538..52dc68809c 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go @@ -35,22 +35,28 @@ import ( // webInterface holds the state needed for serving a browser based interface. type webInterface struct { - prof *profile.Profile - options *plugin.Options - help map[string]string - templates *template.Template + prof *profile.Profile + options *plugin.Options + help map[string]string + templates *template.Template + settingsFile string } -func makeWebInterface(p *profile.Profile, opt *plugin.Options) *webInterface { +func makeWebInterface(p *profile.Profile, opt *plugin.Options) (*webInterface, error) { + settingsFile, err := settingsFileName() + if err != nil { + return nil, err + } templates := template.New("templategroup") addTemplates(templates) report.AddSourceTemplates(templates) return &webInterface{ - prof: p, - options: opt, - help: make(map[string]string), - templates: templates, - } + prof: p, + options: opt, + help: make(map[string]string), + templates: templates, + settingsFile: settingsFile, + }, nil } // maxEntries is the maximum number of entries to print for text interfaces. @@ -80,6 +86,7 @@ type webArgs struct { TextBody string Top []report.TextItem FlameGraph template.JS + Configs []configMenuEntry } func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, disableBrowser bool) error { @@ -88,16 +95,20 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, d return err } interactiveMode = true - ui := makeWebInterface(p, o) + ui, err := makeWebInterface(p, o) + if err != nil { + return err + } for n, c := range pprofCommands { ui.help[n] = c.description } - for n, v := range pprofVariables { - ui.help[n] = v.help + for n, help := range configHelp { + ui.help[n] = help } ui.help["details"] = "Show information about the profile and this view" ui.help["graph"] = "Display profile as a directed graph" ui.help["reset"] = "Show the entire profile" + ui.help["save_config"] = "Save current settings" server := o.HTTPServer if server == nil { @@ -108,12 +119,14 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, d Host: host, Port: port, Handlers: map[string]http.Handler{ - "/": http.HandlerFunc(ui.dot), - "/top": http.HandlerFunc(ui.top), - "/disasm": http.HandlerFunc(ui.disasm), - "/source": http.HandlerFunc(ui.source), - "/peek": http.HandlerFunc(ui.peek), - "/flamegraph": http.HandlerFunc(ui.flamegraph), + "/": http.HandlerFunc(ui.dot), + "/top": http.HandlerFunc(ui.top), + "/disasm": http.HandlerFunc(ui.disasm), + "/source": http.HandlerFunc(ui.source), + "/peek": http.HandlerFunc(ui.peek), + "/flamegraph": http.HandlerFunc(ui.flamegraph), + "/saveconfig": http.HandlerFunc(ui.saveConfig), + "/deleteconfig": http.HandlerFunc(ui.deleteConfig), }, } @@ -206,21 +219,9 @@ func isLocalhost(host string) bool { func openBrowser(url string, o *plugin.Options) { // Construct URL. - u, _ := gourl.Parse(url) - q := u.Query() - for _, p := range []struct{ param, key string }{ - {"f", "focus"}, - {"s", "show"}, - {"sf", "show_from"}, - {"i", "ignore"}, - {"h", "hide"}, - {"si", "sample_index"}, - } { - if v := pprofVariables[p.key].value; v != "" { - q.Set(p.param, v) - } - } - u.RawQuery = q.Encode() + baseURL, _ := gourl.Parse(url) + current := currentConfig() + u, _ := current.makeURL(*baseURL) // Give server a little time to get ready. time.Sleep(time.Millisecond * 500) @@ -240,28 +241,23 @@ func openBrowser(url string, o *plugin.Options) { o.UI.PrintErr(u.String()) } -func varsFromURL(u *gourl.URL) variables { - vars := pprofVariables.makeCopy() - vars["focus"].value = u.Query().Get("f") - vars["show"].value = u.Query().Get("s") - vars["show_from"].value = u.Query().Get("sf") - vars["ignore"].value = u.Query().Get("i") - vars["hide"].value = u.Query().Get("h") - vars["sample_index"].value = u.Query().Get("si") - return vars -} - // makeReport generates a report for the specified command. +// If configEditor is not null, it is used to edit the config used for the report. func (ui *webInterface) makeReport(w http.ResponseWriter, req *http.Request, - cmd []string, vars ...string) (*report.Report, []string) { - v := varsFromURL(req.URL) - for i := 0; i+1 < len(vars); i += 2 { - v[vars[i]].value = vars[i+1] + cmd []string, configEditor func(*config)) (*report.Report, []string) { + cfg := currentConfig() + if err := cfg.applyURL(req.URL.Query()); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + ui.options.UI.PrintErr(err) + return nil, nil + } + if configEditor != nil { + configEditor(&cfg) } catcher := &errorCatcher{UI: ui.options.UI} options := *ui.options options.UI = catcher - _, rpt, err := generateRawReport(ui.prof, cmd, v, &options) + _, rpt, err := generateRawReport(ui.prof, cmd, cfg, &options) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) ui.options.UI.PrintErr(err) @@ -271,7 +267,7 @@ func (ui *webInterface) makeReport(w http.ResponseWriter, req *http.Request, } // render generates html using the named template based on the contents of data. -func (ui *webInterface) render(w http.ResponseWriter, tmpl string, +func (ui *webInterface) render(w http.ResponseWriter, req *http.Request, tmpl string, rpt *report.Report, errList, legend []string, data webArgs) { file := getFromLegend(legend, "File: ", "unknown") profile := getFromLegend(legend, "Type: ", "unknown") @@ -281,6 +277,8 @@ func (ui *webInterface) render(w http.ResponseWriter, tmpl string, data.SampleTypes = sampleTypes(ui.prof) data.Legend = legend data.Help = ui.help + data.Configs = configMenu(ui.settingsFile, *req.URL) + html := &bytes.Buffer{} if err := ui.templates.ExecuteTemplate(html, tmpl, data); err != nil { http.Error(w, "internal template error", http.StatusInternalServerError) @@ -293,7 +291,7 @@ func (ui *webInterface) render(w http.ResponseWriter, tmpl string, // dot generates a web page containing an svg diagram. func (ui *webInterface) dot(w http.ResponseWriter, req *http.Request) { - rpt, errList := ui.makeReport(w, req, []string{"svg"}) + rpt, errList := ui.makeReport(w, req, []string{"svg"}, nil) if rpt == nil { return // error already reported } @@ -320,7 +318,7 @@ func (ui *webInterface) dot(w http.ResponseWriter, req *http.Request) { nodes = append(nodes, n.Info.Name) } - ui.render(w, "graph", rpt, errList, legend, webArgs{ + ui.render(w, req, "graph", rpt, errList, legend, webArgs{ HTMLBody: template.HTML(string(svg)), Nodes: nodes, }) @@ -345,7 +343,9 @@ func dotToSvg(dot []byte) ([]byte, error) { } func (ui *webInterface) top(w http.ResponseWriter, req *http.Request) { - rpt, errList := ui.makeReport(w, req, []string{"top"}, "nodecount", "500") + rpt, errList := ui.makeReport(w, req, []string{"top"}, func(cfg *config) { + cfg.NodeCount = 500 + }) if rpt == nil { return // error already reported } @@ -355,7 +355,7 @@ func (ui *webInterface) top(w http.ResponseWriter, req *http.Request) { nodes = append(nodes, item.Name) } - ui.render(w, "top", rpt, errList, legend, webArgs{ + ui.render(w, req, "top", rpt, errList, legend, webArgs{ Top: top, Nodes: nodes, }) @@ -364,7 +364,7 @@ func (ui *webInterface) top(w http.ResponseWriter, req *http.Request) { // disasm generates a web page containing disassembly. func (ui *webInterface) disasm(w http.ResponseWriter, req *http.Request) { args := []string{"disasm", req.URL.Query().Get("f")} - rpt, errList := ui.makeReport(w, req, args) + rpt, errList := ui.makeReport(w, req, args, nil) if rpt == nil { return // error already reported } @@ -377,7 +377,7 @@ func (ui *webInterface) disasm(w http.ResponseWriter, req *http.Request) { } legend := report.ProfileLabels(rpt) - ui.render(w, "plaintext", rpt, errList, legend, webArgs{ + ui.render(w, req, "plaintext", rpt, errList, legend, webArgs{ TextBody: out.String(), }) @@ -387,7 +387,7 @@ func (ui *webInterface) disasm(w http.ResponseWriter, req *http.Request) { // data. func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) { args := []string{"weblist", req.URL.Query().Get("f")} - rpt, errList := ui.makeReport(w, req, args) + rpt, errList := ui.makeReport(w, req, args, nil) if rpt == nil { return // error already reported } @@ -401,7 +401,7 @@ func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) { } legend := report.ProfileLabels(rpt) - ui.render(w, "sourcelisting", rpt, errList, legend, webArgs{ + ui.render(w, req, "sourcelisting", rpt, errList, legend, webArgs{ HTMLBody: template.HTML(body.String()), }) } @@ -409,7 +409,9 @@ func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) { // peek generates a web page listing callers/callers. func (ui *webInterface) peek(w http.ResponseWriter, req *http.Request) { args := []string{"peek", req.URL.Query().Get("f")} - rpt, errList := ui.makeReport(w, req, args, "lines", "t") + rpt, errList := ui.makeReport(w, req, args, func(cfg *config) { + cfg.Granularity = "lines" + }) if rpt == nil { return // error already reported } @@ -422,11 +424,30 @@ func (ui *webInterface) peek(w http.ResponseWriter, req *http.Request) { } legend := report.ProfileLabels(rpt) - ui.render(w, "plaintext", rpt, errList, legend, webArgs{ + ui.render(w, req, "plaintext", rpt, errList, legend, webArgs{ TextBody: out.String(), }) } +// saveConfig saves URL configuration. +func (ui *webInterface) saveConfig(w http.ResponseWriter, req *http.Request) { + if err := setConfig(ui.settingsFile, *req.URL); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + ui.options.UI.PrintErr(err) + return + } +} + +// deleteConfig deletes a configuration. +func (ui *webInterface) deleteConfig(w http.ResponseWriter, req *http.Request) { + name := req.URL.Query().Get("config") + if err := removeConfig(ui.settingsFile, name); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + ui.options.UI.PrintErr(err) + return + } +} + // getFromLegend returns the suffix of an entry in legend that starts // with param. It returns def if no such entry is found. func getFromLegend(legend []string, param, def string) string { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go index 09debfb007..8cb87da9af 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go @@ -127,7 +127,7 @@ func (b *builder) addLegend() { } title := labels[0] fmt.Fprintf(b, `subgraph cluster_L { "%s" [shape=box fontsize=16`, title) - fmt.Fprintf(b, ` label="%s\l"`, strings.Join(labels, `\l`)) + fmt.Fprintf(b, ` label="%s\l"`, strings.Join(escapeAllForDot(labels), `\l`)) if b.config.LegendURL != "" { fmt.Fprintf(b, ` URL="%s" target="_blank"`, b.config.LegendURL) } @@ -187,7 +187,7 @@ func (b *builder) addNode(node *Node, nodeID int, maxFlat float64) { // Create DOT attribute for node. attr := fmt.Sprintf(`label="%s" id="node%d" fontsize=%d shape=%s tooltip="%s (%s)" color="%s" fillcolor="%s"`, - label, nodeID, fontSize, shape, node.Info.PrintableName(), cumValue, + label, nodeID, fontSize, shape, escapeForDot(node.Info.PrintableName()), cumValue, dotColor(float64(node.CumValue())/float64(abs64(b.config.Total)), false), dotColor(float64(node.CumValue())/float64(abs64(b.config.Total)), true)) @@ -305,7 +305,8 @@ func (b *builder) addEdge(edge *Edge, from, to int, hasNodelets bool) { arrow = "..." } tooltip := fmt.Sprintf(`"%s %s %s (%s)"`, - edge.Src.Info.PrintableName(), arrow, edge.Dest.Info.PrintableName(), w) + escapeForDot(edge.Src.Info.PrintableName()), arrow, + escapeForDot(edge.Dest.Info.PrintableName()), w) attr = fmt.Sprintf(`%s tooltip=%s labeltooltip=%s`, attr, tooltip, tooltip) if edge.Residual { @@ -382,7 +383,7 @@ func dotColor(score float64, isBackground bool) string { func multilinePrintableName(info *NodeInfo) string { infoCopy := *info - infoCopy.Name = ShortenFunctionName(infoCopy.Name) + infoCopy.Name = escapeForDot(ShortenFunctionName(infoCopy.Name)) infoCopy.Name = strings.Replace(infoCopy.Name, "::", `\n`, -1) infoCopy.Name = strings.Replace(infoCopy.Name, ".", `\n`, -1) if infoCopy.File != "" { @@ -472,3 +473,19 @@ func min64(a, b int64) int64 { } return b } + +// escapeAllForDot applies escapeForDot to all strings in the given slice. +func escapeAllForDot(in []string) []string { + var out = make([]string, len(in)) + for i := range in { + out[i] = escapeForDot(in[i]) + } + return out +} + +// escapeForDot escapes double quotes and backslashes, and replaces Graphviz's +// "center" character (\n) with a left-justified character. +// See https://graphviz.org/doc/info/attrs.html#k:escString for more info. +func escapeForDot(str string) string { + return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(str, `\`, `\\`), `"`, `\"`), "\n", `\l`) +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go index d2397a93d8..74b904c402 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go @@ -28,12 +28,14 @@ import ( ) var ( - // Removes package name and method arugments for Java method names. + // Removes package name and method arguments for Java method names. // See tests for examples. javaRegExp = regexp.MustCompile(`^(?:[a-z]\w*\.)*([A-Z][\w\$]*\.(?:<init>|[a-z][\w\$]*(?:\$\d+)?))(?:(?:\()|$)`) - // Removes package name and method arugments for Go function names. + // Removes package name and method arguments for Go function names. // See tests for examples. goRegExp = regexp.MustCompile(`^(?:[\w\-\.]+\/)+(.+)`) + // Removes potential module versions in a package path. + goVerRegExp = regexp.MustCompile(`^(.*?)/v(?:[2-9]|[1-9][0-9]+)([./].*)$`) // Strips C++ namespace prefix from a C++ function / method name. // NOTE: Make sure to keep the template parameters in the name. Normally, // template parameters are stripped from the C++ names but when @@ -317,6 +319,8 @@ func New(prof *profile.Profile, o *Options) *Graph { // nodes. func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) { nodes, locationMap := CreateNodes(prof, o) + seenNode := make(map[*Node]bool) + seenEdge := make(map[nodePair]bool) for _, sample := range prof.Sample { var w, dw int64 w = o.SampleValue(sample.Value) @@ -326,8 +330,12 @@ func newGraph(prof *profile.Profile, o *Options) (*Graph, map[uint64]Nodes) { if dw == 0 && w == 0 { continue } - seenNode := make(map[*Node]bool, len(sample.Location)) - seenEdge := make(map[nodePair]bool, len(sample.Location)) + for k := range seenNode { + delete(seenNode, k) + } + for k := range seenEdge { + delete(seenEdge, k) + } var parent *Node // A residual edge goes over one or more nodes that were not kept. residual := false @@ -440,6 +448,7 @@ func newTree(prof *profile.Profile, o *Options) (g *Graph) { // ShortenFunctionName returns a shortened version of a function's name. func ShortenFunctionName(f string) string { f = cppAnonymousPrefixRegExp.ReplaceAllString(f, "") + f = goVerRegExp.ReplaceAllString(f, `${1}${2}`) for _, re := range []*regexp.Regexp{goRegExp, javaRegExp, cppRegExp} { if matches := re.FindStringSubmatch(f); len(matches) >= 2 { return strings.Join(matches[1:], "") diff --git a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go index 4c1db2331f..3a8d0af730 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go @@ -114,7 +114,7 @@ type ObjTool interface { // Disasm disassembles the named object file, starting at // the start address and stopping at (before) the end address. - Disasm(file string, start, end uint64) ([]Inst, error) + Disasm(file string, start, end uint64, intelSyntax bool) ([]Inst, error) } // An Inst is a single instruction in an assembly listing. diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go index 56083d8abf..bc5685d61e 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go @@ -79,6 +79,8 @@ type Options struct { Symbol *regexp.Regexp // Symbols to include on disassembly report. SourcePath string // Search path for source files. TrimPath string // Paths to trim from source file paths. + + IntelSyntax bool // Whether or not to print assembly in Intel syntax. } // Generate generates a report as directed by the Report. @@ -438,7 +440,7 @@ func PrintAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFuncs int) e flatSum, cumSum := sns.Sum() // Get the function assembly. - insts, err := obj.Disasm(s.sym.File, s.sym.Start, s.sym.End) + insts, err := obj.Disasm(s.sym.File, s.sym.Start, s.sym.End, o.IntelSyntax) if err != nil { return err } @@ -1201,6 +1203,13 @@ func reportLabels(rpt *Report, g *graph.Graph, origCount, droppedNodes, droppedE nodeCount, origCount)) } } + + // Help new users understand the graph. + // A new line is intentionally added here to better show this message. + if fullHeaders { + label = append(label, "\nSee https://git.io/JfYMW for how to read the graph") + } + return label } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go index ab8b64cbab..b480535439 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/source.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/source.go @@ -205,7 +205,7 @@ func PrintWebList(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFiles int) er ff := fileFunction{n.Info.File, n.Info.Name} fns := fileNodes[ff] - asm := assemblyPerSourceLine(symbols, fns, ff.fileName, obj) + asm := assemblyPerSourceLine(symbols, fns, ff.fileName, obj, o.IntelSyntax) start, end := sourceCoordinates(asm) fnodes, path, err := getSourceFromFile(ff.fileName, reader, fns, start, end) @@ -239,7 +239,7 @@ func sourceCoordinates(asm map[int][]assemblyInstruction) (start, end int) { // assemblyPerSourceLine disassembles the binary containing a symbol // and classifies the assembly instructions according to its // corresponding source line, annotating them with a set of samples. -func assemblyPerSourceLine(objSyms []*objSymbol, rs graph.Nodes, src string, obj plugin.ObjTool) map[int][]assemblyInstruction { +func assemblyPerSourceLine(objSyms []*objSymbol, rs graph.Nodes, src string, obj plugin.ObjTool, intelSyntax bool) map[int][]assemblyInstruction { assembly := make(map[int][]assemblyInstruction) // Identify symbol to use for this collection of samples. o := findMatchingSymbol(objSyms, rs) @@ -248,7 +248,7 @@ func assemblyPerSourceLine(objSyms []*objSymbol, rs graph.Nodes, src string, obj } // Extract assembly for matched symbol - insts, err := obj.Disasm(o.sym.File, o.sym.Start, o.sym.End) + insts, err := obj.Disasm(o.sym.File, o.sym.Start, o.sym.End, intelSyntax) if err != nil { return assembly } diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile.go b/src/cmd/vendor/github.com/google/pprof/profile/profile.go index c950d8dc7f..d94d8b3d1c 100644 --- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go +++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go @@ -398,10 +398,12 @@ func (p *Profile) CheckValid() error { } } for _, ln := range l.Line { - if f := ln.Function; f != nil { - if f.ID == 0 || functions[f.ID] != f { - return fmt.Errorf("inconsistent function %p: %d", f, f.ID) - } + f := ln.Function + if f == nil { + return fmt.Errorf("location id: %d has a line with nil function", l.ID) + } + if f.ID == 0 || functions[f.ID] != f { + return fmt.Errorf("inconsistent function %p: %d", f, f.ID) } } } diff --git a/src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go b/src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go index 0ad5354f58..ccbe5b3559 100644 --- a/src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go +++ b/src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go @@ -5,7 +5,6 @@ package demangle import ( - "bytes" "fmt" "strings" ) @@ -23,7 +22,10 @@ type AST interface { // Copy an AST with possible transformations. // If the skip function returns true, no copy is required. // If the copy function returns nil, no copy is required. - // Otherwise the AST returned by copy is used in a copy of the full AST. + // The Copy method will do the right thing if copy returns nil + // for some components of an AST but not others, so a good + // copy function will only return non-nil for AST values that + // need to change. // Copy itself returns either a copy or nil. Copy(copy func(AST) AST, skip func(AST) bool) AST @@ -51,7 +53,7 @@ func ASTToString(a AST, options ...Option) string { type printState struct { tparams bool // whether to print template parameters - buf bytes.Buffer + buf strings.Builder last byte // Last byte written to buffer. // The inner field is a list of items to print for a type @@ -398,13 +400,172 @@ func (tp *TemplateParam) goString(indent int, field string) string { return fmt.Sprintf("%*s%sTemplateParam: Template: %p; Index %d", indent, "", field, tp.Template, tp.Index) } +// LambdaAuto is a lambda auto parameter. +type LambdaAuto struct { + Index int +} + +func (la *LambdaAuto) print(ps *printState) { + // We print the index plus 1 because that is what the standard + // demangler does. + fmt.Fprintf(&ps.buf, "auto:%d", la.Index+1) +} + +func (la *LambdaAuto) Traverse(fn func(AST) bool) { + fn(la) +} + +func (la *LambdaAuto) Copy(fn func(AST) AST, skip func(AST) bool) AST { + if skip(la) { + return nil + } + return fn(la) +} + +func (la *LambdaAuto) GoString() string { + return la.goString(0, "") +} + +func (la *LambdaAuto) goString(indent int, field string) string { + return fmt.Sprintf("%*s%sLambdaAuto: Index %d", indent, "", field, la.Index) +} + // Qualifiers is an ordered list of type qualifiers. -type Qualifiers []string +type Qualifiers struct { + Qualifiers []AST +} + +func (qs *Qualifiers) print(ps *printState) { + first := true + for _, q := range qs.Qualifiers { + if !first { + ps.writeByte(' ') + } + q.print(ps) + first = false + } +} + +func (qs *Qualifiers) Traverse(fn func(AST) bool) { + if fn(qs) { + for _, q := range qs.Qualifiers { + q.Traverse(fn) + } + } +} + +func (qs *Qualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST { + if skip(qs) { + return nil + } + changed := false + qualifiers := make([]AST, len(qs.Qualifiers)) + for i, q := range qs.Qualifiers { + qc := q.Copy(fn, skip) + if qc == nil { + qualifiers[i] = q + } else { + qualifiers[i] = qc + changed = true + } + } + if !changed { + return fn(qs) + } + qs = &Qualifiers{Qualifiers: qualifiers} + if r := fn(qs); r != nil { + return r + } + return qs +} + +func (qs *Qualifiers) GoString() string { + return qs.goString(0, "") +} + +func (qs *Qualifiers) goString(indent int, field string) string { + quals := fmt.Sprintf("%*s%s", indent, "", field) + for _, q := range qs.Qualifiers { + quals += "\n" + quals += q.goString(indent+2, "") + } + return quals +} + +// Qualifier is a single type qualifier. +type Qualifier struct { + Name string // qualifier name: const, volatile, etc. + Exprs []AST // can be non-nil for noexcept and throw +} + +func (q *Qualifier) print(ps *printState) { + ps.writeString(q.Name) + if len(q.Exprs) > 0 { + ps.writeByte('(') + first := true + for _, e := range q.Exprs { + if !first { + ps.writeString(", ") + } + ps.print(e) + first = false + } + ps.writeByte(')') + } +} + +func (q *Qualifier) Traverse(fn func(AST) bool) { + if fn(q) { + for _, e := range q.Exprs { + e.Traverse(fn) + } + } +} + +func (q *Qualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST { + if skip(q) { + return nil + } + exprs := make([]AST, len(q.Exprs)) + changed := false + for i, e := range q.Exprs { + ec := e.Copy(fn, skip) + if ec == nil { + exprs[i] = e + } else { + exprs[i] = ec + changed = true + } + } + if !changed { + return fn(q) + } + q = &Qualifier{Name: q.Name, Exprs: exprs} + if r := fn(q); r != nil { + return r + } + return q +} + +func (q *Qualifier) GoString() string { + return q.goString(0, "Qualifier: ") +} + +func (q *Qualifier) goString(indent int, field string) string { + qs := fmt.Sprintf("%*s%s%s", indent, "", field, q.Name) + if len(q.Exprs) > 0 { + for i, e := range q.Exprs { + qs += "\n" + qs += e.goString(indent+2, fmt.Sprintf("%d: ", i)) + } + } + return qs +} // TypeWithQualifiers is a type with standard qualifiers. type TypeWithQualifiers struct { Base AST - Qualifiers Qualifiers + Qualifiers AST } func (twq *TypeWithQualifiers) print(ps *printState) { @@ -414,7 +575,7 @@ func (twq *TypeWithQualifiers) print(ps *printState) { if len(ps.inner) > 0 { // The qualifier wasn't printed by Base. ps.writeByte(' ') - ps.writeString(strings.Join(twq.Qualifiers, " ")) + ps.print(twq.Qualifiers) ps.inner = ps.inner[:len(ps.inner)-1] } } @@ -422,7 +583,7 @@ func (twq *TypeWithQualifiers) print(ps *printState) { // Print qualifiers as an inner type by just printing the qualifiers. func (twq *TypeWithQualifiers) printInner(ps *printState) { ps.writeByte(' ') - ps.writeString(strings.Join(twq.Qualifiers, " ")) + ps.print(twq.Qualifiers) } func (twq *TypeWithQualifiers) Traverse(fn func(AST) bool) { @@ -436,10 +597,17 @@ func (twq *TypeWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST { return nil } base := twq.Base.Copy(fn, skip) - if base == nil { + quals := twq.Qualifiers.Copy(fn, skip) + if base == nil && quals == nil { return fn(twq) } - twq = &TypeWithQualifiers{Base: base, Qualifiers: twq.Qualifiers} + if base == nil { + base = twq.Base + } + if quals == nil { + quals = twq.Qualifiers + } + twq = &TypeWithQualifiers{Base: base, Qualifiers: quals} if r := fn(twq); r != nil { return r } @@ -451,14 +619,15 @@ func (twq *TypeWithQualifiers) GoString() string { } func (twq *TypeWithQualifiers) goString(indent int, field string) string { - return fmt.Sprintf("%*s%sTypeWithQualifiers: Qualifiers: %s\n%s", indent, "", field, - twq.Qualifiers, twq.Base.goString(indent+2, "Base: ")) + return fmt.Sprintf("%*s%sTypeWithQualifiers:\n%s\n%s", indent, "", field, + twq.Qualifiers.goString(indent+2, "Qualifiers: "), + twq.Base.goString(indent+2, "Base: ")) } // MethodWithQualifiers is a method with qualifiers. type MethodWithQualifiers struct { Method AST - Qualifiers Qualifiers + Qualifiers AST RefQualifier string // "" or "&" or "&&" } @@ -467,9 +636,9 @@ func (mwq *MethodWithQualifiers) print(ps *printState) { ps.inner = append(ps.inner, mwq) ps.print(mwq.Method) if len(ps.inner) > 0 { - if len(mwq.Qualifiers) > 0 { + if mwq.Qualifiers != nil { ps.writeByte(' ') - ps.writeString(strings.Join(mwq.Qualifiers, " ")) + ps.print(mwq.Qualifiers) } if mwq.RefQualifier != "" { ps.writeByte(' ') @@ -480,9 +649,9 @@ func (mwq *MethodWithQualifiers) print(ps *printState) { } func (mwq *MethodWithQualifiers) printInner(ps *printState) { - if len(mwq.Qualifiers) > 0 { + if mwq.Qualifiers != nil { ps.writeByte(' ') - ps.writeString(strings.Join(mwq.Qualifiers, " ")) + ps.print(mwq.Qualifiers) } if mwq.RefQualifier != "" { ps.writeByte(' ') @@ -501,10 +670,20 @@ func (mwq *MethodWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST return nil } method := mwq.Method.Copy(fn, skip) - if method == nil { + var quals AST + if mwq.Qualifiers != nil { + quals = mwq.Qualifiers.Copy(fn, skip) + } + if method == nil && quals == nil { return fn(mwq) } - mwq = &MethodWithQualifiers{Method: method, Qualifiers: mwq.Qualifiers, RefQualifier: mwq.RefQualifier} + if method == nil { + method = mwq.Method + } + if quals == nil { + quals = mwq.Qualifiers + } + mwq = &MethodWithQualifiers{Method: method, Qualifiers: quals, RefQualifier: mwq.RefQualifier} if r := fn(mwq); r != nil { return r } @@ -517,14 +696,14 @@ func (mwq *MethodWithQualifiers) GoString() string { func (mwq *MethodWithQualifiers) goString(indent int, field string) string { var q string - if len(mwq.Qualifiers) > 0 { - q += fmt.Sprintf(" Qualifiers: %v", mwq.Qualifiers) + if mwq.Qualifiers != nil { + q += "\n" + mwq.Qualifiers.goString(indent+2, "Qualifiers: ") } if mwq.RefQualifier != "" { if q != "" { - q += ";" + q += "\n" } - q += " RefQualifier: " + mwq.RefQualifier + q += fmt.Sprintf("%*s%s%s", indent+2, "", "RefQualifier: ", mwq.RefQualifier) } return fmt.Sprintf("%*s%sMethodWithQualifiers:%s\n%s", indent, "", field, q, mwq.Method.goString(indent+2, "Method: ")) @@ -1955,6 +2134,22 @@ func (u *Unary) goString(indent int, field string) string { u.Expr.goString(indent+2, "Expr: ")) } +// isDesignatedInitializer reports whether x is a designated +// initializer. +func isDesignatedInitializer(x AST) bool { + switch x := x.(type) { + case *Binary: + if op, ok := x.Op.(*Operator); ok { + return op.Name == "=" || op.Name == "]=" + } + case *Trinary: + if op, ok := x.Op.(*Operator); ok { + return op.Name == "[...]=" + } + } + return false +} + // Binary is a binary operation in an expression. type Binary struct { Op AST @@ -1975,6 +2170,27 @@ func (b *Binary) print(ps *printState) { return } + if isDesignatedInitializer(b) { + if op.Name == "=" { + ps.writeByte('.') + } else { + ps.writeByte('[') + } + ps.print(b.Left) + if op.Name == "]=" { + ps.writeByte(']') + } + if isDesignatedInitializer(b.Right) { + // Don't add anything between designated + // initializer chains. + ps.print(b.Right) + } else { + ps.writeByte('=') + parenthesize(ps, b.Right) + } + return + } + // Use an extra set of parentheses around an expression that // uses the greater-than operator, so that it does not get // confused with the '>' that ends template parameters. @@ -1984,15 +2200,28 @@ func (b *Binary) print(ps *printState) { left := b.Left - // A function call in an expression should not print the types - // of the arguments. + // For a function call in an expression, don't print the types + // of the arguments unless there is a return type. + skipParens := false if op != nil && op.Name == "()" { if ty, ok := b.Left.(*Typed); ok { - left = ty.Name + if ft, ok := ty.Type.(*FunctionType); ok { + if ft.Return == nil { + left = ty.Name + } else { + skipParens = true + } + } else { + left = ty.Name + } } } - parenthesize(ps, left) + if skipParens { + ps.print(left) + } else { + parenthesize(ps, left) + } if op != nil && op.Name == "[]" { ps.writeByte('[') @@ -2070,6 +2299,23 @@ type Trinary struct { } func (t *Trinary) print(ps *printState) { + if isDesignatedInitializer(t) { + ps.writeByte('[') + ps.print(t.First) + ps.writeString(" ... ") + ps.print(t.Second) + ps.writeByte(']') + if isDesignatedInitializer(t.Third) { + // Don't add anything between designated + // initializer chains. + ps.print(t.Third) + } else { + ps.writeByte('=') + parenthesize(ps, t.Third) + } + return + } + parenthesize(ps, t.First) ps.writeByte('?') parenthesize(ps, t.Second) @@ -2362,6 +2608,9 @@ func (l *Literal) print(ps *printState) { ps.writeString("true") return } + } else if b.Name == "decltype(nullptr)" && l.Val == "" { + ps.print(l.Type) + return } else { isFloat = builtinTypeFloat[b.Name] } @@ -2821,6 +3070,83 @@ func (s *Special2) goString(indent int, field string) string { indent+2, "", s.Middle, s.Val2.goString(indent+2, "Val2: ")) } +// EnableIf is used by clang for an enable_if attribute. +type EnableIf struct { + Type AST + Args []AST +} + +func (ei *EnableIf) print(ps *printState) { + ps.print(ei.Type) + ps.writeString(" [enable_if:") + first := true + for _, a := range ei.Args { + if !first { + ps.writeString(", ") + } + ps.print(a) + first = false + } + ps.writeString("]") +} + +func (ei *EnableIf) Traverse(fn func(AST) bool) { + if fn(ei) { + ei.Type.Traverse(fn) + for _, a := range ei.Args { + a.Traverse(fn) + } + } +} + +func (ei *EnableIf) Copy(fn func(AST) AST, skip func(AST) bool) AST { + if skip(ei) { + return nil + } + typ := ei.Type.Copy(fn, skip) + argsChanged := false + args := make([]AST, len(ei.Args)) + for i, a := range ei.Args { + ac := a.Copy(fn, skip) + if ac == nil { + args[i] = a + } else { + args[i] = ac + argsChanged = true + } + } + if typ == nil && !argsChanged { + return fn(ei) + } + if typ == nil { + typ = ei.Type + } + ei = &EnableIf{Type: typ, Args: args} + if r := fn(ei); r != nil { + return r + } + return ei +} + +func (ei *EnableIf) GoString() string { + return ei.goString(0, "") +} + +func (ei *EnableIf) goString(indent int, field string) string { + var args string + if len(ei.Args) == 0 { + args = fmt.Sprintf("%*sArgs: nil", indent+2, "") + } else { + args = fmt.Sprintf("%*sArgs:", indent+2, "") + for i, a := range ei.Args { + args += "\n" + args += a.goString(indent+4, fmt.Sprintf("%d: ", i)) + } + } + return fmt.Sprintf("%*s%sEnableIf:\n%s\n%s", indent, "", field, + ei.Type.goString(indent+2, "Type: "), args) +} + // Print the inner types. func (ps *printState) printInner(prefixOnly bool) []AST { var save []AST diff --git a/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go b/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go index 7541b736ba..c2667446df 100644 --- a/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go +++ b/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go @@ -5,6 +5,8 @@ // Package demangle defines functions that demangle GCC/LLVM C++ symbol names. // This package recognizes names that were mangled according to the C++ ABI // defined at http://codesourcery.com/cxx-abi/. +// +// Most programs will want to call Filter or ToString. package demangle import ( @@ -45,7 +47,7 @@ func Filter(name string, options ...Option) string { return ret } -// ToString demangles a C++ symbol name, returning human-readable C++ +// ToString demangles a C++ symbol name, returning a human-readable C++ // name or an error. // If the name does not appear to be a C++ symbol name at all, the // error will be ErrNotMangledName. @@ -183,6 +185,7 @@ type state struct { off int // offset of str within original string subs substitutions // substitutions templates []*Template // templates being processed + inLambda int // number of lambdas being parsed } // copy returns a copy of the current state. @@ -310,15 +313,42 @@ func (st *state) encoding(params bool, local forLocalNameType) AST { if mwq != nil { check = mwq.Method } - template, _ := check.(*Template) + + var template *Template + switch check := check.(type) { + case *Template: + template = check + case *Qualified: + if check.LocalName { + n := check.Name + if nmwq, ok := n.(*MethodWithQualifiers); ok { + n = nmwq.Method + } + template, _ = n.(*Template) + } + } + var oldInLambda int if template != nil { st.templates = append(st.templates, template) + oldInLambda = st.inLambda + st.inLambda = 0 + } + + // Checking for the enable_if attribute here is what the LLVM + // demangler does. This is not very general but perhaps it is + // sufficent. + const enableIfPrefix = "Ua9enable_ifI" + var enableIfArgs []AST + if strings.HasPrefix(st.str, enableIfPrefix) { + st.advance(len(enableIfPrefix) - 1) + enableIfArgs = st.templateArgs() } ft := st.bareFunctionType(hasReturnType(a)) if template != nil { st.templates = st.templates[:len(st.templates)-1] + st.inLambda = oldInLambda } ft = simplify(ft) @@ -349,13 +379,24 @@ func (st *state) encoding(params bool, local forLocalNameType) AST { } } - return &Typed{Name: a, Type: ft} + r := AST(&Typed{Name: a, Type: ft}) + + if len(enableIfArgs) > 0 { + r = &EnableIf{Type: r, Args: enableIfArgs} + } + + return r } // hasReturnType returns whether the mangled form of a will have a // return type. func hasReturnType(a AST) bool { switch a := a.(type) { + case *Qualified: + if a.LocalName { + return hasReturnType(a.Name) + } + return false case *Template: return !isCDtorConversion(a.Name) case *TypeWithQualifiers: @@ -481,7 +522,7 @@ func (st *state) nestedName() AST { q := st.cvQualifiers() r := st.refQualifier() a := st.prefix() - if len(q) > 0 || r != "" { + if q != nil || r != "" { a = &MethodWithQualifiers{Method: a, Qualifiers: q, RefQualifier: r} } if len(st.str) == 0 || st.str[0] != 'E' { @@ -608,6 +649,29 @@ func (st *state) prefix() AST { // gives appropriate output. st.advance(1) continue + case 'J': + // It appears that in some cases clang + // can emit a J for a template arg + // without the expected I. I don't + // know when this happens, but I've + // seen it in some large C++ programs. + if a == nil { + st.fail("unexpected template arguments") + } + var args []AST + for len(st.str) == 0 || st.str[0] != 'E' { + arg := st.templateArg() + args = append(args, arg) + } + st.advance(1) + tmpl := &Template{Name: a, Args: args} + if isCast { + st.setTemplate(a, tmpl) + st.clearTemplateArgs(args) + isCast = false + } + a = nil + next = tmpl default: st.fail("unrecognized letter in prefix") } @@ -754,19 +818,26 @@ var operators = map[string]operator{ "ad": {"&", 1}, "an": {"&", 2}, "at": {"alignof ", 1}, + "aw": {"co_await ", 1}, "az": {"alignof ", 1}, "cc": {"const_cast", 2}, "cl": {"()", 2}, + // cp is not in the ABI but is used by clang "when the call + // would use ADL except for being parenthesized." + "cp": {"()", 2}, "cm": {",", 2}, "co": {"~", 1}, "dV": {"/=", 2}, + "dX": {"[...]=", 3}, "da": {"delete[] ", 1}, "dc": {"dynamic_cast", 2}, "de": {"*", 1}, + "di": {"=", 2}, "dl": {"delete ", 1}, "ds": {".*", 2}, "dt": {".", 2}, "dv": {"/", 2}, + "dx": {"]=", 2}, "eO": {"^=", 2}, "eo": {"^", 2}, "eq": {"==", 2}, @@ -808,7 +879,10 @@ var operators = map[string]operator{ "rc": {"reinterpret_cast", 2}, "rm": {"%", 2}, "rs": {">>", 2}, + "sP": {"sizeof...", 1}, + "sZ": {"sizeof...", 1}, "sc": {"static_cast", 2}, + "ss": {"<=>", 2}, "st": {"sizeof ", 1}, "sz": {"sizeof ", 1}, "tr": {"throw", 0}, @@ -928,6 +1002,7 @@ func (st *state) javaResource() AST { // ::= TT <type> // ::= TI <type> // ::= TS <type> +// ::= TA <template-arg> // ::= GV <(object) name> // ::= T <call-offset> <(base) encoding> // ::= Tc <call-offset> <call-offset> <(base) encoding> @@ -961,6 +1036,9 @@ func (st *state) specialName() AST { case 'S': t := st.demangleType(false) return &Special{Prefix: "typeinfo name for ", Val: t} + case 'A': + t := st.templateArg() + return &Special{Prefix: "template parameter object for ", Val: t} case 'h': st.callOffset('h') v := st.encoding(true, notForLocalName) @@ -1138,7 +1216,7 @@ func (st *state) demangleType(isCast bool) AST { addSubst := true q := st.cvQualifiers() - if len(q) > 0 { + if q != nil { if len(st.str) == 0 { st.fail("expected type") } @@ -1159,7 +1237,7 @@ func (st *state) demangleType(isCast bool) AST { if btype, ok := builtinTypes[st.str[0]]; ok { ret = &BuiltinType{Name: btype} st.advance(1) - if len(q) > 0 { + if q != nil { ret = &TypeWithQualifiers{Base: ret, Qualifiers: q} st.subs.add(ret) } @@ -1286,6 +1364,8 @@ func (st *state) demangleType(isCast bool) AST { case 'a': ret = &Name{Name: "auto"} + case 'c': + ret = &Name{Name: "decltype(auto)"} case 'f': ret = &BuiltinType{Name: "decimal32"} @@ -1295,6 +1375,8 @@ func (st *state) demangleType(isCast bool) AST { ret = &BuiltinType{Name: "decimal128"} case 'h': ret = &BuiltinType{Name: "half"} + case 'u': + ret = &BuiltinType{Name: "char8_t"} case 's': ret = &BuiltinType{Name: "char16_t"} case 'i': @@ -1343,7 +1425,7 @@ func (st *state) demangleType(isCast bool) AST { } } - if len(q) > 0 { + if q != nil { if _, ok := ret.(*FunctionType); ok { ret = &MethodWithQualifiers{Method: ret, Qualifiers: q, RefQualifier: ""} } else if mwq, ok := ret.(*MethodWithQualifiers); ok { @@ -1433,17 +1515,32 @@ func (st *state) demangleCastTemplateArgs(tp AST, addSubst bool) AST { } // mergeQualifiers merges two qualifer lists into one. -func mergeQualifiers(q1, q2 Qualifiers) Qualifiers { +func mergeQualifiers(q1AST, q2AST AST) AST { + if q1AST == nil { + return q2AST + } + if q2AST == nil { + return q1AST + } + q1 := q1AST.(*Qualifiers) m := make(map[string]bool) - for _, qual := range q1 { - m[qual] = true + for _, qualAST := range q1.Qualifiers { + qual := qualAST.(*Qualifier) + if len(qual.Exprs) == 0 { + m[qual.Name] = true + } } - for _, qual := range q2 { - if !m[qual] { - q1 = append(q1, qual) - m[qual] = true + rq := q1.Qualifiers + for _, qualAST := range q2AST.(*Qualifiers).Qualifiers { + qual := qualAST.(*Qualifier) + if len(qual.Exprs) > 0 { + rq = append(rq, qualAST) + } else if !m[qual.Name] { + rq = append(rq, qualAST) + m[qual.Name] = true } } + q1.Qualifiers = rq return q1 } @@ -1456,20 +1553,51 @@ var qualifiers = map[byte]string{ } // <CV-qualifiers> ::= [r] [V] [K] -func (st *state) cvQualifiers() Qualifiers { - var q Qualifiers +func (st *state) cvQualifiers() AST { + var q []AST +qualLoop: for len(st.str) > 0 { if qv, ok := qualifiers[st.str[0]]; ok { - q = append([]string{qv}, q...) + qual := &Qualifier{Name: qv} + q = append([]AST{qual}, q...) st.advance(1) - } else if len(st.str) > 1 && st.str[:2] == "Dx" { - q = append([]string{"transaction_safe"}, q...) - st.advance(2) + } else if len(st.str) > 1 && st.str[0] == 'D' { + var qual AST + switch st.str[1] { + case 'x': + qual = &Qualifier{Name: "transaction_safe"} + st.advance(2) + case 'o': + qual = &Qualifier{Name: "noexcept"} + st.advance(2) + case 'O': + st.advance(2) + expr := st.expression() + if len(st.str) == 0 || st.str[0] != 'E' { + st.fail("expected E after computed noexcept expression") + } + st.advance(1) + qual = &Qualifier{Name: "noexcept", Exprs: []AST{expr}} + case 'w': + st.advance(2) + parmlist := st.parmlist() + if len(st.str) == 0 || st.str[0] != 'E' { + st.fail("expected E after throw parameter list") + } + st.advance(1) + qual = &Qualifier{Name: "throw", Exprs: parmlist} + default: + break qualLoop + } + q = append([]AST{qual}, q...) } else { break } } - return q + if len(q) == 0 { + return nil + } + return &Qualifiers{Qualifiers: q} } // <ref-qualifier> ::= R @@ -1677,7 +1805,7 @@ func (st *state) compactNumber() int { // whatever the template parameter would be expanded to here. We sort // this out in substitution and simplify. func (st *state) templateParam() AST { - if len(st.templates) == 0 { + if len(st.templates) == 0 && st.inLambda == 0 { st.fail("template parameter not in scope of template") } off := st.off @@ -1685,6 +1813,13 @@ func (st *state) templateParam() AST { st.checkChar('T') n := st.compactNumber() + if st.inLambda > 0 { + // g++ mangles lambda auto params as template params. + // Apparently we can't encounter a template within a lambda. + // See https://gcc.gnu.org/PR78252. + return &LambdaAuto{Index: n} + } + template := st.templates[len(st.templates)-1] if template == nil { @@ -1723,6 +1858,10 @@ func (st *state) setTemplate(a AST, tmpl *Template) { } a.Template = tmpl return false + case *Closure: + // There are no template params in closure types. + // https://gcc.gnu.org/PR78252. + return false default: for _, v := range seen { if v == a { @@ -1812,12 +1951,60 @@ func (st *state) exprList(stop byte) AST { // <expression> ::= <(unary) operator-name> <expression> // ::= <(binary) operator-name> <expression> <expression> // ::= <(trinary) operator-name> <expression> <expression> <expression> +// ::= pp_ <expression> +// ::= mm_ <expression> +// ::= cl <expression>+ E // ::= cl <expression>+ E +// ::= cv <type> <expression> +// ::= cv <type> _ <expression>* E +// ::= tl <type> <braced-expression>* E +// ::= il <braced-expression>* E +// ::= [gs] nw <expression>* _ <type> E +// ::= [gs] nw <expression>* _ <type> <initializer> +// ::= [gs] na <expression>* _ <type> E +// ::= [gs] na <expression>* _ <type> <initializer> +// ::= [gs] dl <expression> +// ::= [gs] da <expression> +// ::= dc <type> <expression> +// ::= sc <type> <expression> +// ::= cc <type> <expression> +// ::= rc <type> <expression> +// ::= ti <type> +// ::= te <expression> // ::= st <type> +// ::= sz <expression> +// ::= at <type> +// ::= az <expression> +// ::= nx <expression> // ::= <template-param> -// ::= sr <type> <unqualified-name> -// ::= sr <type> <unqualified-name> <template-args> +// ::= <function-param> +// ::= dt <expression> <unresolved-name> +// ::= pt <expression> <unresolved-name> +// ::= ds <expression> <expression> +// ::= sZ <template-param> +// ::= sZ <function-param> +// ::= sP <template-arg>* E +// ::= sp <expression> +// ::= fl <binary operator-name> <expression> +// ::= fr <binary operator-name> <expression> +// ::= fL <binary operator-name> <expression> <expression> +// ::= fR <binary operator-name> <expression> <expression> +// ::= tw <expression> +// ::= tr +// ::= <unresolved-name> // ::= <expr-primary> +// +// <function-param> ::= fp <CV-qualifiers> _ +// ::= fp <CV-qualifiers> <number> +// ::= fL <number> p <CV-qualifiers> _ +// ::= fL <number> p <CV-qualifiers> <number> +// ::= fpT +// +// <braced-expression> ::= <expression> +// ::= di <field source-name> <braced-expression> +// ::= dx <index expression> <braced-expression> +// ::= dX <range begin expression> <range end expression> <braced-expression> +// func (st *state) expression() AST { if len(st.str) == 0 { st.fail("expected expression") @@ -1827,61 +2014,7 @@ func (st *state) expression() AST { } else if st.str[0] == 'T' { return st.templateParam() } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'r' { - st.advance(2) - if len(st.str) == 0 { - st.fail("expected unresolved type") - } - switch st.str[0] { - case 'T', 'D', 'S': - t := st.demangleType(false) - n := st.baseUnresolvedName() - n = &Qualified{Scope: t, Name: n, LocalName: false} - if len(st.str) > 0 && st.str[0] == 'I' { - args := st.templateArgs() - n = &Template{Name: n, Args: args} - } - return n - default: - var s AST - if st.str[0] == 'N' { - st.advance(1) - s = st.demangleType(false) - } - for len(st.str) == 0 || st.str[0] != 'E' { - // GCC does not seem to follow the ABI here. - // It can emit type/name without an 'E'. - if s != nil && len(st.str) > 0 && !isDigit(st.str[0]) { - if q, ok := s.(*Qualified); ok { - a := q.Scope - if t, ok := a.(*Template); ok { - st.subs.add(t.Name) - st.subs.add(t) - } else { - st.subs.add(a) - } - return s - } - } - n := st.sourceName() - if len(st.str) > 0 && st.str[0] == 'I' { - st.subs.add(n) - args := st.templateArgs() - n = &Template{Name: n, Args: args} - } - if s == nil { - s = n - } else { - s = &Qualified{Scope: s, Name: n, LocalName: false} - } - st.subs.add(s) - } - if s == nil { - st.fail("missing scope in unresolved name") - } - st.advance(1) - n := st.baseUnresolvedName() - return &Qualified{Scope: s, Name: n, LocalName: false} - } + return st.unresolvedName() } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'p' { st.advance(2) e := st.expression() @@ -1911,9 +2044,25 @@ func (st *state) expression() AST { st.advance(1) return &FunctionParam{Index: 0} } else { + // We can see qualifiers here, but we don't + // include them in the demangled string. + st.cvQualifiers() index := st.compactNumber() return &FunctionParam{Index: index + 1} } + } else if st.str[0] == 'f' && len(st.str) > 2 && st.str[1] == 'L' && isDigit(st.str[2]) { + st.advance(2) + // We don't include the scope count in the demangled string. + st.number() + if len(st.str) == 0 || st.str[0] != 'p' { + st.fail("expected p after function parameter scope count") + } + st.advance(1) + // We can see qualifiers here, but we don't include them + // in the demangled string. + st.cvQualifiers() + index := st.compactNumber() + return &FunctionParam{Index: index + 1} } else if isDigit(st.str[0]) || (st.str[0] == 'o' && len(st.str) > 1 && st.str[1] == 'n') { if st.str[0] == 'o' { // Skip operator function ID. @@ -1975,13 +2124,15 @@ func (st *state) expression() AST { left, _ = st.operatorName(true) right = st.expression() return &Fold{Left: code[1] == 'l', Op: left, Arg1: right, Arg2: nil} + } else if code == "di" { + left, _ = st.unqualifiedName() } else { left = st.expression() } - if code == "cl" { + if code == "cl" || code == "cp" { right = st.exprList('E') } else if code == "dt" || code == "pt" { - right, _ = st.unqualifiedName() + right = st.unresolvedName() if len(st.str) > 0 && st.str[0] == 'I' { args := st.templateArgs() right = &Template{Name: right, Args: args} @@ -2034,6 +2185,82 @@ func (st *state) expression() AST { } } +// <unresolved-name> ::= [gs] <base-unresolved-name> +// ::= sr <unresolved-type> <base-unresolved-name> +// ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> +// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> +func (st *state) unresolvedName() AST { + if len(st.str) >= 2 && st.str[:2] == "gs" { + st.advance(2) + n := st.unresolvedName() + return &Unary{ + Op: &Operator{Name: "::"}, + Expr: n, + Suffix: false, + SizeofType: false, + } + } else if len(st.str) >= 2 && st.str[:2] == "sr" { + st.advance(2) + if len(st.str) == 0 { + st.fail("expected unresolved type") + } + switch st.str[0] { + case 'T', 'D', 'S': + t := st.demangleType(false) + n := st.baseUnresolvedName() + n = &Qualified{Scope: t, Name: n, LocalName: false} + if len(st.str) > 0 && st.str[0] == 'I' { + args := st.templateArgs() + n = &Template{Name: n, Args: args} + st.subs.add(n) + } + return n + default: + var s AST + if st.str[0] == 'N' { + st.advance(1) + s = st.demangleType(false) + } + for len(st.str) == 0 || st.str[0] != 'E' { + // GCC does not seem to follow the ABI here. + // It can emit type/name without an 'E'. + if s != nil && len(st.str) > 0 && !isDigit(st.str[0]) { + if q, ok := s.(*Qualified); ok { + a := q.Scope + if t, ok := a.(*Template); ok { + st.subs.add(t.Name) + st.subs.add(t) + } else { + st.subs.add(a) + } + return s + } + } + n := st.sourceName() + if len(st.str) > 0 && st.str[0] == 'I' { + st.subs.add(n) + args := st.templateArgs() + n = &Template{Name: n, Args: args} + } + if s == nil { + s = n + } else { + s = &Qualified{Scope: s, Name: n, LocalName: false} + } + st.subs.add(s) + } + if s == nil { + st.fail("missing scope in unresolved name") + } + st.advance(1) + n := st.baseUnresolvedName() + return &Qualified{Scope: s, Name: n, LocalName: false} + } + } else { + return st.baseUnresolvedName() + } +} + // <base-unresolved-name> ::= <simple-id> // ::= on <operator-name> // ::= on <operator-name> <template-args> @@ -2099,7 +2326,14 @@ func (st *state) exprPrimary() AST { st.advance(1) } if len(st.str) > 0 && st.str[0] == 'E' { - st.fail("missing literal value") + if bt, ok := t.(*BuiltinType); ok && bt.Name == "decltype(nullptr)" { + // A nullptr should not have a value. + // We accept one if present because GCC + // used to generate one. + // https://gcc.gnu.org/PR91979. + } else { + st.fail("missing literal value") + } } i := 0 for len(st.str) > i && st.str[i] != 'E' { @@ -2116,17 +2350,29 @@ func (st *state) exprPrimary() AST { return ret } -// <discriminator> ::= _ <(non-negative) number> +// <discriminator> ::= _ <(non-negative) number> (when number < 10) +// __ <(non-negative) number> _ (when number >= 10) func (st *state) discriminator(a AST) AST { if len(st.str) == 0 || st.str[0] != '_' { return a } off := st.off st.advance(1) + trailingUnderscore := false + if len(st.str) > 0 && st.str[0] == '_' { + st.advance(1) + trailingUnderscore = true + } d := st.number() if d < 0 { st.failEarlier("invalid negative discriminator", st.off-off) } + if trailingUnderscore && d >= 10 { + if len(st.str) == 0 || st.str[0] != '_' { + st.fail("expected _ after discriminator >= 10") + } + st.advance(1) + } // We don't currently print out the discriminator, so we don't // save it. return a @@ -2136,15 +2382,15 @@ func (st *state) discriminator(a AST) AST { func (st *state) closureTypeName() AST { st.checkChar('U') st.checkChar('l') + st.inLambda++ types := st.parmlist() + st.inLambda-- if len(st.str) == 0 || st.str[0] != 'E' { st.fail("expected E after closure type name") } st.advance(1) num := st.compactNumber() - ret := &Closure{Types: types, Num: num} - st.subs.add(ret) - return ret + return &Closure{Types: types, Num: num} } // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ @@ -2295,31 +2541,92 @@ func (st *state) substitution(forPrefix bool) AST { // We need to update any references to template // parameters to refer to the currently active // template. + + // When copying a Typed we may need to adjust + // the templates. + copyTemplates := st.templates + var oldInLambda []int + + // pushTemplate is called from skip, popTemplate from copy. + pushTemplate := func(template *Template) { + copyTemplates = append(copyTemplates, template) + oldInLambda = append(oldInLambda, st.inLambda) + st.inLambda = 0 + } + popTemplate := func() { + copyTemplates = copyTemplates[:len(copyTemplates)-1] + st.inLambda = oldInLambda[len(oldInLambda)-1] + oldInLambda = oldInLambda[:len(oldInLambda)-1] + } + copy := func(a AST) AST { - tp, ok := a.(*TemplateParam) - if !ok { + var index int + switch a := a.(type) { + case *Typed: + // Remove the template added in skip. + if _, ok := a.Name.(*Template); ok { + popTemplate() + } + return nil + case *Closure: + // Undo the decrement in skip. + st.inLambda-- return nil + case *TemplateParam: + index = a.Index + case *LambdaAuto: + // A lambda auto parameter is represented + // as a template parameter, so we may have + // to change back when substituting. + index = a.Index + default: + return nil + } + if st.inLambda > 0 { + if _, ok := a.(*LambdaAuto); ok { + return nil + } + return &LambdaAuto{Index: index} } - if len(st.templates) == 0 { + var template *Template + if len(copyTemplates) > 0 { + template = copyTemplates[len(copyTemplates)-1] + } else if rt, ok := ret.(*Template); ok { + // At least with clang we can see a template + // to start, and sometimes we need to refer + // to it. There is probably something wrong + // here. + template = rt + } else { st.failEarlier("substituted template parameter not in scope of template", dec) } - template := st.templates[len(st.templates)-1] if template == nil { // This template parameter is within // the scope of a cast operator. - return &TemplateParam{Index: tp.Index, Template: nil} + return &TemplateParam{Index: index, Template: nil} } - if tp.Index >= len(template.Args) { - st.failEarlier(fmt.Sprintf("substituted template index out of range (%d >= %d)", tp.Index, len(template.Args)), dec) + if index >= len(template.Args) { + st.failEarlier(fmt.Sprintf("substituted template index out of range (%d >= %d)", index, len(template.Args)), dec) } - return &TemplateParam{Index: tp.Index, Template: template} + return &TemplateParam{Index: index, Template: template} } var seen []AST skip := func(a AST) bool { - if _, ok := a.(*Typed); ok { - return true + switch a := a.(type) { + case *Typed: + if template, ok := a.Name.(*Template); ok { + // This template is removed in copy. + pushTemplate(template) + } + return false + case *Closure: + // This is decremented in copy. + st.inLambda++ + return false + case *TemplateParam, *LambdaAuto: + return false } for _, v := range seen { if v == a { @@ -2329,6 +2636,7 @@ func (st *state) substitution(forPrefix bool) AST { seen = append(seen, a) return false } + if c := ret.Copy(copy, skip); c != nil { return c } @@ -2351,6 +2659,7 @@ func (st *state) substitution(forPrefix bool) AST { if len(st.str) > 0 && st.str[0] == 'B' { a = st.taggedName(a) + st.subs.add(a) } return a diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go index 858f9acbb8..48a4e9790a 100644 --- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go +++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go @@ -112,7 +112,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin case STDCXCC, STWCXCC, STHCXCC, STBCXCC: return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")" - case STXVD2X, STXVW4X, STXSDX, STVX, STVXL, STVEBX, STVEHX, STVEWX, STXSIWX, STFDX, STFDUX, STFDPX, STFSX, STFSUX: + case STXVX, STXVD2X, STXVW4X, STXVH8X, STXVB16X, STXSDX, STVX, STVXL, STVEBX, STVEHX, STVEWX, STXSIWX, STFDX, STFDUX, STFDPX, STFSX, STFSUX: return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")" case STXV: @@ -127,7 +127,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin } return op + " (" + args[2] + ")(" + args[1] + ")," + args[0] - case LXVD2X, LXVW4X, LVX, LVXL, LVSR, LVSL, LVEBX, LVEHX, LVEWX, LXSDX, LXSIWAX: + case LXVX, LXVD2X, LXVW4X, LXVH8X, LXVB16X, LVX, LVXL, LVSR, LVSL, LVEBX, LVEHX, LVEWX, LXSDX, LXSIWAX: return op + " (" + args[2] + ")(" + args[1] + ")," + args[0] case LXV: @@ -332,6 +332,7 @@ var plan9OpMap = map[Op]string{ DIVDUO: "DIVDUV", DIVDUOCC: "DIVDUVCC", ADDI: "ADD", + MULLI: "MULLD", SRADI: "SRAD", SUBF: "SUB", STBCXCC: "STBCCC", diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go index 250d3b7193..76f96356d2 100644 --- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go +++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go @@ -1,5 +1,5 @@ // DO NOT EDIT -// generated by: ppc64map -fmt=decoder ../pp64.csv +// generated by: ppc64map -fmt=decoder pp64.csv package ppc64asm @@ -727,17 +727,23 @@ const ( LXVD2X LXVDSX LXVW4X + LXVH8X + LXVB16X LXV LXVL LXVLL + LXVX STXSDX STXSIWX STXSSPX STXVD2X STXVW4X + STXVH8X + STXVB16X STXV STXVL STXVLL + STXVX XSABSDP XSADDDP XSADDSP @@ -881,6 +887,9 @@ const ( XXSEL XXSLDWI XXSPLTW + XXBRD + XXBRW + XXBRH BRINC EVABS EVADDIW @@ -2095,17 +2104,23 @@ var opstr = [...]string{ LXVD2X: "lxvd2x", LXVDSX: "lxvdsx", LXVW4X: "lxvw4x", + LXVH8X: "lxvh8x", + LXVB16X: "lxvb16x", LXV: "lxv", LXVL: "lxvl", LXVLL: "lxvll", + LXVX: "lxvx", STXSDX: "stxsdx", STXSIWX: "stxsiwx", STXSSPX: "stxsspx", STXVD2X: "stxvd2x", STXVW4X: "stxvw4x", + STXVH8X: "stxvh8x", + STXVB16X: "stxvb16x", STXV: "stxv", STXVL: "stxvl", STXVLL: "stxvll", + STXVX: "stxvx", XSABSDP: "xsabsdp", XSADDDP: "xsadddp", XSADDSP: "xsaddsp", @@ -2249,6 +2264,9 @@ var opstr = [...]string{ XXSEL: "xxsel", XXSLDWI: "xxsldwi", XXSPLTW: "xxspltw", + XXBRD: "xxbrd", + XXBRW: "xxbrw", + XXBRH: "xxbrh", BRINC: "brinc", EVABS: "evabs", EVADDIW: "evaddiw", @@ -4260,12 +4278,18 @@ var instFormats = [...]instFormat{ [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {LXVW4X, 0xfc0007fe, 0x7c000618, 0x0, // Load VSX Vector Word*4 Indexed XX1-form (lxvw4x XT,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVH8X, 0xfc0007fe, 0x7c000658, 0x0, // Load VSX Vector Halfword*8 Indexed XX1-form (lxvh8x XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVB16X, 0xfc0007fe, 0x7c0006d8, 0x0, // Load VSX Vector Byte*16 Indexed XX1-form (lxvb16x XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {LXV, 0xfc000007, 0xf4000001, 0x0, // Load VSX Vector DQ-form (lxv XT,DQ(RA)) [5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}}, {LXVL, 0xfc0007fe, 0x7c00021a, 0x0, // Load VSX Vector with Length X-form (lxvl XT,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {LXVLL, 0xfc0007fe, 0x7c00025a, 0x0, // Load VSX Vector Left-justified with Length X-form (lxvll XT,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {LXVX, 0xfc0007be, 0x7c000218, 0x40, // Load VSX Vector Indexed X-form (lxvx XT,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {STXSDX, 0xfc0007fe, 0x7c000598, 0x0, // Store VSX Scalar Doubleword Indexed XX1-form (stxsdx XS,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {STXSIWX, 0xfc0007fe, 0x7c000118, 0x0, // Store VSX Scalar as Integer Word Indexed XX1-form (stxsiwx XS,RA,RB) @@ -4276,12 +4300,18 @@ var instFormats = [...]instFormat{ [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {STXVW4X, 0xfc0007fe, 0x7c000718, 0x0, // Store VSX Vector Word*4 Indexed XX1-form (stxvw4x XS,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXVH8X, 0xfc0007fe, 0x7c000758, 0x0, // Store VSX Vector Halfword*4 Indexed XX1-form (stxvh8x XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXVB16X, 0xfc0007fe, 0x7c0007d8, 0x0, // Store VSX Vector Byte*16 Indexed XX1-form (stxvb16x XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {STXV, 0xfc000007, 0xf4000005, 0x0, // Store VSX Vector DQ-form (stxv XS,DQ(RA)) [5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}}, {STXVL, 0xfc0007fe, 0x7c00031a, 0x0, // Store VSX Vector with Length X-form (stxvl XS,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {STXVLL, 0xfc0007fe, 0x7c00035a, 0x0, // Store VSX Vector Left-justified with Length X-form (stxvll XS,RA,RB) [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, + {STXVX, 0xfc0007fe, 0x7c000318, 0x0, // Store VSX Vector Indexed X-form (stxvx XS,RA,RB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {XSABSDP, 0xfc0007fc, 0xf0000564, 0x1f0000, // VSX Scalar Absolute Value Double-Precision XX2-form (xsabsdp XT,XB) [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, {XSADDDP, 0xfc0007f8, 0xf0000100, 0x0, // VSX Scalar Add Double-Precision XX3-form (xsadddp XT,XA,XB) @@ -4568,6 +4598,12 @@ var instFormats = [...]instFormat{ [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}}, {XXSPLTW, 0xfc0007fc, 0xf0000290, 0x1c0000, // VSX Splat Word XX2-form (xxspltw XT,XB,UIM) [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_14_15}}, + {XXBRD, 0xfc1f07fc, 0xf017076c, 0x0, // VSX Vector Byte-Reverse Doubleword XX2-form (xxbrd XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XXBRW, 0xfc1f07fc, 0xf00f076c, 0x0, // VSX Vector Byte-Reverse Word XX2-form (xxbrw XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, + {XXBRH, 0xfc1f07fc, 0xf007076c, 0x0, // VSX Vector Byte-Reverse Halfword XX2-form (xxbrh XT,XB) + [5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}}, {BRINC, 0xfc0007ff, 0x1000020f, 0x0, // Bit Reversed Increment EVX-form (brinc RT,RA,RB) [5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}}, {EVABS, 0xfc0007ff, 0x10000208, 0xf800, // Vector Absolute Value EVX-form (evabs RT,RA) diff --git a/src/cmd/vendor/golang.org/x/mod/semver/semver.go b/src/cmd/vendor/golang.org/x/mod/semver/semver.go index 2988e3cf9c..4338f35177 100644 --- a/src/cmd/vendor/golang.org/x/mod/semver/semver.go +++ b/src/cmd/vendor/golang.org/x/mod/semver/semver.go @@ -138,6 +138,9 @@ func Compare(v, w string) int { // Max canonicalizes its arguments and then returns the version string // that compares greater. +// +// Deprecated: use Compare instead. In most cases, returning a canonicalized +// version is not expected or desired. func Max(v, w string) string { v = Canonical(v) w = Canonical(w) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s index 06f84b8555..6b4027b33f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s index 8a7278319e..8a06b87d71 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s index 6321421f27..f2397fde55 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s index 333242d506..c9e6b6fc8b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc // +build arm,darwin #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s index 97e0174371..89843f8f4b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc // +build arm64,darwin #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s index 603dd5728c..27674e1caf 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s index c9a0a26015..49f0ac2364 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s index 35172477c8..f2dfc57b83 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s index 9227c875bf..6d740db2c0 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s index d9318cbf03..a8f5a29b35 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s index 448bebbb59..0655ecbfbb 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s index c6468a9588..bc3fb6ac3e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s index cf0f3575c1..55b13c7ba4 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s index afe6fdf6b1..22a83d8e3f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s @@ -4,7 +4,7 @@ // +build linux // +build arm64 -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s index ab9d63831a..dc222b90ce 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s @@ -4,7 +4,7 @@ // +build linux // +build mips64 mips64le -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s index 99e5399045..d333f13cff 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s @@ -4,7 +4,7 @@ // +build linux // +build mips mipsle -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s index 88f7125578..459a629c27 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s @@ -4,7 +4,7 @@ // +build linux // +build ppc64 ppc64le -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s index 3cfefed2ec..04d38497c6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build riscv64,!gccgo +// +build riscv64,gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s index a5a863c6bd..cc303989e1 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s @@ -4,7 +4,7 @@ // +build s390x // +build linux -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s index 48bdcd7632..ae7b498d50 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s index 2ede05c72f..e57367c17a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s index e8928571c4..d7da175e1a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s index 6f98ba5a37..e7cbe1904c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s index 00576f3c83..2f00b0310f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s index 790ef77f86..07632c99ce 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s index 469bfa1003..73e997320f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s index 0cedea3d39..c47302aa46 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s new file mode 100644 index 0000000000..47c93fcb6c --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s @@ -0,0 +1,29 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gc + +#include "textflag.h" + +// +// System call support for mips64, OpenBSD +// + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-56 + JMP syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + JMP syscall·Syscall6(SB) + +TEXT ·Syscall9(SB),NOSPLIT,$0-104 + JMP syscall·Syscall9(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + JMP syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + JMP syscall·RawSyscall6(SB) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s index ded8260f3e..1f2c755a72 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo +// +build gc #include "textflag.h" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go b/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go index 5e9269063f..86781eac22 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/endian_big.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // -// +build ppc64 s390x mips mips64 +// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64 package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go index bcdb5d30eb..8822d8541f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // -// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64 +// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_darwin.go b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_darwin.go index 5868a4a47b..a9911c7c1d 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_darwin.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_darwin.go @@ -16,3 +16,9 @@ func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk)))) return err } + +// FcntlFstore performs a fcntl syscall for the F_PREALLOCATE command. +func FcntlFstore(fd uintptr, cmd int, fstore *Fstore_t) error { + _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(fstore)))) + return err +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go index fc0e50e037..8db48e5e06 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go @@ -1,9 +1,9 @@ -// +build linux,386 linux,arm linux,mips linux,mipsle - // Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build linux,386 linux,arm linux,mips linux,mipsle + package unix func init() { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go b/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go index cd6f5a6133..86032c11ef 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/gccgo.go @@ -12,10 +12,8 @@ import "syscall" // We can't use the gc-syntax .s files for gccgo. On the plus side // much of the functionality can be written directly in Go. -//extern gccgoRealSyscallNoError func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr) -//extern gccgoRealSyscall func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr) func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/gccgo_c.c b/src/cmd/vendor/golang.org/x/sys/unix/gccgo_c.c index c44730c5e9..2cb1fefac6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/gccgo_c.c +++ b/src/cmd/vendor/golang.org/x/sys/unix/gccgo_c.c @@ -21,6 +21,9 @@ struct ret { uintptr_t err; }; +struct ret gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) + __asm__(GOSYM_PREFIX GOPKGPATH ".realSyscall"); + struct ret gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) { @@ -32,6 +35,9 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp return r; } +uintptr_t gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) + __asm__(GOSYM_PREFIX GOPKGPATH ".realSyscallNoError"); + uintptr_t gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go b/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go index 3559e5dcb2..5641678613 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ioctl.go @@ -20,6 +20,15 @@ func IoctlSetInt(fd int, req uint, value int) error { return ioctl(fd, req, uintptr(value)) } +// IoctlSetPointerInt performs an ioctl operation which sets an +// integer value on fd, using the specified request number. The ioctl +// argument is called with a pointer to the integer value, rather than +// passing the integer value directly. +func IoctlSetPointerInt(fd int, req uint, value int) error { + v := int32(value) + return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) +} + // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. // // To change fd's window size, the req argument should be TIOCSWINSZ. diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh index ece31e9dcd..d257fac505 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh +++ b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh @@ -73,26 +73,22 @@ aix_ppc64) darwin_386) mkerrors="$mkerrors -m32" mksyscall="go run mksyscall.go -l32" - mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_amd64) mkerrors="$mkerrors -m64" - mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_arm) mkerrors="$mkerrors" mksyscall="go run mksyscall.go -l32" - mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_arm64) mkerrors="$mkerrors -m64" - mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; @@ -184,6 +180,15 @@ openbsd_arm64) # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; +openbsd_mips64) + mkerrors="$mkerrors -m64" + mksyscall="go run mksyscall.go -openbsd" + mksysctl="go run mksysctl_openbsd.go" + mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; solaris_amd64) mksyscall="go run mksyscall_solaris.go" mkerrors="$mkerrors -m64" @@ -217,8 +222,6 @@ esac # aix/ppc64 script generates files instead of writing to stdin. echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ; elif [ "$GOOS" == "darwin" ]; then - # pre-1.12, direct syscalls - echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos syscall_darwin_${GOARCH}.1_11.go $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go"; # 1.12 and later, syscalls via libSystem echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; # 1.13 and later, syscalls via libSystem (including syscallPtr) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh index 780e387e3f..c0f9f2d523 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -58,12 +58,15 @@ includes_Darwin=' #define _DARWIN_USE_64_BIT_INODE #include <stdint.h> #include <sys/attr.h> +#include <sys/clonefile.h> +#include <sys/kern_control.h> #include <sys/types.h> #include <sys/event.h> #include <sys/ptrace.h> #include <sys/select.h> #include <sys/socket.h> #include <sys/sockio.h> +#include <sys/sys_domain.h> #include <sys/sysctl.h> #include <sys/mman.h> #include <sys/mount.h> @@ -93,6 +96,7 @@ includes_DragonFly=' #include <sys/ioctl.h> #include <net/bpf.h> #include <net/if.h> +#include <net/if_clone.h> #include <net/if_types.h> #include <net/route.h> #include <netinet/in.h> @@ -107,6 +111,7 @@ includes_FreeBSD=' #include <sys/types.h> #include <sys/disk.h> #include <sys/event.h> +#include <sys/sched.h> #include <sys/select.h> #include <sys/socket.h> #include <sys/sockio.h> @@ -192,9 +197,12 @@ struct ltchars { #include <sys/xattr.h> #include <linux/bpf.h> #include <linux/can.h> +#include <linux/can/error.h> +#include <linux/can/raw.h> #include <linux/capability.h> #include <linux/cryptouser.h> #include <linux/devlink.h> +#include <linux/dm-ioctl.h> #include <linux/errqueue.h> #include <linux/falloc.h> #include <linux/fanotify.h> @@ -217,6 +225,7 @@ struct ltchars { #include <linux/kexec.h> #include <linux/keyctl.h> #include <linux/loop.h> +#include <linux/lwtunnel.h> #include <linux/magic.h> #include <linux/memfd.h> #include <linux/module.h> @@ -225,6 +234,7 @@ struct ltchars { #include <linux/net_namespace.h> #include <linux/nsfs.h> #include <linux/perf_event.h> +#include <linux/pps.h> #include <linux/ptrace.h> #include <linux/random.h> #include <linux/reboot.h> @@ -297,6 +307,7 @@ includes_NetBSD=' #include <sys/extattr.h> #include <sys/mman.h> #include <sys/mount.h> +#include <sys/sched.h> #include <sys/select.h> #include <sys/socket.h> #include <sys/sockio.h> @@ -325,6 +336,7 @@ includes_OpenBSD=' #include <sys/mman.h> #include <sys/mount.h> #include <sys/select.h> +#include <sys/sched.h> #include <sys/socket.h> #include <sys/sockio.h> #include <sys/stat.h> @@ -365,6 +377,7 @@ includes_SunOS=' #include <sys/socket.h> #include <sys/sockio.h> #include <sys/stat.h> +#include <sys/stream.h> #include <sys/mman.h> #include <sys/wait.h> #include <sys/ioctl.h> @@ -489,6 +502,7 @@ ccflags="$@" $2 !~ "NLA_TYPE_MASK" && $2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ && $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ || + $2 ~ /^FIORDCHK$/ || $2 ~ /^SIOC/ || $2 ~ /^TIOC/ || $2 ~ /^TCGET/ || @@ -507,16 +521,21 @@ ccflags="$@" $2 ~ /^(CLOCK|TIMER)_/ || $2 ~ /^CAN_/ || $2 ~ /^CAP_/ || + $2 ~ /^CP_/ || + $2 ~ /^CPUSTATES$/ || + $2 ~ /^CTLIOCGINFO$/ || $2 ~ /^ALG_/ || + $2 ~ /^FI(CLONE|DEDUPERANGE)/ || $2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ || - $2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|GETFLAGS)/ || + $2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|[GS]ETFLAGS)/ || $2 ~ /^FS_VERITY_/ || $2 ~ /^FSCRYPT_/ || + $2 ~ /^DM_/ || $2 ~ /^GRND_/ || $2 ~ /^RND/ || $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || - $2 ~ /^PERF_EVENT_IOC_/ || + $2 ~ /^PERF_/ || $2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SPLICE_/ || $2 ~ /^SYNC_FILE_RANGE_/ || @@ -535,7 +554,7 @@ ccflags="$@" $2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ || $2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ || $2 ~ /^FSOPT_/ || - $2 ~ /^WDIOC_/ || + $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || @@ -543,6 +562,7 @@ ccflags="$@" $2 ~ /^CRYPTO_/ || $2 ~ /^TIPC_/ || $2 ~ /^DEVLINK_/ || + $2 ~ /^LWTUNNEL_IP/ || $2 !~ "WMESGLEN" && $2 ~ /^W[A-Z0-9]+$/ || $2 ~/^PPPIOC/ || diff --git a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go index 7d08dae5ba..57a0021da5 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go @@ -20,7 +20,7 @@ func cmsgAlignOf(salen int) int { case "aix": // There is no alignment on AIX. salign = 1 - case "darwin", "illumos", "solaris": + case "darwin", "ios", "illumos", "solaris": // NOTE: It seems like 64-bit Darwin, Illumos and Solaris // kernels still require 32-bit aligned access to network // subsystem. @@ -32,6 +32,10 @@ func cmsgAlignOf(salen int) int { if runtime.GOARCH == "arm" { salign = 8 } + // NetBSD aarch64 requires 128-bit alignment. + if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm64" { + salign = 16 + } } return (salen + salign - 1) & ^(salign - 1) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go index fd4ee8ebeb..ab75ef9cc6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go @@ -24,7 +24,13 @@ // holds a value of type syscall.Errno. package unix // import "golang.org/x/sys/unix" -import "strings" +import ( + "bytes" + "strings" + "unsafe" + + "golang.org/x/sys/internal/unsafeheader" +) // ByteSliceFromString returns a NUL-terminated slice of bytes // containing the text of s. If s contains a NUL byte at any @@ -49,5 +55,40 @@ func BytePtrFromString(s string) (*byte, error) { return &a[0], nil } +// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any +// bytes after the NUL removed. +func ByteSliceToString(s []byte) string { + if i := bytes.IndexByte(s, 0); i != -1 { + s = s[:i] + } + return string(s) +} + +// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string. +// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated +// at a zero byte; if the zero byte is not present, the program may crash. +func BytePtrToString(p *byte) string { + if p == nil { + return "" + } + if *p == 0 { + return "" + } + + // Find NUL terminator. + n := 0 + for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ { + ptr = unsafe.Pointer(uintptr(ptr) + 1) + } + + var s []byte + h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) + h.Data = unsafe.Pointer(p) + h.Len = n + h.Cap = n + + return string(s) +} + // Single-word zero for use when we need a valid pointer to 0 bytes. var _zero uintptr diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go index 9ad8a0d4a5..4408153822 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -19,6 +19,22 @@ import "unsafe" * Wrapped */ +func Access(path string, mode uint32) (err error) { + return Faccessat(AT_FDCWD, path, mode, 0) +} + +func Chmod(path string, mode uint32) (err error) { + return Fchmodat(AT_FDCWD, path, mode, 0) +} + +func Chown(path string, uid int, gid int) (err error) { + return Fchownat(AT_FDCWD, path, uid, gid, 0) +} + +func Creat(path string, mode uint32) (fd int, err error) { + return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) +} + //sys utimes(path string, times *[2]Timeval) (err error) func Utimes(path string, tv []Timeval) error { if len(tv) != 2 { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go index 68605db624..bc634a280a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -18,6 +18,21 @@ import ( "unsafe" ) +const ImplementsGetwd = true + +func Getwd() (string, error) { + var buf [PathMax]byte + _, err := Getcwd(buf[0:]) + if err != nil { + return "", err + } + n := clen(buf[:]) + if n < 1 { + return "", EINVAL + } + return string(buf[:n]), nil +} + /* * Wrapped */ @@ -262,7 +277,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { } return sa, nil } - return nil, EAFNOSUPPORT + return anyToSockaddrGOOS(fd, rsa) } func Accept(fd int) (nfd int, sa Sockaddr, err error) { @@ -272,7 +287,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { if err != nil { return } - if runtime.GOOS == "darwin" && len == 0 { + if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 { // Accepted socket has no address. // This is likely due to a bug in xnu kernels, // where instead of ECONNABORTED error socket @@ -527,6 +542,23 @@ func SysctlClockinfo(name string) (*Clockinfo, error) { return &ci, nil } +func SysctlTimeval(name string) (*Timeval, error) { + mib, err := sysctlmib(name) + if err != nil { + return nil, err + } + + var tv Timeval + n := uintptr(unsafe.Sizeof(tv)) + if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil { + return nil, err + } + if n != unsafe.Sizeof(tv) { + return nil, EIO + } + return &tv, nil +} + //sys utimes(path string, timeval *[2]Timeval) (err error) func Utimes(path string, tv []Timeval) error { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go index 6a15cba611..b31ef03588 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go @@ -10,6 +10,8 @@ import ( "unsafe" ) +const _SYS_GETDIRENTRIES64 = 344 + func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { // To implement this using libSystem we'd need syscall_syscallPtr for // fdopendir. However, syscallPtr was only added in Go 1.13, so we fall @@ -20,7 +22,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { } else { p = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) + r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) n = int(r0) if e1 != 0 { return n, errnoErr(e1) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go index dc0befee37..ee852f1abc 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go @@ -26,7 +26,6 @@ func fdopendir(fd int) (dir uintptr, err error) { func libc_fdopendir_trampoline() -//go:linkname libc_fdopendir libc_fdopendir //go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go index 9a5a6ee544..b625738900 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -13,29 +13,11 @@ package unix import ( - "errors" + "runtime" "syscall" "unsafe" ) -const ImplementsGetwd = true - -func Getwd() (string, error) { - buf := make([]byte, 2048) - attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0) - if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 { - wd := string(attrs[0]) - // Sanity check that it's an absolute path and ends - // in a null byte, which we then strip. - if wd[0] == '/' && wd[len(wd)-1] == 0 { - return wd[:len(wd)-1], nil - } - } - // If pkg/os/getwd.go gets ENOTSUP, it will fall back to the - // slow algorithm. - return "", ENOTSUP -} - // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 @@ -49,6 +31,41 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } +// SockaddrCtl implements the Sockaddr interface for AF_SYSTEM type sockets. +type SockaddrCtl struct { + ID uint32 + Unit uint32 + raw RawSockaddrCtl +} + +func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Sc_len = SizeofSockaddrCtl + sa.raw.Sc_family = AF_SYSTEM + sa.raw.Ss_sysaddr = AF_SYS_CONTROL + sa.raw.Sc_id = sa.ID + sa.raw.Sc_unit = sa.Unit + return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil +} + +func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { + switch rsa.Addr.Family { + case AF_SYSTEM: + pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa)) + if pp.Ss_sysaddr == AF_SYS_CONTROL { + sa := new(SockaddrCtl) + sa.ID = pp.Sc_id + sa.Unit = pp.Sc_unit + return sa, nil + } + } + return nil, EAFNOSUPPORT +} + +// Some external packages rely on SYS___SYSCTL being defined to implement their +// own sysctl wrappers. Provide it here, even though direct syscalls are no +// longer supported on darwin. +const SYS___SYSCTL = SYS_SYSCTL + // Translate "kern.hostname" to []_C_int{0,1,2,3}. func nametomib(name string) (mib []_C_int, err error) { const siz = unsafe.Sizeof(mib[0]) @@ -92,11 +109,6 @@ func direntNamlen(buf []byte) (uint64, bool) { func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } -const ( - attrBitMapCount = 5 - attrCmnFullpath = 0x08000000 -) - type attrList struct { bitmapCount uint16 _ uint16 @@ -107,54 +119,6 @@ type attrList struct { Forkattr uint32 } -func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { - if len(attrBuf) < 4 { - return nil, errors.New("attrBuf too small") - } - attrList.bitmapCount = attrBitMapCount - - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return nil, err - } - - if err := getattrlist(_p0, unsafe.Pointer(&attrList), unsafe.Pointer(&attrBuf[0]), uintptr(len(attrBuf)), int(options)); err != nil { - return nil, err - } - size := *(*uint32)(unsafe.Pointer(&attrBuf[0])) - - // dat is the section of attrBuf that contains valid data, - // without the 4 byte length header. All attribute offsets - // are relative to dat. - dat := attrBuf - if int(size) < len(attrBuf) { - dat = dat[:size] - } - dat = dat[4:] // remove length prefix - - for i := uint32(0); int(i) < len(dat); { - header := dat[i:] - if len(header) < 8 { - return attrs, errors.New("truncated attribute header") - } - datOff := *(*int32)(unsafe.Pointer(&header[0])) - attrLen := *(*uint32)(unsafe.Pointer(&header[4])) - if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { - return attrs, errors.New("truncated results; attrBuf too small") - } - end := uint32(datOff) + attrLen - attrs = append(attrs, dat[datOff:end]) - i = end - if r := i % 4; r != 0 { - i += (4 - r) - } - } - return -} - -//sys getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -324,6 +288,35 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig //sys ioctl(fd int, req uint, arg uintptr) (err error) +func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error { + err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo))) + runtime.KeepAlive(ctlInfo) + return err +} + +// IfreqMTU is struct ifreq used to get or set a network device's MTU. +type IfreqMTU struct { + Name [IFNAMSIZ]byte + MTU int32 +} + +// IoctlGetIfreqMTU performs the SIOCGIFMTU ioctl operation on fd to get the MTU +// of the network device specified by ifname. +func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) { + var ifreq IfreqMTU + copy(ifreq.Name[:], ifname) + err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq))) + return &ifreq, err +} + +// IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU +// of the network device specified by ifreq.Name. +func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { + err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq))) + runtime.KeepAlive(ifreq) + return err +} + //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL func Uname(uname *Utsname) error { @@ -396,6 +389,8 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Chroot(path string) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error) //sys Close(fd int) (err error) +//sys Clonefile(src string, dst string, flags int) (err error) +//sys Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) //sys Exchangedata(path1 string, path2 string, options int) (err error) @@ -407,10 +402,12 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) +//sys Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) +//sys Getcwd(buf []byte) (n int, err error) //sys Getdtablesize() (size int) //sysnb Getegid() (egid int) //sysnb Geteuid() (uid int) @@ -423,6 +420,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sysnb Getrlimit(which int, lim *Rlimit) (err error) //sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getsid(pid int) (sid int, err error) +//sysnb Gettimeofday(tp *Timeval) (err error) //sysnb Getuid() (uid int) //sysnb Issetugid() (tainted bool) //sys Kqueue() (fd int, err error) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go deleted file mode 100644 index 6b223f91a5..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin,386,!go1.12 - -package unix - -//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go index 707ba4f59a..6c1f4ab95b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go @@ -6,11 +6,7 @@ package unix -import ( - "syscall" -) - -//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) +import "syscall" func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: int32(sec), Nsec: int32(nsec)} @@ -20,17 +16,6 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: int32(sec), Usec: int32(usec)} } -//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. - sec, usec, err := gettimeofday(tv) - tv.Sec = int32(sec) - tv.Usec = int32(usec) - return err -} - func SetKevent(k *Kevent_t, fd, mode, flags int) { k.Ident = uint32(fd) k.Filter = int16(mode) @@ -55,14 +40,11 @@ func (cmsg *Cmsghdr) SetLen(length int) { func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) -// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions -// of darwin/386 the syscall is called sysctl instead of __sysctl. -const SYS___SYSCTL = SYS_SYSCTL - //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 +//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go deleted file mode 100644 index 68ebd6fab2..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin,amd64,!go1.12 - -package unix - -//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go index fdbfb5911a..0582ae256e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go @@ -6,11 +6,7 @@ package unix -import ( - "syscall" -) - -//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) +import "syscall" func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} @@ -20,17 +16,6 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: sec, Usec: int32(usec)} } -//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. - sec, usec, err := gettimeofday(tv) - tv.Sec = sec - tv.Usec = usec - return err -} - func SetKevent(k *Kevent_t, fd, mode, flags int) { k.Ident = uint64(fd) k.Filter = int16(mode) @@ -55,14 +40,11 @@ func (cmsg *Cmsghdr) SetLen(length int) { func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) -// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions -// of darwin/amd64 the syscall is called sysctl instead of __sysctl. -const SYS___SYSCTL = SYS_SYSCTL - //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 +//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go deleted file mode 100644 index 0e3f25aca1..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin,arm,!go1.12 - -package unix - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - return 0, ENOSYS -} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go index f8bc4cfb1f..c6a9733b4c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go @@ -4,9 +4,7 @@ package unix -import ( - "syscall" -) +import "syscall" func ptrace(request int, pid int, addr uintptr, data uintptr) error { return ENOTSUP @@ -20,17 +18,6 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: int32(sec), Usec: int32(usec)} } -//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. - sec, usec, err := gettimeofday(tv) - tv.Sec = int32(sec) - tv.Usec = int32(usec) - return err -} - func SetKevent(k *Kevent_t, fd, mode, flags int) { k.Ident = uint32(fd) k.Filter = int16(mode) @@ -55,10 +42,6 @@ func (cmsg *Cmsghdr) SetLen(length int) { func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic -// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions -// of darwin/arm the syscall is called sysctl instead of __sysctl. -const SYS___SYSCTL = SYS_SYSCTL - //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go deleted file mode 100644 index 01d450406b..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin,arm64,!go1.12 - -package unix - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - return 0, ENOSYS -} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go index 5ede3ac316..253afa4de5 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go @@ -6,13 +6,7 @@ package unix -import ( - "syscall" -) - -func ptrace(request int, pid int, addr uintptr, data uintptr) error { - return ENOTSUP -} +import "syscall" func setTimespec(sec, nsec int64) Timespec { return Timespec{Sec: sec, Nsec: nsec} @@ -22,17 +16,6 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: sec, Usec: int32(usec)} } -//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. - sec, usec, err := gettimeofday(tv) - tv.Sec = sec - tv.Usec = usec - return err -} - func SetKevent(k *Kevent_t, fd, mode, flags int) { k.Ident = uint64(fd) k.Filter = int16(mode) @@ -57,14 +40,11 @@ func (cmsg *Cmsghdr) SetLen(length int) { func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic -// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions -// of darwin/arm64 the syscall is called sysctl instead of __sysctl. -const SYS___SYSCTL = SYS_SYSCTL - //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT //sys Lstat(path string, stat *Stat_t) (err error) +//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys Stat(path string, stat *Stat_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 8a195ae586..a4f2944a24 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -47,6 +47,10 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } +func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { + return nil, EAFNOSUPPORT +} + // Translate "kern.hostname" to []_C_int{0,1,2,3}. func nametomib(name string) (mib []_C_int, err error) { const siz = unsafe.Sizeof(mib[0]) @@ -101,6 +105,19 @@ func Pipe(p []int) (err error) { return } +//sysnb pipe2(p *[2]_C_int, flags int) (err error) + +func Pipe2(p []int, flags int) error { + if len(p) != 2 { + return EINVAL + } + var pp [2]_C_int + err := pipe2(&pp, flags) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return err +} + //sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) func Pread(fd int, p []byte, offset int64) (n int, err error) { return extpread(fd, p, 0, offset) @@ -129,23 +146,8 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { return } -const ImplementsGetwd = true - //sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD -func Getwd() (string, error) { - var buf [PathMax]byte - _, err := Getcwd(buf[0:]) - if err != nil { - return "", err - } - n := clen(buf[:]) - if n < 1 { - return "", EINVAL - } - return string(buf[:n]), nil -} - func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 6932e7c2c1..acc00c2e6a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -54,6 +54,10 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } +func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { + return nil, EAFNOSUPPORT +} + // Translate "kern.hostname" to []_C_int{0,1,2,3}. func nametomib(name string) (mib []_C_int, err error) { const siz = unsafe.Sizeof(mib[0]) @@ -140,23 +144,8 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { return } -const ImplementsGetwd = true - //sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD -func Getwd() (string, error) { - var buf [PathMax]byte - _, err := Getcwd(buf[0:]) - if err != nil { - return "", err - } - n := clen(buf[:]) - if n < 1 { - return "", EINVAL - } - return string(buf[:n]), nil -} - func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { var ( _p0 unsafe.Pointer diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go index 99e62dcd82..bbc4f3ea54 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go @@ -24,7 +24,7 @@ func bytes2iovec(bs [][]byte) []Iovec { return iovecs } -//sys readv(fd int, iovs []Iovec) (n int, err error) +//sys readv(fd int, iovs []Iovec) (n int, err error) func Readv(fd int, iovs [][]byte) (n int, err error) { iovecs := bytes2iovec(iovs) @@ -32,7 +32,7 @@ func Readv(fd int, iovs [][]byte) (n int, err error) { return n, err } -//sys preadv(fd int, iovs []Iovec, off int64) (n int, err error) +//sys preadv(fd int, iovs []Iovec, off int64) (n int, err error) func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) { iovecs := bytes2iovec(iovs) @@ -40,7 +40,7 @@ func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) { return n, err } -//sys writev(fd int, iovs []Iovec) (n int, err error) +//sys writev(fd int, iovs []Iovec) (n int, err error) func Writev(fd int, iovs [][]byte) (n int, err error) { iovecs := bytes2iovec(iovs) @@ -48,10 +48,43 @@ func Writev(fd int, iovs [][]byte) (n int, err error) { return n, err } -//sys pwritev(fd int, iovs []Iovec, off int64) (n int, err error) +//sys pwritev(fd int, iovs []Iovec, off int64) (n int, err error) func Pwritev(fd int, iovs [][]byte, off int64) (n int, err error) { iovecs := bytes2iovec(iovs) n, err = pwritev(fd, iovecs, off) return n, err } + +//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = libsocket.accept4 + +func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { + var rsa RawSockaddrAny + var len _Socklen = SizeofSockaddrAny + nfd, err = accept4(fd, &rsa, &len, flags) + if err != nil { + return + } + if len > SizeofSockaddrAny { + panic("RawSockaddrAny too small") + } + sa, err = anyToSockaddr(fd, &rsa) + if err != nil { + Close(nfd) + nfd = 0 + } + return +} + +//sysnb pipe2(p *[2]_C_int, flags int) (err error) + +func Pipe2(p []int, flags int) error { + if len(p) != 2 { + return EINVAL + } + var pp [2]_C_int + err := pipe2(&pp, flags) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return err +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go index 942a4bbf74..28be1306ec 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -82,21 +82,18 @@ func IoctlRetInt(fd int, req uint) (int, error) { return int(ret), nil } -// IoctlSetPointerInt performs an ioctl operation which sets an -// integer value on fd, using the specified request number. The ioctl -// argument is called with a pointer to the integer value, rather than -// passing the integer value directly. -func IoctlSetPointerInt(fd int, req uint, value int) error { - v := int32(value) - return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) -} - func IoctlSetRTCTime(fd int, value *RTCTime) error { err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) runtime.KeepAlive(value) return err } +func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { + err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + func IoctlGetUint32(fd int, req uint) (uint32, error) { var value uint32 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) @@ -109,6 +106,53 @@ func IoctlGetRTCTime(fd int) (*RTCTime, error) { return &value, err } +// IoctlGetWatchdogInfo fetches information about a watchdog device from the +// Linux watchdog API. For more information, see: +// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. +func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { + var value WatchdogInfo + err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { + var value RTCWkAlrm + err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the +// range of data conveyed in value to the file associated with the file +// descriptor destFd. See the ioctl_ficlonerange(2) man page for details. +func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { + err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + +// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file +// associated with the file description srcFd to the file associated with the +// file descriptor destFd. See the ioctl_ficlone(2) man page for details. +func IoctlFileClone(destFd, srcFd int) error { + return ioctl(destFd, FICLONE, uintptr(srcFd)) +} + +// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the +// range of data conveyed in value with the file associated with the file +// descriptor destFd. See the ioctl_fideduperange(2) man page for details. +func IoctlFileDedupeRange(destFd int, value *FileDedupeRange) error { + err := ioctl(destFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + +// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For +// more information, see: +// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. +func IoctlWatchdogKeepalive(fd int) error { + return ioctl(fd, WDIOC_KEEPALIVE, 0) +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { @@ -133,6 +177,12 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) return openat(dirfd, path, flags|O_LARGEFILE, mode) } +//sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) + +func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { + return openat2(dirfd, path, how, SizeofOpenHow) +} + //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { @@ -591,6 +641,36 @@ func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil } +// SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939 +// protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information +// on the purposes of the fields, check the official linux kernel documentation +// available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst +type SockaddrCANJ1939 struct { + Ifindex int + Name uint64 + PGN uint32 + Addr uint8 + raw RawSockaddrCAN +} + +func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { + if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { + return nil, 0, EINVAL + } + sa.raw.Family = AF_CAN + sa.raw.Ifindex = int32(sa.Ifindex) + n := (*[8]byte)(unsafe.Pointer(&sa.Name)) + for i := 0; i < 8; i++ { + sa.raw.Addr[i] = n[i] + } + p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) + for i := 0; i < 4; i++ { + sa.raw.Addr[i+8] = p[i] + } + sa.raw.Addr[12] = sa.Addr + return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil +} + // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. // SockaddrALG enables userspace access to the Linux kernel's cryptography // subsystem. The Type and Name fields specify which type of hash or cipher @@ -873,6 +953,39 @@ func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil } +// SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets. +type SockaddrIUCV struct { + UserID string + Name string + raw RawSockaddrIUCV +} + +func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Family = AF_IUCV + // These are EBCDIC encoded by the kernel, but we still need to pad them + // with blanks. Initializing with blanks allows the caller to feed in either + // a padded or an unpadded string. + for i := 0; i < 8; i++ { + sa.raw.Nodeid[i] = ' ' + sa.raw.User_id[i] = ' ' + sa.raw.Name[i] = ' ' + } + if len(sa.UserID) > 8 || len(sa.Name) > 8 { + return nil, 0, EINVAL + } + for i, b := range []byte(sa.UserID[:]) { + sa.raw.User_id[i] = int8(b) + } + for i, b := range []byte(sa.Name[:]) { + sa.raw.Name[i] = int8(b) + } + return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil +} + +var socketProtocol = func(fd int) (int, error) { + return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) +} + func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_NETLINK: @@ -923,7 +1036,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { return sa, nil case AF_INET: - proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) + proto, err := socketProtocol(fd) if err != nil { return nil, err } @@ -949,7 +1062,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { } case AF_INET6: - proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) + proto, err := socketProtocol(fd) if err != nil { return nil, err } @@ -984,7 +1097,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { } return sa, nil case AF_BLUETOOTH: - proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) + proto, err := socketProtocol(fd) if err != nil { return nil, err } @@ -1053,6 +1166,61 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { } return sa, nil + case AF_IUCV: + pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa)) + + var user [8]byte + var name [8]byte + + for i := 0; i < 8; i++ { + user[i] = byte(pp.User_id[i]) + name[i] = byte(pp.Name[i]) + } + + sa := &SockaddrIUCV{ + UserID: string(user[:]), + Name: string(name[:]), + } + return sa, nil + + case AF_CAN: + proto, err := socketProtocol(fd) + if err != nil { + return nil, err + } + + pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa)) + + switch proto { + case CAN_J1939: + sa := &SockaddrCANJ1939{ + Ifindex: int(pp.Ifindex), + } + name := (*[8]byte)(unsafe.Pointer(&sa.Name)) + for i := 0; i < 8; i++ { + name[i] = pp.Addr[i] + } + pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) + for i := 0; i < 4; i++ { + pgn[i] = pp.Addr[i+8] + } + addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) + addr[0] = pp.Addr[12] + return sa, nil + default: + sa := &SockaddrCAN{ + Ifindex: int(pp.Ifindex), + } + rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) + for i := 0; i < 4; i++ { + rx[i] = pp.Addr[i] + } + tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) + for i := 0; i < 4; i++ { + tx[i] = pp.Addr[i+4] + } + return sa, nil + } } return nil, EAFNOSUPPORT } @@ -1938,11 +2106,30 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { return int(n), nil } +func isGroupMember(gid int) bool { + groups, err := Getgroups() + if err != nil { + return false + } + + for _, g := range groups { + if g == gid { + return true + } + } + return false +} + //sys faccessat(dirfd int, path string, mode uint32) (err error) +//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { - return EINVAL + if flags == 0 { + return faccessat(dirfd, path, mode) + } + + if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM { + return err } // The Linux kernel faccessat system call does not take any flags. @@ -1951,8 +2138,8 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { // Because people naturally expect syscall.Faccessat to act // like C faccessat, we do the same. - if flags == 0 { - return faccessat(dirfd, path, mode) + if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { + return EINVAL } var st Stat_t @@ -1995,7 +2182,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { gid = Getgid() } - if uint32(gid) == st.Gid { + if uint32(gid) == st.Gid || isGroupMember(gid) { fmode = (st.Mode >> 3) & 7 } else { fmode = st.Mode & 7 @@ -2096,6 +2283,18 @@ func Klogset(typ int, arg int) (err error) { return nil } +// RemoteIovec is Iovec with the pointer replaced with an integer. +// It is used for ProcessVMReadv and ProcessVMWritev, where the pointer +// refers to a location in a different process' address space, which +// would confuse the Go garbage collector. +type RemoteIovec struct { + Base uintptr + Len int +} + +//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV +//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV + /* * Unimplemented */ diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go index 048d18e3c8..c97c2ee53e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP) -// so that go vet can check that they are correct. - // +build 386,linux package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go index 21a4946ba5..baa771f8ad 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build amd64,linux -// +build !gccgo +// +build gc package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go index e1913e2c93..496837b1e3 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go @@ -7,7 +7,6 @@ package unix import ( - "syscall" "unsafe" ) @@ -49,10 +48,6 @@ func Pipe2(p []int, flags int) (err error) { return } -// Underlying system call writes to newoffset via pointer. -// Implemented in assembly to avoid allocation. -func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) - func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { newoffset, errno := seek(fd, offset, whence) if errno != 0 { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go index c26e6ec231..9edf3961b0 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build linux,!gccgo +// +build linux,gc package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go index 070bd38994..90e33d8cf7 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build linux,!gccgo,386 +// +build linux,gc,386 package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go new file mode 100644 index 0000000000..1a97baae73 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm,gc,linux + +package unix + +import "syscall" + +// Underlying system call writes to newoffset via pointer. +// Implemented in assembly to avoid allocation. +func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 45b50a6105..1e6843b4c3 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -31,6 +31,10 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } +func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { + return nil, EAFNOSUPPORT +} + func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) { @@ -141,23 +145,8 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { return } -const ImplementsGetwd = true - //sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD -func Getwd() (string, error) { - var buf [PathMax]byte - _, err := Getcwd(buf[0:]) - if err != nil { - return "", err - } - n := clen(buf[:]) - if n < 1 { - return "", EINVAL - } - return string(buf[:n]), nil -} - // TODO func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { return -1, ENOSYS diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go index a266e92a9b..6a50b50bd6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -31,6 +31,10 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } +func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { + return nil, EAFNOSUPPORT +} + func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func nametomib(name string) (mib []_C_int, err error) { @@ -114,23 +118,8 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { return } -const ImplementsGetwd = true - //sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD -func Getwd() (string, error) { - var buf [PathMax]byte - _, err := Getcwd(buf[0:]) - if err != nil { - return "", err - } - n := clen(buf[:]) - if n < 1 { - return "", EINVAL - } - return string(buf[:n]), nil -} - func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { if raceenabled { raceReleaseMerge(unsafe.Pointer(&ioSync)) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go new file mode 100644 index 0000000000..30f285343e --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go @@ -0,0 +1,35 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} +} + +func SetKevent(k *Kevent_t, fd, mode, flags int) { + k.Ident = uint64(fd) + k.Filter = int16(mode) + k.Flags = uint16(flags) +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint32(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint32(length) +} + +// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions +// of OpenBSD the syscall is called sysctl instead of __sysctl. +const SYS___SYSCTL = SYS_SYSCTL diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go index 0e2a696ad3..fee6e99528 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -13,6 +13,7 @@ package unix import ( + "runtime" "syscall" "unsafe" ) @@ -553,8 +554,10 @@ func Minor(dev uint64) uint32 { //sys ioctl(fd int, req uint, arg uintptr) (err error) -func IoctlSetTermio(fd int, req uint, value *Termio) (err error) { - return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +func IoctlSetTermio(fd int, req uint, value *Termio) error { + err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err } func IoctlGetTermio(fd int, req uint) (*Termio, error) { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go index 1c70d1b690..87bd161cef 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build darwin dragonfly freebsd linux netbsd openbsd solaris -// +build !gccgo,!ppc64le,!ppc64 +// +build gc,!ppc64le,!ppc64 package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go index 86dc765aba..d36216c3ca 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go @@ -4,7 +4,7 @@ // +build linux // +build ppc64le ppc64 -// +build !gccgo +// +build gc package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go index 6217cdba57..ec376f51bc 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go @@ -45,6 +45,7 @@ const ( AF_SIP = 0x18 AF_SNA = 0xb AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 AF_UNIX = 0x1 AF_UNSPEC = 0x0 AF_UTUN = 0x26 @@ -232,6 +233,8 @@ const ( CLOCK_THREAD_CPUTIME_ID = 0x10 CLOCK_UPTIME_RAW = 0x8 CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -249,6 +252,7 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 CTL_HW = 0x6 CTL_KERN = 0x1 CTL_MAXNAME = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index e3ff2ee3d4..fea5dfaadb 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -45,6 +45,7 @@ const ( AF_SIP = 0x18 AF_SNA = 0xb AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 AF_UNIX = 0x1 AF_UNSPEC = 0x0 AF_UTUN = 0x26 @@ -232,6 +233,8 @@ const ( CLOCK_THREAD_CPUTIME_ID = 0x10 CLOCK_UPTIME_RAW = 0x8 CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -249,6 +252,7 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 CTL_HW = 0x6 CTL_KERN = 0x1 CTL_MAXNAME = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go index 3e417571a9..03feefbf8c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go @@ -45,6 +45,7 @@ const ( AF_SIP = 0x18 AF_SNA = 0xb AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 AF_UNIX = 0x1 AF_UNSPEC = 0x0 AF_UTUN = 0x26 @@ -232,6 +233,8 @@ const ( CLOCK_THREAD_CPUTIME_ID = 0x10 CLOCK_UPTIME_RAW = 0x8 CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -249,6 +252,7 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 CTL_HW = 0x6 CTL_KERN = 0x1 CTL_MAXNAME = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index cbd8ed18b9..b40fb1f696 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -45,6 +45,7 @@ const ( AF_SIP = 0x18 AF_SNA = 0xb AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 AF_UNIX = 0x1 AF_UNSPEC = 0x0 AF_UTUN = 0x26 @@ -232,6 +233,8 @@ const ( CLOCK_THREAD_CPUTIME_ID = 0x10 CLOCK_UPTIME_RAW = 0x8 CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -249,6 +252,7 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 CTL_HW = 0x6 CTL_KERN = 0x1 CTL_MAXNAME = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go index 6130471748..f5e91b7aba 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go @@ -62,6 +62,7 @@ const ( B28800 = 0x7080 B300 = 0x12c B38400 = 0x9600 + B460800 = 0x70800 B4800 = 0x12c0 B50 = 0x32 B57600 = 0xe100 @@ -69,12 +70,15 @@ const ( B7200 = 0x1c20 B75 = 0x4b B76800 = 0x12c00 + B921600 = 0xe1000 B9600 = 0x2580 + BIOCFEEDBACK = 0x8004427d BIOCFLUSH = 0x20004268 BIOCGBLEN = 0x40044266 BIOCGDLT = 0x4004426a BIOCGDLTLIST = 0xc0104279 BIOCGETIF = 0x4020426b + BIOCGFEEDBACK = 0x4004427c BIOCGHDRCMPLT = 0x40044274 BIOCGRSIG = 0x40044272 BIOCGRTIMEOUT = 0x4010426e @@ -88,6 +92,7 @@ const ( BIOCSETF = 0x80104267 BIOCSETIF = 0x8020426c BIOCSETWF = 0x8010427b + BIOCSFEEDBACK = 0x8004427d BIOCSHDRCMPLT = 0x80044275 BIOCSRSIG = 0x80044273 BIOCSRTIMEOUT = 0x8010426d @@ -125,6 +130,7 @@ const ( BPF_MINBUFSIZE = 0x20 BPF_MINOR_VERSION = 0x1 BPF_MISC = 0x7 + BPF_MOD = 0x90 BPF_MSH = 0xa0 BPF_MUL = 0x20 BPF_NEG = 0x80 @@ -139,6 +145,7 @@ const ( BPF_TXA = 0x80 BPF_W = 0x0 BPF_X = 0x8 + BPF_XOR = 0xa0 BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 @@ -156,6 +163,12 @@ const ( CLOCK_UPTIME_FAST = 0x8 CLOCK_UPTIME_PRECISE = 0x7 CLOCK_VIRTUAL = 0x1 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x30000 CS5 = 0x0 @@ -175,6 +188,7 @@ const ( DLT_A429 = 0xb8 DLT_A653_ICM = 0xb9 DLT_AIRONET_HEADER = 0x78 + DLT_AOS = 0xde DLT_APPLE_IP_OVER_IEEE1394 = 0x8a DLT_ARCNET = 0x7 DLT_ARCNET_LINUX = 0x81 @@ -184,22 +198,33 @@ const ( DLT_AX25 = 0x3 DLT_AX25_KISS = 0xca DLT_BACNET_MS_TP = 0xa5 + DLT_BLUETOOTH_BREDR_BB = 0xff DLT_BLUETOOTH_HCI_H4 = 0xbb DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 + DLT_BLUETOOTH_LE_LL = 0xfb + DLT_BLUETOOTH_LE_LL_WITH_PHDR = 0x100 + DLT_BLUETOOTH_LINUX_MONITOR = 0xfe DLT_CAN20B = 0xbe + DLT_CAN_SOCKETCAN = 0xe3 DLT_CHAOS = 0x5 DLT_CHDLC = 0x68 DLT_CISCO_IOS = 0x76 DLT_C_HDLC = 0x68 DLT_C_HDLC_WITH_DIR = 0xcd + DLT_DBUS = 0xe7 + DLT_DECT = 0xdd DLT_DOCSIS = 0x8f + DLT_DVB_CI = 0xeb DLT_ECONET = 0x73 DLT_EN10MB = 0x1 DLT_EN3MB = 0x2 DLT_ENC = 0x6d + DLT_EPON = 0x103 DLT_ERF = 0xc5 DLT_ERF_ETH = 0xaf DLT_ERF_POS = 0xb0 + DLT_FC_2 = 0xe0 + DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 DLT_FDDI = 0xa DLT_FLEXRAY = 0xd2 DLT_FRELAY = 0x6b @@ -209,6 +234,8 @@ const ( DLT_GPF_F = 0xab DLT_GPF_T = 0xaa DLT_GPRS_LLC = 0xa9 + DLT_GSMTAP_ABIS = 0xda + DLT_GSMTAP_UM = 0xd9 DLT_HHDLC = 0x79 DLT_IBM_SN = 0x92 DLT_IBM_SP = 0x91 @@ -218,18 +245,28 @@ const ( DLT_IEEE802_11_RADIO_AVS = 0xa3 DLT_IEEE802_15_4 = 0xc3 DLT_IEEE802_15_4_LINUX = 0xbf + DLT_IEEE802_15_4_NOFCS = 0xe6 DLT_IEEE802_15_4_NONASK_PHY = 0xd7 DLT_IEEE802_16_MAC_CPS = 0xbc DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 + DLT_INFINIBAND = 0xf7 DLT_IPFILTER = 0x74 DLT_IPMB = 0xc7 DLT_IPMB_LINUX = 0xd1 + DLT_IPMI_HPM_2 = 0x104 + DLT_IPNET = 0xe2 + DLT_IPOIB = 0xf2 + DLT_IPV4 = 0xe4 + DLT_IPV6 = 0xe5 DLT_IP_OVER_FC = 0x7a + DLT_ISO_14443 = 0x108 DLT_JUNIPER_ATM1 = 0x89 DLT_JUNIPER_ATM2 = 0x87 + DLT_JUNIPER_ATM_CEMIC = 0xee DLT_JUNIPER_CHDLC = 0xb5 DLT_JUNIPER_ES = 0x84 DLT_JUNIPER_ETHER = 0xb2 + DLT_JUNIPER_FIBRECHANNEL = 0xea DLT_JUNIPER_FRELAY = 0xb4 DLT_JUNIPER_GGSN = 0x85 DLT_JUNIPER_ISM = 0xc2 @@ -242,25 +279,40 @@ const ( DLT_JUNIPER_PPPOE = 0xa7 DLT_JUNIPER_PPPOE_ATM = 0xa8 DLT_JUNIPER_SERVICES = 0x88 + DLT_JUNIPER_SRX_E2E = 0xe9 DLT_JUNIPER_ST = 0xc8 DLT_JUNIPER_VP = 0xb7 + DLT_JUNIPER_VS = 0xe8 DLT_LAPB_WITH_DIR = 0xcf DLT_LAPD = 0xcb DLT_LIN = 0xd4 + DLT_LINUX_EVDEV = 0xd8 DLT_LINUX_IRDA = 0x90 DLT_LINUX_LAPD = 0xb1 DLT_LINUX_SLL = 0x71 DLT_LOOP = 0x6c DLT_LTALK = 0x72 + DLT_MATCHING_MAX = 0x109 + DLT_MATCHING_MIN = 0x68 DLT_MFR = 0xb6 DLT_MOST = 0xd3 + DLT_MPEG_2_TS = 0xf3 + DLT_MPLS = 0xdb DLT_MTP2 = 0x8c DLT_MTP2_WITH_PHDR = 0x8b DLT_MTP3 = 0x8d + DLT_MUX27010 = 0xec + DLT_NETANALYZER = 0xf0 + DLT_NETANALYZER_TRANSPARENT = 0xf1 + DLT_NETLINK = 0xfd + DLT_NFC_LLCP = 0xf5 + DLT_NFLOG = 0xef + DLT_NG40 = 0xf4 DLT_NULL = 0x0 DLT_PCI_EXP = 0x7d DLT_PFLOG = 0x75 DLT_PFSYNC = 0x12 + DLT_PKTAP = 0x102 DLT_PPI = 0xc0 DLT_PPP = 0x9 DLT_PPP_BSDOS = 0x10 @@ -269,22 +321,51 @@ const ( DLT_PPP_SERIAL = 0x32 DLT_PPP_WITH_DIR = 0xcc DLT_PRISM_HEADER = 0x77 + DLT_PROFIBUS_DL = 0x101 DLT_PRONET = 0x4 DLT_RAIF1 = 0xc6 DLT_RAW = 0xc + DLT_RDS = 0x109 DLT_REDBACK_SMARTEDGE = 0x20 DLT_RIO = 0x7c + DLT_RTAC_SERIAL = 0xfa DLT_SCCP = 0x8e + DLT_SCTP = 0xf8 DLT_SITA = 0xc4 DLT_SLIP = 0x8 DLT_SLIP_BSDOS = 0xf + DLT_STANAG_5066_D_PDU = 0xed DLT_SUNATM = 0x7b DLT_SYMANTEC_FIREWALL = 0x63 DLT_TZSP = 0x80 DLT_USB = 0xba + DLT_USBPCAP = 0xf9 + DLT_USB_FREEBSD = 0xba DLT_USB_LINUX = 0xbd + DLT_USB_LINUX_MMAPPED = 0xdc + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DLT_WATTSTOPPER_DLM = 0x107 + DLT_WIHART = 0xdf + DLT_WIRESHARK_UPPER_PDU = 0xfc DLT_X2E_SERIAL = 0xd5 DLT_X2E_XORAYA = 0xd6 + DLT_ZWAVE_R1_R2 = 0x105 + DLT_ZWAVE_R3 = 0x106 DT_BLK = 0x6 DT_CHR = 0x2 DT_DBF = 0xf @@ -323,10 +404,11 @@ const ( EV_EOF = 0x8000 EV_ERROR = 0x4000 EV_FLAG1 = 0x2000 + EV_HUP = 0x800 EV_NODATA = 0x1000 EV_ONESHOT = 0x10 EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 + EV_SYSFLAGS = 0xf800 EXTA = 0x4b00 EXTB = 0x9600 EXTEXIT_LWP = 0x10000 @@ -365,8 +447,9 @@ const ( IFF_ALLMULTI = 0x200 IFF_ALTPHYS = 0x4000 IFF_BROADCAST = 0x2 - IFF_CANTCHANGE = 0x118e72 + IFF_CANTCHANGE = 0x318e72 IFF_DEBUG = 0x4 + IFF_IDIRECT = 0x200000 IFF_LINK0 = 0x1000 IFF_LINK1 = 0x2000 IFF_LINK2 = 0x4000 @@ -441,7 +524,6 @@ const ( IFT_EPLRS = 0x57 IFT_ESCON = 0x49 IFT_ETHER = 0x6 - IFT_FAITH = 0xf2 IFT_FAST = 0x7d IFT_FASTETHER = 0x3e IFT_FASTETHERFX = 0x45 @@ -614,6 +696,7 @@ const ( IN_CLASSD_NET = 0xf0000000 IN_CLASSD_NSHIFT = 0x1c IN_LOOPBACKNET = 0x7f + IN_RFC3021_MASK = 0xfffffffe IPPROTO_3PC = 0x22 IPPROTO_ADFS = 0x44 IPPROTO_AH = 0x33 @@ -735,7 +818,6 @@ const ( IPV6_DEFHLIM = 0x40 IPV6_DONTFRAG = 0x3e IPV6_DSTOPTS = 0x32 - IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 IPV6_FRAGTTL = 0x78 @@ -747,7 +829,6 @@ const ( IPV6_HLIMDEC = 0x1 IPV6_HOPLIMIT = 0x2f IPV6_HOPOPTS = 0x31 - IPV6_IPSEC_POLICY = 0x1c IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd IPV6_MAXHLIM = 0xff @@ -795,16 +876,22 @@ const ( IP_DUMMYNET_DEL = 0x3d IP_DUMMYNET_FLUSH = 0x3e IP_DUMMYNET_GET = 0x40 - IP_FAITH = 0x16 IP_FW_ADD = 0x32 IP_FW_DEL = 0x33 IP_FW_FLUSH = 0x34 IP_FW_GET = 0x36 IP_FW_RESETLOG = 0x37 + IP_FW_TBL_ADD = 0x2a + IP_FW_TBL_CREATE = 0x28 + IP_FW_TBL_DEL = 0x2b + IP_FW_TBL_DESTROY = 0x29 + IP_FW_TBL_EXPIRE = 0x2f + IP_FW_TBL_FLUSH = 0x2c + IP_FW_TBL_GET = 0x2d + IP_FW_TBL_ZERO = 0x2e IP_FW_X = 0x31 IP_FW_ZERO = 0x35 IP_HDRINCL = 0x2 - IP_IPSEC_POLICY = 0x15 IP_MAXPACKET = 0xffff IP_MAX_MEMBERSHIPS = 0x14 IP_MF = 0x2000 @@ -1080,12 +1167,10 @@ const ( RTM_MISS = 0x7 RTM_NEWADDR = 0xc RTM_NEWMADDR = 0xf - RTM_OLDADD = 0x9 - RTM_OLDDEL = 0xa RTM_REDIRECT = 0x6 RTM_RESOLVE = 0xb RTM_RTTUNIT = 0xf4240 - RTM_VERSION = 0x6 + RTM_VERSION = 0x7 RTV_EXPIRE = 0x4 RTV_HOPCOUNT = 0x2 RTV_IWCAPSEGS = 0x400 @@ -1106,13 +1191,13 @@ const ( SHUT_RDWR = 0x2 SHUT_WR = 0x1 SIOCADDMULTI = 0x80206931 - SIOCADDRT = 0x8040720a SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 SIOCALIFADDR = 0x8118691b SIOCATMARK = 0x40047307 SIOCDELMULTI = 0x80206932 - SIOCDELRT = 0x8040720b SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 SIOCDIFPHYADDR = 0x80206949 SIOCDLIFADDR = 0x8118691d SIOCGDRVSPEC = 0xc028697b @@ -1120,6 +1205,7 @@ const ( SIOCGETVIFCNT = 0xc028720f SIOCGHIWAT = 0x40047301 SIOCGIFADDR = 0xc0206921 + SIOCGIFALIAS = 0xc0406929 SIOCGIFBRDADDR = 0xc0206923 SIOCGIFCAP = 0xc020691f SIOCGIFCONF = 0xc0106924 @@ -1128,6 +1214,7 @@ const ( SIOCGIFFLAGS = 0xc0206911 SIOCGIFGENERIC = 0xc020693a SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 SIOCGIFINDEX = 0xc0206920 SIOCGIFMEDIA = 0xc0306938 SIOCGIFMETRIC = 0xc0206917 @@ -1194,6 +1281,7 @@ const ( SO_RCVBUF = 0x1002 SO_RCVLOWAT = 0x1004 SO_RCVTIMEO = 0x1006 + SO_RERROR = 0x2000 SO_REUSEADDR = 0x4 SO_REUSEPORT = 0x200 SO_SNDBUF = 0x1001 @@ -1233,6 +1321,9 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 + TAB0 = 0x0 + TAB3 = 0x4 + TABDLY = 0x4 TCIFLUSH = 0x1 TCIOFF = 0x3 TCIOFLUSH = 0x3 @@ -1259,6 +1350,8 @@ const ( TCP_NOPUSH = 0x4 TCP_SIGNATURE_ENABLE = 0x10 TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 TIOCCONS = 0x80047462 @@ -1272,7 +1365,6 @@ const ( TIOCGETD = 0x4004741a TIOCGPGRP = 0x40047477 TIOCGSID = 0x40047463 - TIOCGSIZE = 0x40087468 TIOCGWINSZ = 0x40087468 TIOCISPTMASTER = 0x20007455 TIOCMBIC = 0x8004746b @@ -1317,7 +1409,6 @@ const ( TIOCSETD = 0x8004741b TIOCSIG = 0x2000745f TIOCSPGRP = 0x80047476 - TIOCSSIZE = 0x80087467 TIOCSTART = 0x2000746e TIOCSTAT = 0x20007465 TIOCSTI = 0x80017472 @@ -1326,6 +1417,8 @@ const ( TIOCTIMESTAMP = 0x40107459 TIOCUCNTL = 0x80047466 TOSTOP = 0x400000 + UTIME_NOW = -0x1 + UTIME_OMIT = -0x2 VCHECKPT = 0x13 VDISCARD = 0xf VDSUSP = 0xb @@ -1350,9 +1443,12 @@ const ( VWERASE = 0x4 WCONTINUED = 0x4 WCOREFLAG = 0x80 + WEXITED = 0x10 WLINUXCLONE = 0x80000000 WNOHANG = 0x1 - WSTOPPED = 0x7f + WNOWAIT = 0x8 + WSTOPPED = 0x2 + WTRAPPED = 0x20 WUNTRACED = 0x2 ) @@ -1452,11 +1548,6 @@ const ( ETIMEDOUT = syscall.Errno(0x3c) ETOOMANYREFS = syscall.Errno(0x3b) ETXTBSY = syscall.Errno(0x1a) - EUNUSED94 = syscall.Errno(0x5e) - EUNUSED95 = syscall.Errno(0x5f) - EUNUSED96 = syscall.Errno(0x60) - EUNUSED97 = syscall.Errno(0x61) - EUNUSED98 = syscall.Errno(0x62) EUSERS = syscall.Errno(0x44) EWOULDBLOCK = syscall.Errno(0x23) EXDEV = syscall.Errno(0x12) @@ -1600,12 +1691,7 @@ var errorList = [...]struct { {91, "ENOLINK", "link has been severed"}, {92, "EPROTO", "protocol error"}, {93, "ENOMEDIUM", "no medium found"}, - {94, "EUNUSED94", "unknown error: 94"}, - {95, "EUNUSED95", "unknown error: 95"}, - {96, "EUNUSED96", "unknown error: 96"}, - {97, "EUNUSED97", "unknown error: 97"}, - {98, "EUNUSED98", "unknown error: 98"}, - {99, "ELAST", "unknown error: 99"}, + {99, "EASYNC", "unknown error: 99"}, } // Signal table diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go index 8482458734..3689c80848 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go @@ -339,6 +339,12 @@ const ( CLOCK_UPTIME_FAST = 0x8 CLOCK_UPTIME_PRECISE = 0x7 CLOCK_VIRTUAL = 0x1 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x30000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go index 4acd101c3e..b8f7c3c930 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go @@ -339,6 +339,12 @@ const ( CLOCK_UPTIME_FAST = 0x8 CLOCK_UPTIME_PRECISE = 0x7 CLOCK_VIRTUAL = 0x1 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x30000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go index e4719873b9..be14bb1a4c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go @@ -339,6 +339,12 @@ const ( CLOCK_UPTIME_FAST = 0x8 CLOCK_UPTIME_PRECISE = 0x7 CLOCK_VIRTUAL = 0x1 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x30000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go index 5e49769d96..7ce9c0081a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go @@ -339,6 +339,12 @@ const ( CLOCK_UPTIME_FAST = 0x8 CLOCK_UPTIME_PRECISE = 0x7 CLOCK_VIRTUAL = 0x1 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x30000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go index 6e3cfec46c..b46110354d 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -160,78 +160,28 @@ const ( BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 - BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff - BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38 BPF_ALU = 0x4 BPF_ALU64 = 0x7 BPF_AND = 0x50 - BPF_ANY = 0x0 BPF_ARSH = 0xc0 BPF_B = 0x10 BPF_BUILD_ID_SIZE = 0x14 BPF_CALL = 0x80 - BPF_DEVCG_ACC_MKNOD = 0x1 - BPF_DEVCG_ACC_READ = 0x2 - BPF_DEVCG_ACC_WRITE = 0x4 - BPF_DEVCG_DEV_BLOCK = 0x1 - BPF_DEVCG_DEV_CHAR = 0x2 BPF_DIV = 0x30 BPF_DW = 0x18 BPF_END = 0xd0 - BPF_EXIST = 0x2 BPF_EXIT = 0x90 - BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = 0x1 - BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = 0x4 - BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2 BPF_FROM_BE = 0x8 BPF_FROM_LE = 0x0 BPF_FS_MAGIC = 0xcafe4a11 - BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = 0x2 - BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = 0x4 - BPF_F_ADJ_ROOM_ENCAP_L4_GRE = 0x8 - BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10 - BPF_F_ADJ_ROOM_FIXED_GSO = 0x1 BPF_F_ALLOW_MULTI = 0x2 BPF_F_ALLOW_OVERRIDE = 0x1 BPF_F_ANY_ALIGNMENT = 0x2 - BPF_F_CLONE = 0x200 - BPF_F_CTXLEN_MASK = 0xfffff00000000 - BPF_F_CURRENT_CPU = 0xffffffff - BPF_F_CURRENT_NETNS = -0x1 - BPF_F_DONT_FRAGMENT = 0x4 - BPF_F_FAST_STACK_CMP = 0x200 - BPF_F_HDR_FIELD_MASK = 0xf - BPF_F_INDEX_MASK = 0xffffffff - BPF_F_INGRESS = 0x1 - BPF_F_INVALIDATE_HASH = 0x2 - BPF_F_LOCK = 0x4 - BPF_F_MARK_ENFORCE = 0x40 - BPF_F_MARK_MANGLED_0 = 0x20 - BPF_F_MMAPABLE = 0x400 - BPF_F_NO_COMMON_LRU = 0x2 - BPF_F_NO_PREALLOC = 0x1 - BPF_F_NUMA_NODE = 0x4 - BPF_F_PSEUDO_HDR = 0x10 BPF_F_QUERY_EFFECTIVE = 0x1 - BPF_F_RDONLY = 0x8 - BPF_F_RDONLY_PROG = 0x80 - BPF_F_RECOMPUTE_CSUM = 0x1 BPF_F_REPLACE = 0x4 - BPF_F_REUSE_STACKID = 0x400 - BPF_F_SEQ_NUMBER = 0x8 - BPF_F_SKIP_FIELD_MASK = 0xff - BPF_F_STACK_BUILD_ID = 0x20 BPF_F_STRICT_ALIGNMENT = 0x1 - BPF_F_SYSCTL_BASE_NAME = 0x1 BPF_F_TEST_RND_HI32 = 0x4 BPF_F_TEST_STATE_FREQ = 0x8 - BPF_F_TUNINFO_IPV6 = 0x1 - BPF_F_USER_BUILD_ID = 0x800 - BPF_F_USER_STACK = 0x100 - BPF_F_WRONLY = 0x10 - BPF_F_WRONLY_PROG = 0x100 - BPF_F_ZERO_CSUM_TX = 0x2 - BPF_F_ZERO_SEED = 0x40 BPF_H = 0x8 BPF_IMM = 0x0 BPF_IND = 0x40 @@ -267,7 +217,6 @@ const ( BPF_MUL = 0x20 BPF_NEG = 0x80 BPF_NET_OFF = -0x100000 - BPF_NOEXIST = 0x1 BPF_OBJ_NAME_LEN = 0x10 BPF_OR = 0x40 BPF_PSEUDO_CALL = 0x1 @@ -275,12 +224,6 @@ const ( BPF_PSEUDO_MAP_VALUE = 0x2 BPF_RET = 0x6 BPF_RSH = 0x70 - BPF_SK_STORAGE_GET_F_CREATE = 0x1 - BPF_SOCK_OPS_ALL_CB_FLAGS = 0xf - BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2 - BPF_SOCK_OPS_RTO_CB_FLAG = 0x1 - BPF_SOCK_OPS_RTT_CB_FLAG = 0x8 - BPF_SOCK_OPS_STATE_CB_FLAG = 0x4 BPF_ST = 0x2 BPF_STX = 0x3 BPF_SUB = 0x10 @@ -301,8 +244,66 @@ const ( CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d CAN_EFF_MASK = 0x1fffffff + CAN_ERR_ACK = 0x20 + CAN_ERR_BUSERROR = 0x80 + CAN_ERR_BUSOFF = 0x40 + CAN_ERR_CRTL = 0x4 + CAN_ERR_CRTL_ACTIVE = 0x40 + CAN_ERR_CRTL_RX_OVERFLOW = 0x1 + CAN_ERR_CRTL_RX_PASSIVE = 0x10 + CAN_ERR_CRTL_RX_WARNING = 0x4 + CAN_ERR_CRTL_TX_OVERFLOW = 0x2 + CAN_ERR_CRTL_TX_PASSIVE = 0x20 + CAN_ERR_CRTL_TX_WARNING = 0x8 + CAN_ERR_CRTL_UNSPEC = 0x0 + CAN_ERR_DLC = 0x8 CAN_ERR_FLAG = 0x20000000 + CAN_ERR_LOSTARB = 0x2 + CAN_ERR_LOSTARB_UNSPEC = 0x0 CAN_ERR_MASK = 0x1fffffff + CAN_ERR_PROT = 0x8 + CAN_ERR_PROT_ACTIVE = 0x40 + CAN_ERR_PROT_BIT = 0x1 + CAN_ERR_PROT_BIT0 = 0x8 + CAN_ERR_PROT_BIT1 = 0x10 + CAN_ERR_PROT_FORM = 0x2 + CAN_ERR_PROT_LOC_ACK = 0x19 + CAN_ERR_PROT_LOC_ACK_DEL = 0x1b + CAN_ERR_PROT_LOC_CRC_DEL = 0x18 + CAN_ERR_PROT_LOC_CRC_SEQ = 0x8 + CAN_ERR_PROT_LOC_DATA = 0xa + CAN_ERR_PROT_LOC_DLC = 0xb + CAN_ERR_PROT_LOC_EOF = 0x1a + CAN_ERR_PROT_LOC_ID04_00 = 0xe + CAN_ERR_PROT_LOC_ID12_05 = 0xf + CAN_ERR_PROT_LOC_ID17_13 = 0x7 + CAN_ERR_PROT_LOC_ID20_18 = 0x6 + CAN_ERR_PROT_LOC_ID28_21 = 0x2 + CAN_ERR_PROT_LOC_IDE = 0x5 + CAN_ERR_PROT_LOC_INTERM = 0x12 + CAN_ERR_PROT_LOC_RES0 = 0x9 + CAN_ERR_PROT_LOC_RES1 = 0xd + CAN_ERR_PROT_LOC_RTR = 0xc + CAN_ERR_PROT_LOC_SOF = 0x3 + CAN_ERR_PROT_LOC_SRTR = 0x4 + CAN_ERR_PROT_LOC_UNSPEC = 0x0 + CAN_ERR_PROT_OVERLOAD = 0x20 + CAN_ERR_PROT_STUFF = 0x4 + CAN_ERR_PROT_TX = 0x80 + CAN_ERR_PROT_UNSPEC = 0x0 + CAN_ERR_RESTARTED = 0x100 + CAN_ERR_TRX = 0x10 + CAN_ERR_TRX_CANH_NO_WIRE = 0x4 + CAN_ERR_TRX_CANH_SHORT_TO_BAT = 0x5 + CAN_ERR_TRX_CANH_SHORT_TO_GND = 0x7 + CAN_ERR_TRX_CANH_SHORT_TO_VCC = 0x6 + CAN_ERR_TRX_CANL_NO_WIRE = 0x40 + CAN_ERR_TRX_CANL_SHORT_TO_BAT = 0x50 + CAN_ERR_TRX_CANL_SHORT_TO_CANH = 0x80 + CAN_ERR_TRX_CANL_SHORT_TO_GND = 0x70 + CAN_ERR_TRX_CANL_SHORT_TO_VCC = 0x60 + CAN_ERR_TRX_UNSPEC = 0x0 + CAN_ERR_TX_TIMEOUT = 0x1 CAN_INV_FILTER = 0x20000000 CAN_ISOTP = 0x6 CAN_J1939 = 0x7 @@ -322,6 +323,8 @@ const ( CAP_AUDIT_READ = 0x25 CAP_AUDIT_WRITE = 0x1d CAP_BLOCK_SUSPEND = 0x24 + CAP_BPF = 0x27 + CAP_CHECKPOINT_RESTORE = 0x28 CAP_CHOWN = 0x0 CAP_DAC_OVERRIDE = 0x1 CAP_DAC_READ_SEARCH = 0x2 @@ -330,7 +333,7 @@ const ( CAP_IPC_LOCK = 0xe CAP_IPC_OWNER = 0xf CAP_KILL = 0x5 - CAP_LAST_CAP = 0x25 + CAP_LAST_CAP = 0x28 CAP_LEASE = 0x1c CAP_LINUX_IMMUTABLE = 0x9 CAP_MAC_ADMIN = 0x21 @@ -340,6 +343,7 @@ const ( CAP_NET_BIND_SERVICE = 0xa CAP_NET_BROADCAST = 0xb CAP_NET_RAW = 0xd + CAP_PERFMON = 0x26 CAP_SETFCAP = 0x1f CAP_SETGID = 0x6 CAP_SETPCAP = 0x8 @@ -378,12 +382,14 @@ const ( CLOCK_TXINT = 0x3 CLONE_ARGS_SIZE_VER0 = 0x40 CLONE_ARGS_SIZE_VER1 = 0x50 + CLONE_ARGS_SIZE_VER2 = 0x58 CLONE_CHILD_CLEARTID = 0x200000 CLONE_CHILD_SETTID = 0x1000000 CLONE_CLEAR_SIGHAND = 0x100000000 CLONE_DETACHED = 0x400000 CLONE_FILES = 0x400 CLONE_FS = 0x200 + CLONE_INTO_CGROUP = 0x200000000 CLONE_IO = 0x80000000 CLONE_NEWCGROUP = 0x2000000 CLONE_NEWIPC = 0x8000000 @@ -427,8 +433,54 @@ const ( DEVLINK_GENL_NAME = "devlink" DEVLINK_GENL_VERSION = 0x1 DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX = 0x14 + DEVMEM_MAGIC = 0x454d444d DEVPTS_SUPER_MAGIC = 0x1cd1 DMA_BUF_MAGIC = 0x444d4142 + DM_ACTIVE_PRESENT_FLAG = 0x20 + DM_BUFFER_FULL_FLAG = 0x100 + DM_CONTROL_NODE = "control" + DM_DATA_OUT_FLAG = 0x10000 + DM_DEFERRED_REMOVE = 0x20000 + DM_DEV_ARM_POLL = 0xc138fd10 + DM_DEV_CREATE = 0xc138fd03 + DM_DEV_REMOVE = 0xc138fd04 + DM_DEV_RENAME = 0xc138fd05 + DM_DEV_SET_GEOMETRY = 0xc138fd0f + DM_DEV_STATUS = 0xc138fd07 + DM_DEV_SUSPEND = 0xc138fd06 + DM_DEV_WAIT = 0xc138fd08 + DM_DIR = "mapper" + DM_GET_TARGET_VERSION = 0xc138fd11 + DM_INACTIVE_PRESENT_FLAG = 0x40 + DM_INTERNAL_SUSPEND_FLAG = 0x40000 + DM_IOCTL = 0xfd + DM_LIST_DEVICES = 0xc138fd02 + DM_LIST_VERSIONS = 0xc138fd0d + DM_MAX_TYPE_NAME = 0x10 + DM_NAME_LEN = 0x80 + DM_NOFLUSH_FLAG = 0x800 + DM_PERSISTENT_DEV_FLAG = 0x8 + DM_QUERY_INACTIVE_TABLE_FLAG = 0x1000 + DM_READONLY_FLAG = 0x1 + DM_REMOVE_ALL = 0xc138fd01 + DM_SECURE_DATA_FLAG = 0x8000 + DM_SKIP_BDGET_FLAG = 0x200 + DM_SKIP_LOCKFS_FLAG = 0x400 + DM_STATUS_TABLE_FLAG = 0x10 + DM_SUSPEND_FLAG = 0x2 + DM_TABLE_CLEAR = 0xc138fd0a + DM_TABLE_DEPS = 0xc138fd0b + DM_TABLE_LOAD = 0xc138fd09 + DM_TABLE_STATUS = 0xc138fd0c + DM_TARGET_MSG = 0xc138fd0e + DM_UEVENT_GENERATED_FLAG = 0x2000 + DM_UUID_FLAG = 0x4000 + DM_UUID_LEN = 0x81 + DM_VERSION = 0xc138fd00 + DM_VERSION_EXTRA = "-ioctl (2020-02-27)" + DM_VERSION_MAJOR = 0x4 + DM_VERSION_MINOR = 0x2a + DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -530,6 +582,7 @@ const ( ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 + ETH_P_MRP = 0x88e3 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 ETH_P_NSH = 0x894f @@ -599,6 +652,8 @@ const ( FAN_DELETE_SELF = 0x400 FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_INFO_TYPE_DFID = 0x3 + FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_FID = 0x1 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 @@ -625,13 +680,17 @@ const ( FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_DFID_NAME = 0xc00 + FAN_REPORT_DIR_FID = 0x400 FAN_REPORT_FID = 0x200 + FAN_REPORT_NAME = 0x800 FAN_REPORT_TID = 0x100 FAN_UNLIMITED_MARKS = 0x20 FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 + FIDEDUPERANGE = 0xc0189436 FSCRYPT_KEY_DESCRIPTOR_SIZE = 0x8 FSCRYPT_KEY_DESC_PREFIX = "fscrypt:" FSCRYPT_KEY_DESC_PREFIX_SIZE = 0x8 @@ -655,8 +714,9 @@ const ( FSCRYPT_POLICY_FLAGS_PAD_4 = 0x0 FSCRYPT_POLICY_FLAGS_PAD_8 = 0x1 FSCRYPT_POLICY_FLAGS_PAD_MASK = 0x3 - FSCRYPT_POLICY_FLAGS_VALID = 0xf + FSCRYPT_POLICY_FLAGS_VALID = 0x1f FSCRYPT_POLICY_FLAG_DIRECT_KEY = 0x4 + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 = 0x10 FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 = 0x8 FSCRYPT_POLICY_V1 = 0x0 FSCRYPT_POLICY_V2 = 0x2 @@ -685,7 +745,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0xf + FS_POLICY_FLAGS_VALID = 0x1f FS_VERITY_FL = 0x100000 FS_VERITY_HASH_ALG_SHA256 = 0x1 FS_VERITY_HASH_ALG_SHA512 = 0x2 @@ -887,6 +947,7 @@ const ( IPPROTO_EGP = 0x8 IPPROTO_ENCAP = 0x62 IPPROTO_ESP = 0x32 + IPPROTO_ETHERNET = 0x8f IPPROTO_FRAGMENT = 0x2c IPPROTO_GRE = 0x2f IPPROTO_HOPOPTS = 0x0 @@ -900,6 +961,7 @@ const ( IPPROTO_L2TP = 0x73 IPPROTO_MH = 0x87 IPPROTO_MPLS = 0x89 + IPPROTO_MPTCP = 0x106 IPPROTO_MTP = 0x5c IPPROTO_NONE = 0x3b IPPROTO_PIM = 0x67 @@ -1069,6 +1131,7 @@ const ( KEYCTL_CAPS0_PERSISTENT_KEYRINGS = 0x2 KEYCTL_CAPS0_PUBLIC_KEY = 0x8 KEYCTL_CAPS0_RESTRICT_KEYRING = 0x40 + KEYCTL_CAPS1_NOTIFICATIONS = 0x4 KEYCTL_CAPS1_NS_KEYRING_NAME = 0x1 KEYCTL_CAPS1_NS_KEY_TAG = 0x2 KEYCTL_CHOWN = 0x4 @@ -1106,6 +1169,7 @@ const ( KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 + KEYCTL_WATCH_KEY = 0x20 KEY_REQKEY_DEFL_DEFAULT = 0x0 KEY_REQKEY_DEFL_GROUP_KEYRING = 0x6 KEY_REQKEY_DEFL_NO_CHANGE = -0x1 @@ -1149,8 +1213,16 @@ const ( LOOP_SET_FD = 0x4c00 LOOP_SET_STATUS = 0x4c02 LOOP_SET_STATUS64 = 0x4c04 + LOOP_SET_STATUS_CLEARABLE_FLAGS = 0x4 + LOOP_SET_STATUS_SETTABLE_FLAGS = 0xc LO_KEY_SIZE = 0x20 LO_NAME_SIZE = 0x40 + LWTUNNEL_IP6_MAX = 0x8 + LWTUNNEL_IP_MAX = 0x8 + LWTUNNEL_IP_OPTS_MAX = 0x3 + LWTUNNEL_IP_OPT_ERSPAN_MAX = 0x4 + LWTUNNEL_IP_OPT_GENEVE_MAX = 0x3 + LWTUNNEL_IP_OPT_VXLAN_MAX = 0x1 MADV_COLD = 0x14 MADV_DODUMP = 0x11 MADV_DOFORK = 0xb @@ -1446,6 +1518,92 @@ const ( PARITY_DEFAULT = 0x0 PARITY_NONE = 0x1 PARMRK = 0x8 + PERF_ATTR_SIZE_VER0 = 0x40 + PERF_ATTR_SIZE_VER1 = 0x48 + PERF_ATTR_SIZE_VER2 = 0x50 + PERF_ATTR_SIZE_VER3 = 0x60 + PERF_ATTR_SIZE_VER4 = 0x68 + PERF_ATTR_SIZE_VER5 = 0x70 + PERF_ATTR_SIZE_VER6 = 0x78 + PERF_AUX_FLAG_COLLISION = 0x8 + PERF_AUX_FLAG_OVERWRITE = 0x2 + PERF_AUX_FLAG_PARTIAL = 0x4 + PERF_AUX_FLAG_TRUNCATED = 0x1 + PERF_FLAG_FD_CLOEXEC = 0x8 + PERF_FLAG_FD_NO_GROUP = 0x1 + PERF_FLAG_FD_OUTPUT = 0x2 + PERF_FLAG_PID_CGROUP = 0x4 + PERF_MAX_CONTEXTS_PER_STACK = 0x8 + PERF_MAX_STACK_DEPTH = 0x7f + PERF_MEM_LOCK_LOCKED = 0x2 + PERF_MEM_LOCK_NA = 0x1 + PERF_MEM_LOCK_SHIFT = 0x18 + PERF_MEM_LVLNUM_ANY_CACHE = 0xb + PERF_MEM_LVLNUM_L1 = 0x1 + PERF_MEM_LVLNUM_L2 = 0x2 + PERF_MEM_LVLNUM_L3 = 0x3 + PERF_MEM_LVLNUM_L4 = 0x4 + PERF_MEM_LVLNUM_LFB = 0xc + PERF_MEM_LVLNUM_NA = 0xf + PERF_MEM_LVLNUM_PMEM = 0xe + PERF_MEM_LVLNUM_RAM = 0xd + PERF_MEM_LVLNUM_SHIFT = 0x21 + PERF_MEM_LVL_HIT = 0x2 + PERF_MEM_LVL_IO = 0x1000 + PERF_MEM_LVL_L1 = 0x8 + PERF_MEM_LVL_L2 = 0x20 + PERF_MEM_LVL_L3 = 0x40 + PERF_MEM_LVL_LFB = 0x10 + PERF_MEM_LVL_LOC_RAM = 0x80 + PERF_MEM_LVL_MISS = 0x4 + PERF_MEM_LVL_NA = 0x1 + PERF_MEM_LVL_REM_CCE1 = 0x400 + PERF_MEM_LVL_REM_CCE2 = 0x800 + PERF_MEM_LVL_REM_RAM1 = 0x100 + PERF_MEM_LVL_REM_RAM2 = 0x200 + PERF_MEM_LVL_SHIFT = 0x5 + PERF_MEM_LVL_UNC = 0x2000 + PERF_MEM_OP_EXEC = 0x10 + PERF_MEM_OP_LOAD = 0x2 + PERF_MEM_OP_NA = 0x1 + PERF_MEM_OP_PFETCH = 0x8 + PERF_MEM_OP_SHIFT = 0x0 + PERF_MEM_OP_STORE = 0x4 + PERF_MEM_REMOTE_REMOTE = 0x1 + PERF_MEM_REMOTE_SHIFT = 0x25 + PERF_MEM_SNOOPX_FWD = 0x1 + PERF_MEM_SNOOPX_SHIFT = 0x25 + PERF_MEM_SNOOP_HIT = 0x4 + PERF_MEM_SNOOP_HITM = 0x10 + PERF_MEM_SNOOP_MISS = 0x8 + PERF_MEM_SNOOP_NA = 0x1 + PERF_MEM_SNOOP_NONE = 0x2 + PERF_MEM_SNOOP_SHIFT = 0x13 + PERF_MEM_TLB_HIT = 0x2 + PERF_MEM_TLB_L1 = 0x8 + PERF_MEM_TLB_L2 = 0x10 + PERF_MEM_TLB_MISS = 0x4 + PERF_MEM_TLB_NA = 0x1 + PERF_MEM_TLB_OS = 0x40 + PERF_MEM_TLB_SHIFT = 0x1a + PERF_MEM_TLB_WK = 0x20 + PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER = 0x1 + PERF_RECORD_MISC_COMM_EXEC = 0x2000 + PERF_RECORD_MISC_CPUMODE_MASK = 0x7 + PERF_RECORD_MISC_CPUMODE_UNKNOWN = 0x0 + PERF_RECORD_MISC_EXACT_IP = 0x4000 + PERF_RECORD_MISC_EXT_RESERVED = 0x8000 + PERF_RECORD_MISC_FORK_EXEC = 0x2000 + PERF_RECORD_MISC_GUEST_KERNEL = 0x4 + PERF_RECORD_MISC_GUEST_USER = 0x5 + PERF_RECORD_MISC_HYPERVISOR = 0x3 + PERF_RECORD_MISC_KERNEL = 0x1 + PERF_RECORD_MISC_MMAP_DATA = 0x2000 + PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT = 0x1000 + PERF_RECORD_MISC_SWITCH_OUT = 0x2000 + PERF_RECORD_MISC_SWITCH_OUT_PREEMPT = 0x4000 + PERF_RECORD_MISC_USER = 0x2 + PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PIPEFS_MAGIC = 0x50495045 PPC_CMM_MAGIC = 0xc7571590 PPPIOCGNPMODE = 0xc008744c @@ -1832,6 +1990,7 @@ const ( RTPROT_EIGRP = 0xc0 RTPROT_GATED = 0x8 RTPROT_ISIS = 0xbb + RTPROT_KEEPALIVED = 0x12 RTPROT_KERNEL = 0x2 RTPROT_MROUTED = 0x11 RTPROT_MRT = 0xa @@ -1982,6 +2141,7 @@ const ( SOL_ATM = 0x108 SOL_CAIF = 0x116 SOL_CAN_BASE = 0x64 + SOL_CAN_RAW = 0x65 SOL_DCCP = 0x10d SOL_DECNET = 0x105 SOL_ICMPV6 = 0x3a @@ -2021,6 +2181,7 @@ const ( SO_EE_ORIGIN_TXSTATUS = 0x4 SO_EE_ORIGIN_TXTIME = 0x6 SO_EE_ORIGIN_ZEROCOPY = 0x5 + SO_EE_RFC4884_FLAG_INVALID = 0x1 SO_GET_FILTER = 0x1a SO_NO_CHECK = 0xb SO_PEERNAME = 0x1c @@ -2045,8 +2206,10 @@ const ( STATX_ATTR_APPEND = 0x20 STATX_ATTR_AUTOMOUNT = 0x1000 STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_DAX = 0x2000 STATX_ATTR_ENCRYPTED = 0x800 STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_MOUNT_ROOT = 0x2000 STATX_ATTR_NODUMP = 0x40 STATX_ATTR_VERITY = 0x100000 STATX_BASIC_STATS = 0x7ff @@ -2055,6 +2218,7 @@ const ( STATX_CTIME = 0x80 STATX_GID = 0x10 STATX_INO = 0x100 + STATX_MNT_ID = 0x1000 STATX_MODE = 0x2 STATX_MTIME = 0x40 STATX_NLINK = 0x4 @@ -2108,8 +2272,6 @@ const ( TCOFLUSH = 0x1 TCOOFF = 0x0 TCOON = 0x1 - TCP_BPF_IW = 0x3e9 - TCP_BPF_SNDCWND_CLAMP = 0x3ea TCP_CC_INFO = 0x1a TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd @@ -2293,6 +2455,23 @@ const ( WCONTINUED = 0x8 WDIOC_SETPRETIMEOUT = 0xc0045708 WDIOC_SETTIMEOUT = 0xc0045706 + WDIOF_ALARMONLY = 0x400 + WDIOF_CARDRESET = 0x20 + WDIOF_EXTERN1 = 0x4 + WDIOF_EXTERN2 = 0x8 + WDIOF_FANFAULT = 0x2 + WDIOF_KEEPALIVEPING = 0x8000 + WDIOF_MAGICCLOSE = 0x100 + WDIOF_OVERHEAT = 0x1 + WDIOF_POWEROVER = 0x40 + WDIOF_POWERUNDER = 0x10 + WDIOF_PRETIMEOUT = 0x200 + WDIOF_SETTIMEOUT = 0x80 + WDIOF_UNKNOWN = -0x1 + WDIOS_DISABLECARD = 0x1 + WDIOS_ENABLECARD = 0x2 + WDIOS_TEMPPANIC = 0x4 + WDIOS_UNKNOWN = -0x1 WEXITED = 0x4 WIN_ACKMEDIACHANGE = 0xdb WIN_CHECKPOWERMODE1 = 0xe5 @@ -2384,8 +2563,9 @@ const ( XDP_COPY = 0x2 XDP_FLAGS_DRV_MODE = 0x4 XDP_FLAGS_HW_MODE = 0x8 - XDP_FLAGS_MASK = 0xf + XDP_FLAGS_MASK = 0x1f XDP_FLAGS_MODES = 0xe + XDP_FLAGS_REPLACE = 0x10 XDP_FLAGS_SKB_MODE = 0x2 XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1 XDP_MMAP_OFFSETS = 0x1 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 5e974110d9..dd282c08b7 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -71,12 +71,16 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FP_XSTATE_MAGIC2 = 0x46505845 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80046601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40046602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0xc F_GETLK64 = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 47a57fe468..82fc93c7bb 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -71,12 +71,16 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FP_XSTATE_MAGIC2 = 0x46505845 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0x5 F_GETLK64 = 0x5 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index df2eea4bb7..fe7094f276 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80046601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40046602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0xc F_GETLK64 = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 4e1214217f..3b6cc58803 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -73,12 +73,16 @@ const ( EXTRA_MAGIC = 0x45585401 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FPSIMD_MAGIC = 0x46508001 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0x5 F_GETLK64 = 0x5 @@ -190,6 +194,7 @@ const ( PPPIOCSRASYNCMAP = 0x40047454 PPPIOCSXASYNCMAP = 0x4020744f PPPIOCXFERUNIT = 0x744e + PROT_BTI = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index a23b08029a..ce3d9ae156 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x2000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40046601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80046602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0x21 F_GETLK64 = 0x21 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index a5a921e43b..7a85215ce5 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x2000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0xe F_GETLK64 = 0xe diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index d088e197bd..07d4cc1bd5 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x2000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0xe F_GETLK64 = 0xe diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 0ddf9d5fe8..d4842ba1c2 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x2000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40046601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80046602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0x21 F_GETLK64 = 0x21 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index a93ffc1807..941e20dace 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000000 FF1 = 0x4000 FFDLY = 0x4000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x800000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0x5 F_GETLK64 = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index c1ea48b95f..63d3bc5662 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000000 FF1 = 0x4000 FFDLY = 0x4000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x800000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0x5 F_GETLK64 = 0xc diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 7def950ba5..490bee1ab1 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0x5 F_GETLK64 = 0x5 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index d39293c871..467b8218e8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -71,11 +71,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x40049409 + FICLONERANGE = 0x4020940d FLUSHO = 0x1000 FS_IOC_ENABLE_VERITY = 0x40806685 FS_IOC_GETFLAGS = 0x80086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x8010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 + FS_IOC_SETFLAGS = 0x40086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 F_GETLK = 0x5 F_GETLK64 = 0x5 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 3ff3ec681b..79fbafbcf6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -75,11 +75,15 @@ const ( EXTPROC = 0x10000 FF1 = 0x8000 FFDLY = 0x8000 + FICLONE = 0x80049409 + FICLONERANGE = 0x8020940d FLUSHO = 0x1000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 + FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 + FS_IOC_SETFLAGS = 0x80086602 FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 F_GETLK = 0x7 F_GETLK64 = 0x7 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go index 96b9b8ab30..20f3a5799f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go @@ -158,6 +158,12 @@ const ( CLONE_SIGHAND = 0x800 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go index ed522a84e8..90b8fcd29c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go @@ -158,6 +158,12 @@ const ( CLONE_SIGHAND = 0x800 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go index c8d36fe998..c5c03993b6 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go @@ -150,6 +150,12 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go index f1c146a74c..14dd3c1d1e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go @@ -158,6 +158,12 @@ const ( CLONE_SIGHAND = 0x800 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 + CPUSTATES = 0x5 + CP_IDLE = 0x4 + CP_INTR = 0x3 + CP_NICE = 0x1 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go index 5402bd55ce..c865a10df4 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go @@ -146,6 +146,13 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go index ffaf2d2f9f..9db6b2fb6e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go @@ -153,6 +153,13 @@ const ( CLOCK_REALTIME = 0x0 CLOCK_THREAD_CPUTIME_ID = 0x4 CLOCK_UPTIME = 0x5 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go index 7aa796a642..7072526a64 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go @@ -146,6 +146,13 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go index 1792d3f13e..ac5efbe5ac 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go @@ -156,6 +156,13 @@ const ( CLOCK_REALTIME = 0x0 CLOCK_THREAD_CPUTIME_ID = 0x4 CLOCK_UPTIME = 0x5 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 CREAD = 0x800 CRTSCTS = 0x10000 CS5 = 0x0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go new file mode 100644 index 0000000000..a74639a46f --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go @@ -0,0 +1,1862 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build mips64,openbsd + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_BLUETOOTH = 0x20 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_ENCAP = 0x1c + AF_HYLINK = 0xf + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x18 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_KEY = 0x1e + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x24 + AF_MPLS = 0x21 + AF_NATM = 0x1b + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x11 + AF_SIP = 0x1d + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + ALTWERASE = 0x200 + ARPHRD_ETHER = 0x1 + ARPHRD_FRELAY = 0xf + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDIRFILT = 0x4004427c + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc010427b + BIOCGETIF = 0x4020426b + BIOCGFILDROP = 0x40044278 + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044273 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCLOCK = 0x20004276 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDIRFILT = 0x8004427d + BIOCSDLT = 0x8004427a + BIOCSETF = 0x80104267 + BIOCSETIF = 0x8020426c + BIOCSETWF = 0x80104277 + BIOCSFILDROP = 0x80044279 + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044272 + BIOCSRTIMEOUT = 0x8010426d + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIRECTION_IN = 0x1 + BPF_DIRECTION_OUT = 0x2 + BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x200000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 + CPUSTATES = 0x6 + CP_IDLE = 0x5 + CP_INTR = 0x4 + CP_NICE = 0x1 + CP_SPIN = 0x3 + CP_SYS = 0x2 + CP_USER = 0x0 + CREAD = 0x800 + CRTSCTS = 0x10000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0xff + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DIOCADDQUEUE = 0xc110445d + DIOCADDRULE = 0xcd604404 + DIOCADDSTATE = 0xc1084425 + DIOCCHANGERULE = 0xcd60441a + DIOCCLRIFFLAG = 0xc028445a + DIOCCLRSRCNODES = 0x20004455 + DIOCCLRSTATES = 0xc0e04412 + DIOCCLRSTATUS = 0xc0284416 + DIOCGETLIMIT = 0xc0084427 + DIOCGETQSTATS = 0xc1204460 + DIOCGETQUEUE = 0xc110445f + DIOCGETQUEUES = 0xc110445e + DIOCGETRULE = 0xcd604407 + DIOCGETRULES = 0xcd604406 + DIOCGETRULESET = 0xc444443b + DIOCGETRULESETS = 0xc444443a + DIOCGETSRCNODES = 0xc0104454 + DIOCGETSTATE = 0xc1084413 + DIOCGETSTATES = 0xc0104419 + DIOCGETSTATUS = 0xc1e84415 + DIOCGETSYNFLWATS = 0xc0084463 + DIOCGETTIMEOUT = 0xc008441e + DIOCIGETIFACES = 0xc0284457 + DIOCKILLSRCNODES = 0xc080445b + DIOCKILLSTATES = 0xc0e04429 + DIOCNATLOOK = 0xc0504417 + DIOCOSFPADD = 0xc088444f + DIOCOSFPFLUSH = 0x2000444e + DIOCOSFPGET = 0xc0884450 + DIOCRADDADDRS = 0xc4504443 + DIOCRADDTABLES = 0xc450443d + DIOCRCLRADDRS = 0xc4504442 + DIOCRCLRASTATS = 0xc4504448 + DIOCRCLRTABLES = 0xc450443c + DIOCRCLRTSTATS = 0xc4504441 + DIOCRDELADDRS = 0xc4504444 + DIOCRDELTABLES = 0xc450443e + DIOCRGETADDRS = 0xc4504446 + DIOCRGETASTATS = 0xc4504447 + DIOCRGETTABLES = 0xc450443f + DIOCRGETTSTATS = 0xc4504440 + DIOCRINADEFINE = 0xc450444d + DIOCRSETADDRS = 0xc4504445 + DIOCRSETTFLAGS = 0xc450444a + DIOCRTSTADDRS = 0xc4504449 + DIOCSETDEBUG = 0xc0044418 + DIOCSETHOSTID = 0xc0044456 + DIOCSETIFFLAG = 0xc0284459 + DIOCSETLIMIT = 0xc0084428 + DIOCSETREASS = 0xc004445c + DIOCSETSTATUSIF = 0xc0284414 + DIOCSETSYNCOOKIES = 0xc0014462 + DIOCSETSYNFLWATS = 0xc0084461 + DIOCSETTIMEOUT = 0xc008441d + DIOCSTART = 0x20004401 + DIOCSTOP = 0x20004402 + DIOCXBEGIN = 0xc0104451 + DIOCXCOMMIT = 0xc0104452 + DIOCXROLLBACK = 0xc0104453 + DLT_ARCNET = 0x7 + DLT_ATM_RFC1483 = 0xb + DLT_AX25 = 0x3 + DLT_CHAOS = 0x5 + DLT_C_HDLC = 0x68 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0xd + DLT_FDDI = 0xa + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_LOOP = 0xc + DLT_MPLS = 0xdb + DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_SERIAL = 0x32 + DLT_PRONET = 0x4 + DLT_RAW = 0xe + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EMT_TAGOVF = 0x1 + EMUL_ENABLED = 0x1 + EMUL_NATIVE = 0x2 + ENDRUNDISC = 0x9 + ETHERMIN = 0x2e + ETHERMTU = 0x5dc + ETHERTYPE_8023 = 0x4 + ETHERTYPE_AARP = 0x80f3 + ETHERTYPE_ACCTON = 0x8390 + ETHERTYPE_AEONIC = 0x8036 + ETHERTYPE_ALPHA = 0x814a + ETHERTYPE_AMBER = 0x6008 + ETHERTYPE_AMOEBA = 0x8145 + ETHERTYPE_AOE = 0x88a2 + ETHERTYPE_APOLLO = 0x80f7 + ETHERTYPE_APOLLODOMAIN = 0x8019 + ETHERTYPE_APPLETALK = 0x809b + ETHERTYPE_APPLITEK = 0x80c7 + ETHERTYPE_ARGONAUT = 0x803a + ETHERTYPE_ARP = 0x806 + ETHERTYPE_AT = 0x809b + ETHERTYPE_ATALK = 0x809b + ETHERTYPE_ATOMIC = 0x86df + ETHERTYPE_ATT = 0x8069 + ETHERTYPE_ATTSTANFORD = 0x8008 + ETHERTYPE_AUTOPHON = 0x806a + ETHERTYPE_AXIS = 0x8856 + ETHERTYPE_BCLOOP = 0x9003 + ETHERTYPE_BOFL = 0x8102 + ETHERTYPE_CABLETRON = 0x7034 + ETHERTYPE_CHAOS = 0x804 + ETHERTYPE_COMDESIGN = 0x806c + ETHERTYPE_COMPUGRAPHIC = 0x806d + ETHERTYPE_COUNTERPOINT = 0x8062 + ETHERTYPE_CRONUS = 0x8004 + ETHERTYPE_CRONUSVLN = 0x8003 + ETHERTYPE_DCA = 0x1234 + ETHERTYPE_DDE = 0x807b + ETHERTYPE_DEBNI = 0xaaaa + ETHERTYPE_DECAM = 0x8048 + ETHERTYPE_DECCUST = 0x6006 + ETHERTYPE_DECDIAG = 0x6005 + ETHERTYPE_DECDNS = 0x803c + ETHERTYPE_DECDTS = 0x803e + ETHERTYPE_DECEXPER = 0x6000 + ETHERTYPE_DECLAST = 0x8041 + ETHERTYPE_DECLTM = 0x803f + ETHERTYPE_DECMUMPS = 0x6009 + ETHERTYPE_DECNETBIOS = 0x8040 + ETHERTYPE_DELTACON = 0x86de + ETHERTYPE_DIDDLE = 0x4321 + ETHERTYPE_DLOG1 = 0x660 + ETHERTYPE_DLOG2 = 0x661 + ETHERTYPE_DN = 0x6003 + ETHERTYPE_DOGFIGHT = 0x1989 + ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_ECMA = 0x803 + ETHERTYPE_ENCRYPT = 0x803d + ETHERTYPE_ES = 0x805d + ETHERTYPE_EXCELAN = 0x8010 + ETHERTYPE_EXPERDATA = 0x8049 + ETHERTYPE_FLIP = 0x8146 + ETHERTYPE_FLOWCONTROL = 0x8808 + ETHERTYPE_FRARP = 0x808 + ETHERTYPE_GENDYN = 0x8068 + ETHERTYPE_HAYES = 0x8130 + ETHERTYPE_HIPPI_FP = 0x8180 + ETHERTYPE_HITACHI = 0x8820 + ETHERTYPE_HP = 0x8005 + ETHERTYPE_IEEEPUP = 0xa00 + ETHERTYPE_IEEEPUPAT = 0xa01 + ETHERTYPE_IMLBL = 0x4c42 + ETHERTYPE_IMLBLDIAG = 0x424c + ETHERTYPE_IP = 0x800 + ETHERTYPE_IPAS = 0x876c + ETHERTYPE_IPV6 = 0x86dd + ETHERTYPE_IPX = 0x8137 + ETHERTYPE_IPXNEW = 0x8037 + ETHERTYPE_KALPANA = 0x8582 + ETHERTYPE_LANBRIDGE = 0x8038 + ETHERTYPE_LANPROBE = 0x8888 + ETHERTYPE_LAT = 0x6004 + ETHERTYPE_LBACK = 0x9000 + ETHERTYPE_LITTLE = 0x8060 + ETHERTYPE_LLDP = 0x88cc + ETHERTYPE_LOGICRAFT = 0x8148 + ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MACSEC = 0x88e5 + ETHERTYPE_MATRA = 0x807a + ETHERTYPE_MAX = 0xffff + ETHERTYPE_MERIT = 0x807c + ETHERTYPE_MICP = 0x873a + ETHERTYPE_MOPDL = 0x6001 + ETHERTYPE_MOPRC = 0x6002 + ETHERTYPE_MOTOROLA = 0x818d + ETHERTYPE_MPLS = 0x8847 + ETHERTYPE_MPLS_MCAST = 0x8848 + ETHERTYPE_MUMPS = 0x813f + ETHERTYPE_NBPCC = 0x3c04 + ETHERTYPE_NBPCLAIM = 0x3c09 + ETHERTYPE_NBPCLREQ = 0x3c05 + ETHERTYPE_NBPCLRSP = 0x3c06 + ETHERTYPE_NBPCREQ = 0x3c02 + ETHERTYPE_NBPCRSP = 0x3c03 + ETHERTYPE_NBPDG = 0x3c07 + ETHERTYPE_NBPDGB = 0x3c08 + ETHERTYPE_NBPDLTE = 0x3c0a + ETHERTYPE_NBPRAR = 0x3c0c + ETHERTYPE_NBPRAS = 0x3c0b + ETHERTYPE_NBPRST = 0x3c0d + ETHERTYPE_NBPSCD = 0x3c01 + ETHERTYPE_NBPVCD = 0x3c00 + ETHERTYPE_NBS = 0x802 + ETHERTYPE_NCD = 0x8149 + ETHERTYPE_NESTAR = 0x8006 + ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NOVELL = 0x8138 + ETHERTYPE_NS = 0x600 + ETHERTYPE_NSAT = 0x601 + ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NTRAILER = 0x10 + ETHERTYPE_OS9 = 0x7007 + ETHERTYPE_OS9NET = 0x7009 + ETHERTYPE_PACER = 0x80c6 + ETHERTYPE_PAE = 0x888e + ETHERTYPE_PBB = 0x88e7 + ETHERTYPE_PCS = 0x4242 + ETHERTYPE_PLANNING = 0x8044 + ETHERTYPE_PPP = 0x880b + ETHERTYPE_PPPOE = 0x8864 + ETHERTYPE_PPPOEDISC = 0x8863 + ETHERTYPE_PRIMENTS = 0x7031 + ETHERTYPE_PUP = 0x200 + ETHERTYPE_PUPAT = 0x200 + ETHERTYPE_QINQ = 0x88a8 + ETHERTYPE_RACAL = 0x7030 + ETHERTYPE_RATIONAL = 0x8150 + ETHERTYPE_RAWFR = 0x6559 + ETHERTYPE_RCL = 0x1995 + ETHERTYPE_RDP = 0x8739 + ETHERTYPE_RETIX = 0x80f2 + ETHERTYPE_REVARP = 0x8035 + ETHERTYPE_SCA = 0x6007 + ETHERTYPE_SECTRA = 0x86db + ETHERTYPE_SECUREDATA = 0x876d + ETHERTYPE_SGITW = 0x817e + ETHERTYPE_SG_BOUNCE = 0x8016 + ETHERTYPE_SG_DIAG = 0x8013 + ETHERTYPE_SG_NETGAMES = 0x8014 + ETHERTYPE_SG_RESV = 0x8015 + ETHERTYPE_SIMNET = 0x5208 + ETHERTYPE_SLOW = 0x8809 + ETHERTYPE_SNA = 0x80d5 + ETHERTYPE_SNMP = 0x814c + ETHERTYPE_SONIX = 0xfaf5 + ETHERTYPE_SPIDER = 0x809f + ETHERTYPE_SPRITE = 0x500 + ETHERTYPE_STP = 0x8181 + ETHERTYPE_TALARIS = 0x812b + ETHERTYPE_TALARISMC = 0x852b + ETHERTYPE_TCPCOMP = 0x876b + ETHERTYPE_TCPSM = 0x9002 + ETHERTYPE_TEC = 0x814f + ETHERTYPE_TIGAN = 0x802f + ETHERTYPE_TRAIL = 0x1000 + ETHERTYPE_TRANSETHER = 0x6558 + ETHERTYPE_TYMSHARE = 0x802e + ETHERTYPE_UBBST = 0x7005 + ETHERTYPE_UBDEBUG = 0x900 + ETHERTYPE_UBDIAGLOOP = 0x7002 + ETHERTYPE_UBDL = 0x7000 + ETHERTYPE_UBNIU = 0x7001 + ETHERTYPE_UBNMC = 0x7003 + ETHERTYPE_VALID = 0x1600 + ETHERTYPE_VARIAN = 0x80dd + ETHERTYPE_VAXELN = 0x803b + ETHERTYPE_VEECO = 0x8067 + ETHERTYPE_VEXP = 0x805b + ETHERTYPE_VGLAB = 0x8131 + ETHERTYPE_VINES = 0xbad + ETHERTYPE_VINESECHO = 0xbaf + ETHERTYPE_VINESLOOP = 0xbae + ETHERTYPE_VITAL = 0xff00 + ETHERTYPE_VLAN = 0x8100 + ETHERTYPE_VLTLMAN = 0x8080 + ETHERTYPE_VPROD = 0x805c + ETHERTYPE_VURESERVED = 0x8147 + ETHERTYPE_WATERLOO = 0x8130 + ETHERTYPE_WELLFLEET = 0x8103 + ETHERTYPE_X25 = 0x805 + ETHERTYPE_X75 = 0x801 + ETHERTYPE_XNSSM = 0x9001 + ETHERTYPE_XTP = 0x817d + ETHER_ADDR_LEN = 0x6 + ETHER_ALIGN = 0x2 + ETHER_CRC_LEN = 0x4 + ETHER_CRC_POLY_BE = 0x4c11db6 + ETHER_CRC_POLY_LE = 0xedb88320 + ETHER_HDR_LEN = 0xe + ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b + ETHER_MAX_LEN = 0x5ee + ETHER_MIN_LEN = 0x40 + ETHER_TYPE_LEN = 0x2 + ETHER_VLAN_ENCAP_LEN = 0x4 + EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x8 + EVFILT_TIMER = -0x7 + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf000 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FLUSHO = 0x800000 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0xa + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETOWN = 0x5 + F_ISATTY = 0xb + F_OK = 0x0 + F_RDLCK = 0x1 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x8e52 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_A12MPPSWITCH = 0x82 + IFT_AAL2 = 0xbb + IFT_AAL5 = 0x31 + IFT_ADSL = 0x5e + IFT_AFLANE8023 = 0x3b + IFT_AFLANE8025 = 0x3c + IFT_ARAP = 0x58 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ASYNC = 0x54 + IFT_ATM = 0x25 + IFT_ATMDXI = 0x69 + IFT_ATMFUNI = 0x6a + IFT_ATMIMA = 0x6b + IFT_ATMLOGICAL = 0x50 + IFT_ATMRADIO = 0xbd + IFT_ATMSUBINTERFACE = 0x86 + IFT_ATMVCIENDPT = 0xc2 + IFT_ATMVIRTUAL = 0x95 + IFT_BGPPOLICYACCOUNTING = 0xa2 + IFT_BLUETOOTH = 0xf8 + IFT_BRIDGE = 0xd1 + IFT_BSC = 0x53 + IFT_CARP = 0xf7 + IFT_CCTEMUL = 0x3d + IFT_CEPT = 0x13 + IFT_CES = 0x85 + IFT_CHANNEL = 0x46 + IFT_CNR = 0x55 + IFT_COFFEE = 0x84 + IFT_COMPOSITELINK = 0x9b + IFT_DCN = 0x8d + IFT_DIGITALPOWERLINE = 0x8a + IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba + IFT_DLSW = 0x4a + IFT_DOCSCABLEDOWNSTREAM = 0x80 + IFT_DOCSCABLEMACLAYER = 0x7f + IFT_DOCSCABLEUPSTREAM = 0x81 + IFT_DOCSCABLEUPSTREAMCHANNEL = 0xcd + IFT_DS0 = 0x51 + IFT_DS0BUNDLE = 0x52 + IFT_DS1FDL = 0xaa + IFT_DS3 = 0x1e + IFT_DTM = 0x8c + IFT_DUMMY = 0xf1 + IFT_DVBASILN = 0xac + IFT_DVBASIOUT = 0xad + IFT_DVBRCCDOWNSTREAM = 0x93 + IFT_DVBRCCMACLAYER = 0x92 + IFT_DVBRCCUPSTREAM = 0x94 + IFT_ECONET = 0xce + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_EPLRS = 0x57 + IFT_ESCON = 0x49 + IFT_ETHER = 0x6 + IFT_FAITH = 0xf3 + IFT_FAST = 0x7d + IFT_FASTETHER = 0x3e + IFT_FASTETHERFX = 0x45 + IFT_FDDI = 0xf + IFT_FIBRECHANNEL = 0x38 + IFT_FRAMERELAYINTERCONNECT = 0x3a + IFT_FRAMERELAYMPI = 0x5c + IFT_FRDLCIENDPT = 0xc1 + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_FRF16MFRBUNDLE = 0xa3 + IFT_FRFORWARD = 0x9e + IFT_G703AT2MB = 0x43 + IFT_G703AT64K = 0x42 + IFT_GIF = 0xf0 + IFT_GIGABITETHERNET = 0x75 + IFT_GR303IDT = 0xb2 + IFT_GR303RDT = 0xb1 + IFT_H323GATEKEEPER = 0xa4 + IFT_H323PROXY = 0xa5 + IFT_HDH1822 = 0x3 + IFT_HDLC = 0x76 + IFT_HDSL2 = 0xa8 + IFT_HIPERLAN2 = 0xb7 + IFT_HIPPI = 0x2f + IFT_HIPPIINTERFACE = 0x39 + IFT_HOSTPAD = 0x5a + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IBM370PARCHAN = 0x48 + IFT_IDSL = 0x9a + IFT_IEEE1394 = 0x90 + IFT_IEEE80211 = 0x47 + IFT_IEEE80212 = 0x37 + IFT_IEEE8023ADLAG = 0xa1 + IFT_IFGSN = 0x91 + IFT_IMT = 0xbe + IFT_INFINIBAND = 0xc7 + IFT_INTERLEAVE = 0x7c + IFT_IP = 0x7e + IFT_IPFORWARD = 0x8e + IFT_IPOVERATM = 0x72 + IFT_IPOVERCDLC = 0x6d + IFT_IPOVERCLAW = 0x6e + IFT_IPSWITCH = 0x4e + IFT_ISDN = 0x3f + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISDNS = 0x4b + IFT_ISDNU = 0x4c + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88025CRFPINT = 0x62 + IFT_ISO88025DTR = 0x56 + IFT_ISO88025FIBER = 0x73 + IFT_ISO88026 = 0xa + IFT_ISUP = 0xb3 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_L3IPXVLAN = 0x89 + IFT_LAPB = 0x10 + IFT_LAPD = 0x4d + IFT_LAPF = 0x77 + IFT_LINEGROUP = 0xd2 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MBIM = 0xfa + IFT_MEDIAMAILOVERIP = 0x8b + IFT_MFSIGLINK = 0xa7 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_MPC = 0x71 + IFT_MPLS = 0xa6 + IFT_MPLSTUNNEL = 0x96 + IFT_MSDSL = 0x8f + IFT_MVL = 0xbf + IFT_MYRINET = 0x63 + IFT_NFAS = 0xaf + IFT_NSIP = 0x1b + IFT_OPTICALCHANNEL = 0xc3 + IFT_OPTICALTRANSPORT = 0xc4 + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PFLOG = 0xf5 + IFT_PFLOW = 0xf9 + IFT_PFSYNC = 0xf6 + IFT_PLC = 0xae + IFT_PON155 = 0xcf + IFT_PON622 = 0xd0 + IFT_POS = 0xab + IFT_PPP = 0x17 + IFT_PPPMULTILINKBUNDLE = 0x6c + IFT_PROPATM = 0xc5 + IFT_PROPBWAP2MP = 0xb8 + IFT_PROPCNLS = 0x59 + IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 + IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 + IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PROPWIRELESSP2P = 0x9d + IFT_PTPSERIAL = 0x16 + IFT_PVC = 0xf2 + IFT_Q2931 = 0xc9 + IFT_QLLC = 0x44 + IFT_RADIOMAC = 0xbc + IFT_RADSL = 0x5f + IFT_REACHDSL = 0xc0 + IFT_RFC1483 = 0x9f + IFT_RS232 = 0x21 + IFT_RSRB = 0x4f + IFT_SDLC = 0x11 + IFT_SDSL = 0x60 + IFT_SHDSL = 0xa9 + IFT_SIP = 0x1f + IFT_SIPSIG = 0xcc + IFT_SIPTG = 0xcb + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETOVERHEADCHANNEL = 0xb9 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SRP = 0x97 + IFT_SS7SIGLINK = 0x9c + IFT_STACKTOSTACK = 0x6f + IFT_STARLAN = 0xb + IFT_T1 = 0x12 + IFT_TDLC = 0x74 + IFT_TELINK = 0xc8 + IFT_TERMPAD = 0x5b + IFT_TR008 = 0xb0 + IFT_TRANSPHDLC = 0x7b + IFT_TUNNEL = 0x83 + IFT_ULTRA = 0x1d + IFT_USB = 0xa0 + IFT_V11 = 0x40 + IFT_V35 = 0x2d + IFT_V36 = 0x41 + IFT_V37 = 0x78 + IFT_VDSL = 0x61 + IFT_VIRTUALIPADDRESS = 0x70 + IFT_VIRTUALTG = 0xca + IFT_VOICEDID = 0xd5 + IFT_VOICEEM = 0x64 + IFT_VOICEEMFGD = 0xd3 + IFT_VOICEENCAP = 0x67 + IFT_VOICEFGDEANA = 0xd4 + IFT_VOICEFXO = 0x65 + IFT_VOICEFXS = 0x66 + IFT_VOICEOVERATM = 0x98 + IFT_VOICEOVERCABLE = 0xc6 + IFT_VOICEOVERFRAMERELAY = 0x99 + IFT_VOICEOVERIP = 0x68 + IFT_X213 = 0x5d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25HUNTGROUP = 0x7a + IFT_X25MLP = 0x79 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IN_RFC3021_HOST = 0x1 + IN_RFC3021_NET = 0xfffffffe + IN_RFC3021_NSHIFT = 0x1f + IPPROTO_AH = 0x33 + IPPROTO_CARP = 0x70 + IPPROTO_DIVERT = 0x102 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPIP = 0x4 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x103 + IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 + IPPROTO_NONE = 0x3b + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 + IPV6_AUTH_LEVEL = 0x35 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_ESP_NETWORK_LEVEL = 0x37 + IPV6_ESP_TRANS_LEVEL = 0x36 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff + IPV6_FRAGTTL = 0x78 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPCOMP_LEVEL = 0x3c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 + IPV6_MMTU = 0x500 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_OPTIONS = 0x1 + IPV6_PATHMTU = 0x2c + IPV6_PIPEX = 0x3f + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVDSTPORT = 0x40 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RTABLE = 0x1021 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_AUTH_LEVEL = 0x14 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0xd + IP_ESP_NETWORK_LEVEL = 0x16 + IP_ESP_TRANS_LEVEL = 0x15 + IP_HDRINCL = 0x2 + IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 + IP_IPSECFLOWINFO = 0x24 + IP_IPSEC_LOCAL_AUTH = 0x1b + IP_IPSEC_LOCAL_CRED = 0x19 + IP_IPSEC_LOCAL_ID = 0x17 + IP_IPSEC_REMOTE_AUTH = 0x1c + IP_IPSEC_REMOTE_CRED = 0x1a + IP_IPSEC_REMOTE_ID = 0x18 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0xfff + IP_MF = 0x2000 + IP_MINTTL = 0x20 + IP_MIN_MEMBERSHIPS = 0xf + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x1 + IP_PIPEX = 0x22 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVDSTPORT = 0x21 + IP_RECVIF = 0x1e + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVRTABLE = 0x23 + IP_RECVTTL = 0x1f + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 + IP_TOS = 0x3 + IP_TTL = 0x4 + ISIG = 0x80 + ISTRIP = 0x20 + IUCLC = 0x1000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LCNT_OVERLOAD_FLUSH = 0x6 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x6 + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_SPACEAVAIL = 0x5 + MADV_WILLNEED = 0x3 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_CONCEAL = 0x8000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FLAGMASK = 0xfff7 + MAP_HASSEMAPHORE = 0x0 + MAP_INHERIT = 0x0 + MAP_INHERIT_COPY = 0x1 + MAP_INHERIT_NONE = 0x2 + MAP_INHERIT_SHARE = 0x0 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x0 + MAP_SHARED = 0x1 + MAP_STACK = 0x4000 + MAP_TRYFIXED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_DOOMED = 0x8000000 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_NOATIME = 0x8000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 + MNT_NOSUID = 0x8 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 + MNT_SYNCHRONOUS = 0x2 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0x400ffff + MNT_WAIT = 0x1 + MNT_WANTRDWR = 0x2000000 + MNT_WXALLOWED = 0x800 + MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOR = 0x8 + MSG_MCAST = 0x200 + MSG_NOSIGNAL = 0x400 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x4 + MS_SYNC = 0x2 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x3 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x7 + NET_RT_STATS = 0x4 + NET_RT_TABLE = 0x5 + NFDBITS = 0x20 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 + NOTE_CHILD = 0x4 + NOTE_DELETE = 0x1 + NOTE_EOF = 0x2 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRUNCATE = 0x80 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OLCUC = 0x20 + ONLCR = 0x2 + ONLRET = 0x80 + ONOCR = 0x40 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x10000 + O_CREAT = 0x200 + O_DIRECTORY = 0x20000 + O_DSYNC = 0x80 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x80 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PF_FLUSH = 0x1 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb + RTAX_BRD = 0x7 + RTAX_DNS = 0xc + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_LABEL = 0xa + RTAX_MAX = 0xf + RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe + RTAX_SRC = 0x8 + RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd + RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 + RTA_BRD = 0x80 + RTA_DNS = 0x1000 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_LABEL = 0x400 + RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 + RTA_SRC = 0x100 + RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 + RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 + RTF_CLONED = 0x10000 + RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_FMASK = 0x110fc08 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MPATH = 0x40000 + RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 + RTF_PERMANENT_ARP = 0x2000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x2000 + RTF_REJECT = 0x8 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_USETRAILERS = 0x8000 + RTM_80211INFO = 0x15 + RTM_ADD = 0x1 + RTM_BFD = 0x12 + RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DESYNC = 0x10 + RTM_GET = 0x4 + RTM_IFANNOUNCE = 0xf + RTM_IFINFO = 0xe + RTM_INVALIDATE = 0x11 + RTM_LOSING = 0x5 + RTM_MAXSIZE = 0x800 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff + RT_TABLEID_MAX = 0xff + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x4 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 + SIOCATMARK = 0x40047307 + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d + SIOCBRDGDADDR = 0x81286947 + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e + SIOCBRDGGCACHE = 0xc0186941 + SIOCBRDGGFD = 0xc0186952 + SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGIFFLGS = 0xc060693e + SIOCBRDGGMA = 0xc0186953 + SIOCBRDGGPARAM = 0xc0406958 + SIOCBRDGGPRI = 0xc0186950 + SIOCBRDGGRL = 0xc030694f + SIOCBRDGGTO = 0xc0186946 + SIOCBRDGIFS = 0xc0606942 + SIOCBRDGRTS = 0xc0206943 + SIOCBRDGSADDR = 0xc1286944 + SIOCBRDGSCACHE = 0x80186940 + SIOCBRDGSFD = 0x80186952 + SIOCBRDGSHT = 0x80186951 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a + SIOCBRDGSMA = 0x80186953 + SIOCBRDGSPRI = 0x80186950 + SIOCBRDGSPROTO = 0x8018695a + SIOCBRDGSTO = 0x80186945 + SIOCBRDGSTXHC = 0x80186959 + SIOCDELLABEL = 0x80206997 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 + SIOCDIFPARENT = 0x802069b4 + SIOCDIFPHYADDR = 0x80206949 + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af + SIOCGETKALIVE = 0xc01869a4 + SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae + SIOCGETPFLOW = 0xc02069fe + SIOCGETPFSYNC = 0xc02069f8 + SIOCGETSGCNT = 0xc0207534 + SIOCGETVIFCNT = 0xc0287533 + SIOCGETVLAN = 0xc0206990 + SIOCGIFADDR = 0xc0206921 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCONF = 0xc0106924 + SIOCGIFDATA = 0xc020691b + SIOCGIFDESCR = 0xc0206981 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFGATTR = 0xc028698b + SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc028698d + SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 + SIOCGIFHARDMTU = 0xc02069a5 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0406938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc020697e + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 + SIOCGIFPRIORITY = 0xc020699c + SIOCGIFRDOMAIN = 0xc02069a0 + SIOCGIFRTLABEL = 0xc0206983 + SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 + SIOCGIFXFLAGS = 0xc020699e + SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 + SIOCGLIFPHYRTABLE = 0xc02069a2 + SIOCGLIFPHYTTL = 0xc02069a9 + SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGRXHPRIO = 0xc02069db + SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 + SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 + SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac + SIOCIFCREATE = 0x8020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106978 + SIOCSETKALIVE = 0x801869a3 + SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad + SIOCSETPFLOW = 0x802069fd + SIOCSETPFSYNC = 0x802069f7 + SIOCSETVLAN = 0x8020698f + SIOCSIFADDR = 0x8020690c + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFDESCR = 0x80206980 + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGATTR = 0x8028698c + SIOCSIFGENERIC = 0x80206939 + SIOCSIFLLADDR = 0x8020691f + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x8020697f + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 + SIOCSIFPRIORITY = 0x8020699b + SIOCSIFRDOMAIN = 0x8020699f + SIOCSIFRTLABEL = 0x80206982 + SIOCSIFXFLAGS = 0x8020699d + SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 + SIOCSLIFPHYRTABLE = 0x802069a1 + SIOCSLIFPHYTTL = 0x802069a8 + SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSRXHPRIO = 0x802069db + SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf + SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 + SIOCSVNETID = 0x802069a6 + SIOCSWGDPID = 0xc018695b + SIOCSWGMAXFLOW = 0xc0186960 + SIOCSWGMAXGROUP = 0xc018695d + SIOCSWSDPID = 0x8018695c + SIOCSWSPORTNO = 0xc060695f + SOCK_CLOEXEC = 0x8000 + SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BINDANY = 0x1000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DOMAIN = 0x1024 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LINGER = 0x80 + SO_NETPROC = 0x1020 + SO_OOBINLINE = 0x100 + SO_PEERCRED = 0x1022 + SO_PROTOCOL = 0x1025 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_RTABLE = 0x1021 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_SPLICE = 0x1023 + SO_TIMESTAMP = 0x800 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCP_MAXBURST = 0x4 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x3 + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x4 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOPUSH = 0x10 + TCP_SACKHOLE_LIMIT = 0x80 + TCP_SACK_ENABLE = 0x8 + TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d + TIOCCONS = 0x80047462 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLAG_CLOCAL = 0x2 + TIOCFLAG_CRTSCTS = 0x4 + TIOCFLAG_MDMBUF = 0x8 + TIOCFLAG_PPS = 0x10 + TIOCFLAG_SOFTCAR = 0x1 + TIOCFLUSH = 0x80047410 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGFLAGS = 0x4004745d + TIOCGPGRP = 0x40047477 + TIOCGSID = 0x40047463 + TIOCGTSTAMP = 0x4010745b + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGET = 0x4004746a + TIOCMODG = 0x4004746a + TIOCMODS = 0x8004746d + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c + TIOCSFLAGS = 0x8004745c + TIOCSIG = 0x8004745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTOP = 0x2000746f + TIOCSTSTAMP = 0x8008745a + TIOCSWINSZ = 0x80087467 + TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b + TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WALTSIG = 0x4 + WCONTINUED = 0x8 + WCOREFLAG = 0x80 + WNOHANG = 0x1 + WUNTRACED = 0x2 + XCASE = 0x1000000 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x58) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x59) + EILSEQ = syscall.Errno(0x54) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EIPSEC = syscall.Errno(0x52) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x5f) + ELOOP = syscall.Errno(0x3e) + EMEDIUMTYPE = syscall.Errno(0x56) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x53) + ENOBUFS = syscall.Errno(0x37) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOMEDIUM = syscall.Errno(0x55) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x5a) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x5b) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTHR = syscall.Signal(0x20) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go index 46e054ccb0..5312c36cc8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go @@ -192,6 +192,12 @@ const ( CSTOPB = 0x40 CSUSP = 0x1a CSWTCH = 0x1a + DIOC = 0x6400 + DIOCGETB = 0x6402 + DIOCGETC = 0x6401 + DIOCGETP = 0x6408 + DIOCSETE = 0x6403 + DIOCSETP = 0x6409 DLT_AIRONET_HEADER = 0x78 DLT_APPLE_IP_OVER_IEEE1394 = 0x8a DLT_ARCNET = 0x7 @@ -290,6 +296,7 @@ const ( FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 + FIORDCHK = 0x6603 FLUSHALL = 0x1 FLUSHDATA = 0x0 FLUSHO = 0x2000 @@ -645,6 +652,14 @@ const ( MAP_SHARED = 0x1 MAP_TEXT = 0x400 MAP_TYPE = 0xf + MCAST_BLOCK_SOURCE = 0x2b + MCAST_EXCLUDE = 0x2 + MCAST_INCLUDE = 0x1 + MCAST_JOIN_GROUP = 0x29 + MCAST_JOIN_SOURCE_GROUP = 0x2d + MCAST_LEAVE_GROUP = 0x2a + MCAST_LEAVE_SOURCE_GROUP = 0x2e + MCAST_UNBLOCK_SOURCE = 0x2c MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 MSG_CTRUNC = 0x10 @@ -653,6 +668,7 @@ const ( MSG_DUPCTRL = 0x800 MSG_EOR = 0x8 MSG_MAXIOVLEN = 0x10 + MSG_NOSIGNAL = 0x200 MSG_NOTIFICATION = 0x100 MSG_OOB = 0x1 MSG_PEEK = 0x2 @@ -687,6 +703,7 @@ const ( O_APPEND = 0x8 O_CLOEXEC = 0x800000 O_CREAT = 0x100 + O_DIRECTORY = 0x1000000 O_DSYNC = 0x40 O_EXCL = 0x400 O_EXEC = 0x400000 @@ -725,7 +742,7 @@ const ( RLIMIT_FSIZE = 0x1 RLIMIT_NOFILE = 0x5 RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x3 + RLIM_INFINITY = 0xfffffffffffffffd RTAX_AUTHOR = 0x6 RTAX_BRD = 0x7 RTAX_DST = 0x0 @@ -1047,6 +1064,7 @@ const ( TCOON = 0x1 TCP_ABORT_THRESHOLD = 0x11 TCP_ANONPRIVBIND = 0x20 + TCP_CONGESTION = 0x25 TCP_CONN_ABORT_THRESHOLD = 0x13 TCP_CONN_NOTIFY_THRESHOLD = 0x12 TCP_CORK = 0x18 @@ -1076,6 +1094,8 @@ const ( TCSETSF = 0x5410 TCSETSW = 0x540f TCXONC = 0x5406 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 TIOC = 0x5400 TIOCCBRK = 0x747a TIOCCDTR = 0x7478 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go index 4b3a8ad7be..0550da06d1 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go @@ -2,7 +2,7 @@ // Code generated by the command above; see README.md. DO NOT EDIT. // +build aix,ppc64 -// +build !gccgo +// +build gc package unix diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go deleted file mode 100644 index c1cc0a415f..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go +++ /dev/null @@ -1,1811 +0,0 @@ -// go run mksyscall.go -l32 -tags darwin,386,!go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_386.1_11.go syscall_darwin_386.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build darwin,386,!go1.12 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getgroups(ngid int, gid *_Gid_t) (n int, err error) { - r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setgroups(ngid int, gid *_Gid_t) (err error) { - _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { - r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) - wpid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { - r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socket(domain int, typ int, proto int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { - _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { - _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Shutdown(s int, how int) (err error) { - _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { - _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { - r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func utimes(path string, timeval *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func futimes(fd int, timeval *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { - r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Madvise(b []byte, behav int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Msync(b []byte, flags int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func pipe() (r int, w int, err error) { - r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) - r = int(r0) - w = int(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func removexattr(path string, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fremovexattr(fd int, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { - r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_SETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fcntl(fd int, cmd int, arg int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kill(pid int, signum int, posix int) (err error) { - _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func ioctl(fd int, req uint, arg uintptr) (err error) { - _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { - var _p0 unsafe.Pointer - if len(mib) > 0 { - _p0 = unsafe.Pointer(&mib[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { - _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(offset>>32), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Access(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { - _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chflags(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chmod(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chroot(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Close(fd int) (err error) { - _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup(fd int) (nfd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) - nfd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup2(from int, to int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exchangedata(path1 string, path2 string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path1) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(path2) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) { - Syscall(SYS_EXIT, uintptr(code), 0, 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchdir(fd int) (err error) { - _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchflags(fd int, flags int) (err error) { - _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmod(fd int, mode uint32) (err error) { - _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchown(fd int, uid int, gid int) (err error) { - _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Flock(fd int, how int) (err error) { - _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fpathconf(fd int, name int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fsync(fd int) (err error) { - _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Ftruncate(fd int, length int64) (err error) { - _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getdtablesize() (size int) { - r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0) - size = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) - egid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Geteuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) - gid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) - pgid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgrp() (pgrp int) { - r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) - pgrp = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) - pid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) - ppid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpriority(which int, who int) (prio int, err error) { - r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) - prio = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrusage(who int, rusage *Rusage) (err error) { - _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getsid(pid int) (sid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) - sid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Issetugid() (tainted bool) { - r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0) - tainted = bool(r0 != 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Kqueue() (fd int, err error) { - r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lchown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Link(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Listen(s int, backlog int) (err error) { - _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdir(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdirat(dirfd int, path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkfifo(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mknod(path string, mode uint32, dev int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Open(path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pathconf(path string, name int) (val int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pread(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pwrite(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func read(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlink(path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rename(from string, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Renameat(fromfd int, from string, tofd int, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Revoke(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rmdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0) - newoffset = int64(int64(r1)<<32 | int64(r0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setegid(egid int) (err error) { - _, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seteuid(euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setgid(gid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setlogin(name string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(name) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpgid(pid int, pgid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpriority(which int, who int, prio int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setprivexec(flag int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setregid(rgid int, egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setreuid(ruid int, euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setsid() (pid int, err error) { - r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) - pid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Settimeofday(tp *Timeval) (err error) { - _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setuid(uid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlink(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Sync() (err error) { - _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Truncate(path string, length int64) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Umask(newmask int) (oldmask int) { - r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) - oldmask = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Undelete(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlink(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlinkat(dirfd int, path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unmount(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func write(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { - r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0) - ret = uintptr(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func munmap(addr uintptr, length uintptr) (err error) { - _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { - r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int32(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatfs(fd int, stat *Statfs_t) (err error) { - _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(buf), uintptr(size), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lstat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Stat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Statfs(path string, stat *Statfs_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go index e263fbdb8b..c8c142c59a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go @@ -24,7 +24,6 @@ func closedir(dir uintptr) (err error) { func libc_closedir_trampoline() -//go:linkname libc_closedir libc_closedir //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -37,5 +36,4 @@ func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { func libc_readdir_r_trampoline() -//go:linkname libc_readdir_r libc_readdir_r //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go index a3fc490041..7f0f117d32 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go @@ -25,7 +25,6 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { func libc_getgroups_trampoline() -//go:linkname libc_getgroups libc_getgroups //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -40,7 +39,6 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { func libc_setgroups_trampoline() -//go:linkname libc_setgroups libc_setgroups //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -56,7 +54,6 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err func libc_wait4_trampoline() -//go:linkname libc_wait4 libc_wait4 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -72,7 +69,6 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { func libc_accept_trampoline() -//go:linkname libc_accept libc_accept //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -87,7 +83,6 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_bind_trampoline() -//go:linkname libc_bind libc_bind //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -102,7 +97,6 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_connect_trampoline() -//go:linkname libc_connect libc_connect //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -118,7 +112,6 @@ func socket(domain int, typ int, proto int) (fd int, err error) { func libc_socket_trampoline() -//go:linkname libc_socket libc_socket //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -133,7 +126,6 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen func libc_getsockopt_trampoline() -//go:linkname libc_getsockopt libc_getsockopt //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -148,7 +140,6 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) func libc_setsockopt_trampoline() -//go:linkname libc_setsockopt libc_setsockopt //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -163,7 +154,6 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getpeername_trampoline() -//go:linkname libc_getpeername libc_getpeername //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -178,7 +168,6 @@ func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getsockname_trampoline() -//go:linkname libc_getsockname libc_getsockname //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -193,7 +182,6 @@ func Shutdown(s int, how int) (err error) { func libc_shutdown_trampoline() -//go:linkname libc_shutdown libc_shutdown //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -208,7 +196,6 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { func libc_socketpair_trampoline() -//go:linkname libc_socketpair libc_socketpair //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -230,7 +217,6 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl func libc_recvfrom_trampoline() -//go:linkname libc_recvfrom libc_recvfrom //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -251,7 +237,6 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( func libc_sendto_trampoline() -//go:linkname libc_sendto libc_sendto //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -267,7 +252,6 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_recvmsg_trampoline() -//go:linkname libc_recvmsg libc_recvmsg //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -283,7 +267,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_sendmsg_trampoline() -//go:linkname libc_sendmsg libc_sendmsg //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -299,7 +282,6 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne func libc_kevent_trampoline() -//go:linkname libc_kevent libc_kevent //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -319,7 +301,6 @@ func utimes(path string, timeval *[2]Timeval) (err error) { func libc_utimes_trampoline() -//go:linkname libc_utimes libc_utimes //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -334,7 +315,6 @@ func futimes(fd int, timeval *[2]Timeval) (err error) { func libc_futimes_trampoline() -//go:linkname libc_futimes libc_futimes //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -350,7 +330,6 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { func libc_poll_trampoline() -//go:linkname libc_poll libc_poll //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -371,7 +350,6 @@ func Madvise(b []byte, behav int) (err error) { func libc_madvise_trampoline() -//go:linkname libc_madvise libc_madvise //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -392,7 +370,6 @@ func Mlock(b []byte) (err error) { func libc_mlock_trampoline() -//go:linkname libc_mlock libc_mlock //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -407,7 +384,6 @@ func Mlockall(flags int) (err error) { func libc_mlockall_trampoline() -//go:linkname libc_mlockall libc_mlockall //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -428,7 +404,6 @@ func Mprotect(b []byte, prot int) (err error) { func libc_mprotect_trampoline() -//go:linkname libc_mprotect libc_mprotect //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -449,7 +424,6 @@ func Msync(b []byte, flags int) (err error) { func libc_msync_trampoline() -//go:linkname libc_msync libc_msync //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -470,7 +444,6 @@ func Munlock(b []byte) (err error) { func libc_munlock_trampoline() -//go:linkname libc_munlock libc_munlock //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -485,26 +458,10 @@ func Munlockall() (err error) { func libc_munlockall_trampoline() -//go:linkname libc_munlockall libc_munlockall //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_getattrlist_trampoline() - -//go:linkname libc_getattrlist libc_getattrlist -//go:cgo_import_dynamic libc_getattrlist getattrlist "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func pipe() (r int, w int, err error) { r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0) r = int(r0) @@ -517,7 +474,6 @@ func pipe() (r int, w int, err error) { func libc_pipe_trampoline() -//go:linkname libc_pipe libc_pipe //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -543,7 +499,6 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o func libc_getxattr_trampoline() -//go:linkname libc_getxattr libc_getxattr //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -564,7 +519,6 @@ func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, optio func libc_fgetxattr_trampoline() -//go:linkname libc_fgetxattr libc_fgetxattr //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -589,7 +543,6 @@ func setxattr(path string, attr string, data *byte, size int, position uint32, o func libc_setxattr_trampoline() -//go:linkname libc_setxattr libc_setxattr //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -609,7 +562,6 @@ func fsetxattr(fd int, attr string, data *byte, size int, position uint32, optio func libc_fsetxattr_trampoline() -//go:linkname libc_fsetxattr libc_fsetxattr //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -634,7 +586,6 @@ func removexattr(path string, attr string, options int) (err error) { func libc_removexattr_trampoline() -//go:linkname libc_removexattr libc_removexattr //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -654,7 +605,6 @@ func fremovexattr(fd int, attr string, options int) (err error) { func libc_fremovexattr_trampoline() -//go:linkname libc_fremovexattr libc_fremovexattr //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -675,7 +625,6 @@ func listxattr(path string, dest *byte, size int, options int) (sz int, err erro func libc_listxattr_trampoline() -//go:linkname libc_listxattr libc_listxattr //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -691,7 +640,6 @@ func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { func libc_flistxattr_trampoline() -//go:linkname libc_flistxattr libc_flistxattr //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -706,7 +654,6 @@ func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp func libc_setattrlist_trampoline() -//go:linkname libc_setattrlist libc_setattrlist //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -722,7 +669,6 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { func libc_fcntl_trampoline() -//go:linkname libc_fcntl libc_fcntl //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -737,7 +683,6 @@ func kill(pid int, signum int, posix int) (err error) { func libc_kill_trampoline() -//go:linkname libc_kill libc_kill //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -752,7 +697,6 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { func libc_ioctl_trampoline() -//go:linkname libc_ioctl libc_ioctl //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -773,7 +717,6 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) func libc_sysctl_trampoline() -//go:linkname libc_sysctl libc_sysctl //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -788,7 +731,6 @@ func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer func libc_sendfile_trampoline() -//go:linkname libc_sendfile libc_sendfile //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -808,7 +750,6 @@ func Access(path string, mode uint32) (err error) { func libc_access_trampoline() -//go:linkname libc_access libc_access //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -823,7 +764,6 @@ func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { func libc_adjtime_trampoline() -//go:linkname libc_adjtime libc_adjtime //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -843,7 +783,6 @@ func Chdir(path string) (err error) { func libc_chdir_trampoline() -//go:linkname libc_chdir libc_chdir //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -863,7 +802,6 @@ func Chflags(path string, flags int) (err error) { func libc_chflags_trampoline() -//go:linkname libc_chflags libc_chflags //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -883,7 +821,6 @@ func Chmod(path string, mode uint32) (err error) { func libc_chmod_trampoline() -//go:linkname libc_chmod libc_chmod //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -903,7 +840,6 @@ func Chown(path string, uid int, gid int) (err error) { func libc_chown_trampoline() -//go:linkname libc_chown libc_chown //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -923,7 +859,6 @@ func Chroot(path string) (err error) { func libc_chroot_trampoline() -//go:linkname libc_chroot libc_chroot //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -938,7 +873,6 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { func libc_clock_gettime_trampoline() -//go:linkname libc_clock_gettime libc_clock_gettime //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -953,11 +887,58 @@ func Close(fd int) (err error) { func libc_close_trampoline() -//go:linkname libc_close libc_close //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Clonefile(src string, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefile_trampoline() + +//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefileat_trampoline() + +//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup(fd int) (nfd int, err error) { r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0) nfd = int(r0) @@ -969,7 +950,6 @@ func Dup(fd int) (nfd int, err error) { func libc_dup_trampoline() -//go:linkname libc_dup libc_dup //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -984,7 +964,6 @@ func Dup2(from int, to int) (err error) { func libc_dup2_trampoline() -//go:linkname libc_dup2 libc_dup2 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1009,7 +988,6 @@ func Exchangedata(path1 string, path2 string, options int) (err error) { func libc_exchangedata_trampoline() -//go:linkname libc_exchangedata libc_exchangedata //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1021,7 +999,6 @@ func Exit(code int) { func libc_exit_trampoline() -//go:linkname libc_exit libc_exit //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1041,7 +1018,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_faccessat_trampoline() -//go:linkname libc_faccessat libc_faccessat //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1056,7 +1032,6 @@ func Fchdir(fd int) (err error) { func libc_fchdir_trampoline() -//go:linkname libc_fchdir libc_fchdir //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1071,7 +1046,6 @@ func Fchflags(fd int, flags int) (err error) { func libc_fchflags_trampoline() -//go:linkname libc_fchflags libc_fchflags //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1086,7 +1060,6 @@ func Fchmod(fd int, mode uint32) (err error) { func libc_fchmod_trampoline() -//go:linkname libc_fchmod libc_fchmod //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1106,7 +1079,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_fchmodat_trampoline() -//go:linkname libc_fchmodat libc_fchmodat //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1121,7 +1093,6 @@ func Fchown(fd int, uid int, gid int) (err error) { func libc_fchown_trampoline() -//go:linkname libc_fchown libc_fchown //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1141,11 +1112,29 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func libc_fchownat_trampoline() -//go:linkname libc_fchownat libc_fchownat //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_fclonefileat_trampoline() + +//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -1156,7 +1145,6 @@ func Flock(fd int, how int) (err error) { func libc_flock_trampoline() -//go:linkname libc_flock libc_flock //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1172,7 +1160,6 @@ func Fpathconf(fd int, name int) (val int, err error) { func libc_fpathconf_trampoline() -//go:linkname libc_fpathconf libc_fpathconf //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1187,7 +1174,6 @@ func Fsync(fd int) (err error) { func libc_fsync_trampoline() -//go:linkname libc_fsync libc_fsync //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1202,11 +1188,31 @@ func Ftruncate(fd int, length int64) (err error) { func libc_ftruncate_trampoline() -//go:linkname libc_ftruncate libc_ftruncate //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_getcwd_trampoline() + +//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdtablesize() (size int) { r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0) size = int(r0) @@ -1215,7 +1221,6 @@ func Getdtablesize() (size int) { func libc_getdtablesize_trampoline() -//go:linkname libc_getdtablesize libc_getdtablesize //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1228,7 +1233,6 @@ func Getegid() (egid int) { func libc_getegid_trampoline() -//go:linkname libc_getegid libc_getegid //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1241,7 +1245,6 @@ func Geteuid() (uid int) { func libc_geteuid_trampoline() -//go:linkname libc_geteuid libc_geteuid //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1254,7 +1257,6 @@ func Getgid() (gid int) { func libc_getgid_trampoline() -//go:linkname libc_getgid libc_getgid //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1270,7 +1272,6 @@ func Getpgid(pid int) (pgid int, err error) { func libc_getpgid_trampoline() -//go:linkname libc_getpgid libc_getpgid //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1283,7 +1284,6 @@ func Getpgrp() (pgrp int) { func libc_getpgrp_trampoline() -//go:linkname libc_getpgrp libc_getpgrp //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1296,7 +1296,6 @@ func Getpid() (pid int) { func libc_getpid_trampoline() -//go:linkname libc_getpid libc_getpid //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1309,7 +1308,6 @@ func Getppid() (ppid int) { func libc_getppid_trampoline() -//go:linkname libc_getppid libc_getppid //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1325,7 +1323,6 @@ func Getpriority(which int, who int) (prio int, err error) { func libc_getpriority_trampoline() -//go:linkname libc_getpriority libc_getpriority //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1340,7 +1337,6 @@ func Getrlimit(which int, lim *Rlimit) (err error) { func libc_getrlimit_trampoline() -//go:linkname libc_getrlimit libc_getrlimit //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1355,7 +1351,6 @@ func Getrusage(who int, rusage *Rusage) (err error) { func libc_getrusage_trampoline() -//go:linkname libc_getrusage libc_getrusage //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1371,11 +1366,24 @@ func Getsid(pid int) (sid int, err error) { func libc_getsid_trampoline() -//go:linkname libc_getsid libc_getsid //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Gettimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_gettimeofday_trampoline() + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getuid() (uid int) { r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0) uid = int(r0) @@ -1384,7 +1392,6 @@ func Getuid() (uid int) { func libc_getuid_trampoline() -//go:linkname libc_getuid libc_getuid //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1397,7 +1404,6 @@ func Issetugid() (tainted bool) { func libc_issetugid_trampoline() -//go:linkname libc_issetugid libc_issetugid //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1413,7 +1419,6 @@ func Kqueue() (fd int, err error) { func libc_kqueue_trampoline() -//go:linkname libc_kqueue libc_kqueue //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1433,7 +1438,6 @@ func Lchown(path string, uid int, gid int) (err error) { func libc_lchown_trampoline() -//go:linkname libc_lchown libc_lchown //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1458,7 +1462,6 @@ func Link(path string, link string) (err error) { func libc_link_trampoline() -//go:linkname libc_link libc_link //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1483,7 +1486,6 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er func libc_linkat_trampoline() -//go:linkname libc_linkat libc_linkat //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1498,7 +1500,6 @@ func Listen(s int, backlog int) (err error) { func libc_listen_trampoline() -//go:linkname libc_listen libc_listen //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1518,7 +1519,6 @@ func Mkdir(path string, mode uint32) (err error) { func libc_mkdir_trampoline() -//go:linkname libc_mkdir libc_mkdir //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1538,7 +1538,6 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { func libc_mkdirat_trampoline() -//go:linkname libc_mkdirat libc_mkdirat //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1558,7 +1557,6 @@ func Mkfifo(path string, mode uint32) (err error) { func libc_mkfifo_trampoline() -//go:linkname libc_mkfifo libc_mkfifo //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1578,7 +1576,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { func libc_mknod_trampoline() -//go:linkname libc_mknod libc_mknod //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1599,7 +1596,6 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { func libc_open_trampoline() -//go:linkname libc_open libc_open //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1620,7 +1616,6 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { func libc_openat_trampoline() -//go:linkname libc_openat libc_openat //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1641,7 +1636,6 @@ func Pathconf(path string, name int) (val int, err error) { func libc_pathconf_trampoline() -//go:linkname libc_pathconf libc_pathconf //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1663,7 +1657,6 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) { func libc_pread_trampoline() -//go:linkname libc_pread libc_pread //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1685,7 +1678,6 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { func libc_pwrite_trampoline() -//go:linkname libc_pwrite libc_pwrite //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1707,7 +1699,6 @@ func read(fd int, p []byte) (n int, err error) { func libc_read_trampoline() -//go:linkname libc_read libc_read //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1734,7 +1725,6 @@ func Readlink(path string, buf []byte) (n int, err error) { func libc_readlink_trampoline() -//go:linkname libc_readlink libc_readlink //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1761,7 +1751,6 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { func libc_readlinkat_trampoline() -//go:linkname libc_readlinkat libc_readlinkat //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1786,7 +1775,6 @@ func Rename(from string, to string) (err error) { func libc_rename_trampoline() -//go:linkname libc_rename libc_rename //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1811,7 +1799,6 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) { func libc_renameat_trampoline() -//go:linkname libc_renameat libc_renameat //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1831,7 +1818,6 @@ func Revoke(path string) (err error) { func libc_revoke_trampoline() -//go:linkname libc_revoke libc_revoke //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1851,7 +1837,6 @@ func Rmdir(path string) (err error) { func libc_rmdir_trampoline() -//go:linkname libc_rmdir libc_rmdir //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1867,7 +1852,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func libc_lseek_trampoline() -//go:linkname libc_lseek libc_lseek //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1883,7 +1867,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err func libc_select_trampoline() -//go:linkname libc_select libc_select //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1898,7 +1881,6 @@ func Setegid(egid int) (err error) { func libc_setegid_trampoline() -//go:linkname libc_setegid libc_setegid //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1913,7 +1895,6 @@ func Seteuid(euid int) (err error) { func libc_seteuid_trampoline() -//go:linkname libc_seteuid libc_seteuid //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1928,7 +1909,6 @@ func Setgid(gid int) (err error) { func libc_setgid_trampoline() -//go:linkname libc_setgid libc_setgid //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1948,7 +1928,6 @@ func Setlogin(name string) (err error) { func libc_setlogin_trampoline() -//go:linkname libc_setlogin libc_setlogin //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1963,7 +1942,6 @@ func Setpgid(pid int, pgid int) (err error) { func libc_setpgid_trampoline() -//go:linkname libc_setpgid libc_setpgid //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1978,7 +1956,6 @@ func Setpriority(which int, who int, prio int) (err error) { func libc_setpriority_trampoline() -//go:linkname libc_setpriority libc_setpriority //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1993,7 +1970,6 @@ func Setprivexec(flag int) (err error) { func libc_setprivexec_trampoline() -//go:linkname libc_setprivexec libc_setprivexec //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2008,7 +1984,6 @@ func Setregid(rgid int, egid int) (err error) { func libc_setregid_trampoline() -//go:linkname libc_setregid libc_setregid //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2023,7 +1998,6 @@ func Setreuid(ruid int, euid int) (err error) { func libc_setreuid_trampoline() -//go:linkname libc_setreuid libc_setreuid //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2038,7 +2012,6 @@ func Setrlimit(which int, lim *Rlimit) (err error) { func libc_setrlimit_trampoline() -//go:linkname libc_setrlimit libc_setrlimit //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2054,7 +2027,6 @@ func Setsid() (pid int, err error) { func libc_setsid_trampoline() -//go:linkname libc_setsid libc_setsid //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2069,7 +2041,6 @@ func Settimeofday(tp *Timeval) (err error) { func libc_settimeofday_trampoline() -//go:linkname libc_settimeofday libc_settimeofday //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2084,7 +2055,6 @@ func Setuid(uid int) (err error) { func libc_setuid_trampoline() -//go:linkname libc_setuid libc_setuid //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2109,7 +2079,6 @@ func Symlink(path string, link string) (err error) { func libc_symlink_trampoline() -//go:linkname libc_symlink libc_symlink //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2134,7 +2103,6 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { func libc_symlinkat_trampoline() -//go:linkname libc_symlinkat libc_symlinkat //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2149,7 +2117,6 @@ func Sync() (err error) { func libc_sync_trampoline() -//go:linkname libc_sync libc_sync //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2169,7 +2136,6 @@ func Truncate(path string, length int64) (err error) { func libc_truncate_trampoline() -//go:linkname libc_truncate libc_truncate //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2182,7 +2148,6 @@ func Umask(newmask int) (oldmask int) { func libc_umask_trampoline() -//go:linkname libc_umask libc_umask //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2202,7 +2167,6 @@ func Undelete(path string) (err error) { func libc_undelete_trampoline() -//go:linkname libc_undelete libc_undelete //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2222,7 +2186,6 @@ func Unlink(path string) (err error) { func libc_unlink_trampoline() -//go:linkname libc_unlink libc_unlink //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2242,7 +2205,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { func libc_unlinkat_trampoline() -//go:linkname libc_unlinkat libc_unlinkat //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2262,7 +2224,6 @@ func Unmount(path string, flags int) (err error) { func libc_unmount_trampoline() -//go:linkname libc_unmount libc_unmount //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2284,7 +2245,6 @@ func write(fd int, p []byte) (n int, err error) { func libc_write_trampoline() -//go:linkname libc_write libc_write //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2300,7 +2260,6 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( func libc_mmap_trampoline() -//go:linkname libc_mmap libc_mmap //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2315,7 +2274,6 @@ func munmap(addr uintptr, length uintptr) (err error) { func libc_munmap_trampoline() -//go:linkname libc_munmap libc_munmap //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2342,38 +2300,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_ptrace_trampoline() - -//go:linkname libc_ptrace libc_ptrace -//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { - r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int32(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_gettimeofday_trampoline() - -//go:linkname libc_gettimeofday libc_gettimeofday -//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2384,7 +2310,6 @@ func Fstat(fd int, stat *Stat_t) (err error) { func libc_fstat64_trampoline() -//go:linkname libc_fstat64 libc_fstat64 //go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2404,7 +2329,6 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { func libc_fstatat64_trampoline() -//go:linkname libc_fstatat64 libc_fstatat64 //go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2419,7 +2343,6 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) { func libc_fstatfs64_trampoline() -//go:linkname libc_fstatfs64 libc_fstatfs64 //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2435,7 +2358,6 @@ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { func libc_getfsstat64_trampoline() -//go:linkname libc_getfsstat64 libc_getfsstat64 //go:cgo_import_dynamic libc_getfsstat64 getfsstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2455,11 +2377,24 @@ func Lstat(path string, stat *Stat_t) (err error) { func libc_lstat64_trampoline() -//go:linkname libc_lstat64 libc_lstat64 //go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_ptrace_trampoline() + +//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Stat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2475,7 +2410,6 @@ func Stat(path string, stat *Stat_t) (err error) { func libc_stat64_trampoline() -//go:linkname libc_stat64 libc_stat64 //go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2495,5 +2429,4 @@ func Statfs(path string, stat *Statfs_t) (err error) { func libc_statfs64_trampoline() -//go:linkname libc_statfs64 libc_statfs64 //go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s index 6836a41290..1c53979a10 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s @@ -60,8 +60,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) -TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 - JMP libc_getattrlist(SB) TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0 @@ -110,6 +108,10 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 JMP libc_close(SB) +TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefile(SB) +TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefileat(SB) TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 JMP libc_dup(SB) TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0 @@ -132,6 +134,8 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) +TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_fclonefileat(SB) TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0 JMP libc_flock(SB) TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0 @@ -140,6 +144,8 @@ TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) +TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0 @@ -164,6 +170,8 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) +TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0 @@ -264,10 +272,6 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) -TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0 - JMP libc_ptrace(SB) -TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 - JMP libc_gettimeofday(SB) TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_fstat64(SB) TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0 @@ -278,6 +282,8 @@ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_getfsstat64(SB) TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_lstat64(SB) +TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0 + JMP libc_ptrace(SB) TEXT ·libc_stat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_stat64(SB) TEXT ·libc_statfs64_trampoline(SB),NOSPLIT,$0-0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go deleted file mode 100644 index f8e5c37c5c..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go +++ /dev/null @@ -1,1811 +0,0 @@ -// go run mksyscall.go -tags darwin,amd64,!go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.1_11.go syscall_darwin_amd64.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build darwin,amd64,!go1.12 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getgroups(ngid int, gid *_Gid_t) (n int, err error) { - r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setgroups(ngid int, gid *_Gid_t) (err error) { - _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { - r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) - wpid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { - r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socket(domain int, typ int, proto int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { - _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { - _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Shutdown(s int, how int) (err error) { - _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { - _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { - r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func utimes(path string, timeval *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func futimes(fd int, timeval *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { - r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Madvise(b []byte, behav int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Msync(b []byte, flags int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func pipe() (r int, w int, err error) { - r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) - r = int(r0) - w = int(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func removexattr(path string, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fremovexattr(fd int, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { - r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_SETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fcntl(fd int, cmd int, arg int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kill(pid int, signum int, posix int) (err error) { - _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func ioctl(fd int, req uint, arg uintptr) (err error) { - _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { - var _p0 unsafe.Pointer - if len(mib) > 0 { - _p0 = unsafe.Pointer(&mib[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { - _, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Access(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { - _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chflags(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chmod(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chroot(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Close(fd int) (err error) { - _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup(fd int) (nfd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) - nfd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup2(from int, to int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exchangedata(path1 string, path2 string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path1) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(path2) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) { - Syscall(SYS_EXIT, uintptr(code), 0, 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchdir(fd int) (err error) { - _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchflags(fd int, flags int) (err error) { - _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmod(fd int, mode uint32) (err error) { - _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchown(fd int, uid int, gid int) (err error) { - _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Flock(fd int, how int) (err error) { - _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fpathconf(fd int, name int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fsync(fd int) (err error) { - _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Ftruncate(fd int, length int64) (err error) { - _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getdtablesize() (size int) { - r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0) - size = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) - egid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Geteuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) - gid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) - pgid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgrp() (pgrp int) { - r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) - pgrp = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) - pid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) - ppid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpriority(which int, who int) (prio int, err error) { - r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) - prio = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrusage(who int, rusage *Rusage) (err error) { - _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getsid(pid int) (sid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) - sid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Issetugid() (tainted bool) { - r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0) - tainted = bool(r0 != 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Kqueue() (fd int, err error) { - r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lchown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Link(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Listen(s int, backlog int) (err error) { - _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdir(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdirat(dirfd int, path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkfifo(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mknod(path string, mode uint32, dev int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Open(path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pathconf(path string, name int) (val int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pread(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pwrite(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func read(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlink(path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rename(from string, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Renameat(fromfd int, from string, tofd int, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Revoke(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rmdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) - newoffset = int64(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setegid(egid int) (err error) { - _, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seteuid(euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setgid(gid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setlogin(name string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(name) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpgid(pid int, pgid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpriority(which int, who int, prio int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setprivexec(flag int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setregid(rgid int, egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setreuid(ruid int, euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setsid() (pid int, err error) { - r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) - pid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Settimeofday(tp *Timeval) (err error) { - _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setuid(uid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlink(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Sync() (err error) { - _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Truncate(path string, length int64) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Umask(newmask int) (oldmask int) { - r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) - oldmask = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Undelete(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlink(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlinkat(dirfd int, path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unmount(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func write(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { - r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) - ret = uintptr(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func munmap(addr uintptr, length uintptr) (err error) { - _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { - r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int64(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatfs(fd int, stat *Statfs_t) (err error) { - _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(buf), uintptr(size), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lstat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Stat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Statfs(path string, stat *Statfs_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go index 314042a9d4..8882623613 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go @@ -24,7 +24,6 @@ func closedir(dir uintptr) (err error) { func libc_closedir_trampoline() -//go:linkname libc_closedir libc_closedir //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -37,5 +36,4 @@ func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { func libc_readdir_r_trampoline() -//go:linkname libc_readdir_r libc_readdir_r //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 50d6437e6b..2daf0bd628 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -25,7 +25,6 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { func libc_getgroups_trampoline() -//go:linkname libc_getgroups libc_getgroups //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -40,7 +39,6 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { func libc_setgroups_trampoline() -//go:linkname libc_setgroups libc_setgroups //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -56,7 +54,6 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err func libc_wait4_trampoline() -//go:linkname libc_wait4 libc_wait4 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -72,7 +69,6 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { func libc_accept_trampoline() -//go:linkname libc_accept libc_accept //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -87,7 +83,6 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_bind_trampoline() -//go:linkname libc_bind libc_bind //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -102,7 +97,6 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_connect_trampoline() -//go:linkname libc_connect libc_connect //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -118,7 +112,6 @@ func socket(domain int, typ int, proto int) (fd int, err error) { func libc_socket_trampoline() -//go:linkname libc_socket libc_socket //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -133,7 +126,6 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen func libc_getsockopt_trampoline() -//go:linkname libc_getsockopt libc_getsockopt //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -148,7 +140,6 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) func libc_setsockopt_trampoline() -//go:linkname libc_setsockopt libc_setsockopt //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -163,7 +154,6 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getpeername_trampoline() -//go:linkname libc_getpeername libc_getpeername //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -178,7 +168,6 @@ func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getsockname_trampoline() -//go:linkname libc_getsockname libc_getsockname //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -193,7 +182,6 @@ func Shutdown(s int, how int) (err error) { func libc_shutdown_trampoline() -//go:linkname libc_shutdown libc_shutdown //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -208,7 +196,6 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { func libc_socketpair_trampoline() -//go:linkname libc_socketpair libc_socketpair //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -230,7 +217,6 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl func libc_recvfrom_trampoline() -//go:linkname libc_recvfrom libc_recvfrom //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -251,7 +237,6 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( func libc_sendto_trampoline() -//go:linkname libc_sendto libc_sendto //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -267,7 +252,6 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_recvmsg_trampoline() -//go:linkname libc_recvmsg libc_recvmsg //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -283,7 +267,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_sendmsg_trampoline() -//go:linkname libc_sendmsg libc_sendmsg //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -299,7 +282,6 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne func libc_kevent_trampoline() -//go:linkname libc_kevent libc_kevent //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -319,7 +301,6 @@ func utimes(path string, timeval *[2]Timeval) (err error) { func libc_utimes_trampoline() -//go:linkname libc_utimes libc_utimes //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -334,7 +315,6 @@ func futimes(fd int, timeval *[2]Timeval) (err error) { func libc_futimes_trampoline() -//go:linkname libc_futimes libc_futimes //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -350,7 +330,6 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { func libc_poll_trampoline() -//go:linkname libc_poll libc_poll //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -371,7 +350,6 @@ func Madvise(b []byte, behav int) (err error) { func libc_madvise_trampoline() -//go:linkname libc_madvise libc_madvise //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -392,7 +370,6 @@ func Mlock(b []byte) (err error) { func libc_mlock_trampoline() -//go:linkname libc_mlock libc_mlock //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -407,7 +384,6 @@ func Mlockall(flags int) (err error) { func libc_mlockall_trampoline() -//go:linkname libc_mlockall libc_mlockall //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -428,7 +404,6 @@ func Mprotect(b []byte, prot int) (err error) { func libc_mprotect_trampoline() -//go:linkname libc_mprotect libc_mprotect //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -449,7 +424,6 @@ func Msync(b []byte, flags int) (err error) { func libc_msync_trampoline() -//go:linkname libc_msync libc_msync //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -470,7 +444,6 @@ func Munlock(b []byte) (err error) { func libc_munlock_trampoline() -//go:linkname libc_munlock libc_munlock //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -485,26 +458,10 @@ func Munlockall() (err error) { func libc_munlockall_trampoline() -//go:linkname libc_munlockall libc_munlockall //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_getattrlist_trampoline() - -//go:linkname libc_getattrlist libc_getattrlist -//go:cgo_import_dynamic libc_getattrlist getattrlist "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func pipe() (r int, w int, err error) { r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0) r = int(r0) @@ -517,7 +474,6 @@ func pipe() (r int, w int, err error) { func libc_pipe_trampoline() -//go:linkname libc_pipe libc_pipe //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -543,7 +499,6 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o func libc_getxattr_trampoline() -//go:linkname libc_getxattr libc_getxattr //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -564,7 +519,6 @@ func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, optio func libc_fgetxattr_trampoline() -//go:linkname libc_fgetxattr libc_fgetxattr //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -589,7 +543,6 @@ func setxattr(path string, attr string, data *byte, size int, position uint32, o func libc_setxattr_trampoline() -//go:linkname libc_setxattr libc_setxattr //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -609,7 +562,6 @@ func fsetxattr(fd int, attr string, data *byte, size int, position uint32, optio func libc_fsetxattr_trampoline() -//go:linkname libc_fsetxattr libc_fsetxattr //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -634,7 +586,6 @@ func removexattr(path string, attr string, options int) (err error) { func libc_removexattr_trampoline() -//go:linkname libc_removexattr libc_removexattr //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -654,7 +605,6 @@ func fremovexattr(fd int, attr string, options int) (err error) { func libc_fremovexattr_trampoline() -//go:linkname libc_fremovexattr libc_fremovexattr //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -675,7 +625,6 @@ func listxattr(path string, dest *byte, size int, options int) (sz int, err erro func libc_listxattr_trampoline() -//go:linkname libc_listxattr libc_listxattr //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -691,7 +640,6 @@ func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { func libc_flistxattr_trampoline() -//go:linkname libc_flistxattr libc_flistxattr //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -706,7 +654,6 @@ func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp func libc_setattrlist_trampoline() -//go:linkname libc_setattrlist libc_setattrlist //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -722,7 +669,6 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { func libc_fcntl_trampoline() -//go:linkname libc_fcntl libc_fcntl //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -737,7 +683,6 @@ func kill(pid int, signum int, posix int) (err error) { func libc_kill_trampoline() -//go:linkname libc_kill libc_kill //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -752,7 +697,6 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { func libc_ioctl_trampoline() -//go:linkname libc_ioctl libc_ioctl //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -773,7 +717,6 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) func libc_sysctl_trampoline() -//go:linkname libc_sysctl libc_sysctl //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -788,7 +731,6 @@ func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer func libc_sendfile_trampoline() -//go:linkname libc_sendfile libc_sendfile //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -808,7 +750,6 @@ func Access(path string, mode uint32) (err error) { func libc_access_trampoline() -//go:linkname libc_access libc_access //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -823,7 +764,6 @@ func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { func libc_adjtime_trampoline() -//go:linkname libc_adjtime libc_adjtime //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -843,7 +783,6 @@ func Chdir(path string) (err error) { func libc_chdir_trampoline() -//go:linkname libc_chdir libc_chdir //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -863,7 +802,6 @@ func Chflags(path string, flags int) (err error) { func libc_chflags_trampoline() -//go:linkname libc_chflags libc_chflags //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -883,7 +821,6 @@ func Chmod(path string, mode uint32) (err error) { func libc_chmod_trampoline() -//go:linkname libc_chmod libc_chmod //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -903,7 +840,6 @@ func Chown(path string, uid int, gid int) (err error) { func libc_chown_trampoline() -//go:linkname libc_chown libc_chown //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -923,7 +859,6 @@ func Chroot(path string) (err error) { func libc_chroot_trampoline() -//go:linkname libc_chroot libc_chroot //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -938,7 +873,6 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { func libc_clock_gettime_trampoline() -//go:linkname libc_clock_gettime libc_clock_gettime //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -953,11 +887,58 @@ func Close(fd int) (err error) { func libc_close_trampoline() -//go:linkname libc_close libc_close //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Clonefile(src string, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefile_trampoline() + +//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefileat_trampoline() + +//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup(fd int) (nfd int, err error) { r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0) nfd = int(r0) @@ -969,7 +950,6 @@ func Dup(fd int) (nfd int, err error) { func libc_dup_trampoline() -//go:linkname libc_dup libc_dup //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -984,7 +964,6 @@ func Dup2(from int, to int) (err error) { func libc_dup2_trampoline() -//go:linkname libc_dup2 libc_dup2 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1009,7 +988,6 @@ func Exchangedata(path1 string, path2 string, options int) (err error) { func libc_exchangedata_trampoline() -//go:linkname libc_exchangedata libc_exchangedata //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1021,7 +999,6 @@ func Exit(code int) { func libc_exit_trampoline() -//go:linkname libc_exit libc_exit //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1041,7 +1018,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_faccessat_trampoline() -//go:linkname libc_faccessat libc_faccessat //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1056,7 +1032,6 @@ func Fchdir(fd int) (err error) { func libc_fchdir_trampoline() -//go:linkname libc_fchdir libc_fchdir //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1071,7 +1046,6 @@ func Fchflags(fd int, flags int) (err error) { func libc_fchflags_trampoline() -//go:linkname libc_fchflags libc_fchflags //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1086,7 +1060,6 @@ func Fchmod(fd int, mode uint32) (err error) { func libc_fchmod_trampoline() -//go:linkname libc_fchmod libc_fchmod //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1106,7 +1079,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_fchmodat_trampoline() -//go:linkname libc_fchmodat libc_fchmodat //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1121,7 +1093,6 @@ func Fchown(fd int, uid int, gid int) (err error) { func libc_fchown_trampoline() -//go:linkname libc_fchown libc_fchown //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1141,11 +1112,29 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func libc_fchownat_trampoline() -//go:linkname libc_fchownat libc_fchownat //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_fclonefileat_trampoline() + +//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -1156,7 +1145,6 @@ func Flock(fd int, how int) (err error) { func libc_flock_trampoline() -//go:linkname libc_flock libc_flock //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1172,7 +1160,6 @@ func Fpathconf(fd int, name int) (val int, err error) { func libc_fpathconf_trampoline() -//go:linkname libc_fpathconf libc_fpathconf //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1187,7 +1174,6 @@ func Fsync(fd int) (err error) { func libc_fsync_trampoline() -//go:linkname libc_fsync libc_fsync //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1202,11 +1188,31 @@ func Ftruncate(fd int, length int64) (err error) { func libc_ftruncate_trampoline() -//go:linkname libc_ftruncate libc_ftruncate //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_getcwd_trampoline() + +//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdtablesize() (size int) { r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0) size = int(r0) @@ -1215,7 +1221,6 @@ func Getdtablesize() (size int) { func libc_getdtablesize_trampoline() -//go:linkname libc_getdtablesize libc_getdtablesize //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1228,7 +1233,6 @@ func Getegid() (egid int) { func libc_getegid_trampoline() -//go:linkname libc_getegid libc_getegid //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1241,7 +1245,6 @@ func Geteuid() (uid int) { func libc_geteuid_trampoline() -//go:linkname libc_geteuid libc_geteuid //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1254,7 +1257,6 @@ func Getgid() (gid int) { func libc_getgid_trampoline() -//go:linkname libc_getgid libc_getgid //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1270,7 +1272,6 @@ func Getpgid(pid int) (pgid int, err error) { func libc_getpgid_trampoline() -//go:linkname libc_getpgid libc_getpgid //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1283,7 +1284,6 @@ func Getpgrp() (pgrp int) { func libc_getpgrp_trampoline() -//go:linkname libc_getpgrp libc_getpgrp //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1296,7 +1296,6 @@ func Getpid() (pid int) { func libc_getpid_trampoline() -//go:linkname libc_getpid libc_getpid //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1309,7 +1308,6 @@ func Getppid() (ppid int) { func libc_getppid_trampoline() -//go:linkname libc_getppid libc_getppid //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1325,7 +1323,6 @@ func Getpriority(which int, who int) (prio int, err error) { func libc_getpriority_trampoline() -//go:linkname libc_getpriority libc_getpriority //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1340,7 +1337,6 @@ func Getrlimit(which int, lim *Rlimit) (err error) { func libc_getrlimit_trampoline() -//go:linkname libc_getrlimit libc_getrlimit //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1355,7 +1351,6 @@ func Getrusage(who int, rusage *Rusage) (err error) { func libc_getrusage_trampoline() -//go:linkname libc_getrusage libc_getrusage //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1371,11 +1366,24 @@ func Getsid(pid int) (sid int, err error) { func libc_getsid_trampoline() -//go:linkname libc_getsid libc_getsid //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Gettimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_gettimeofday_trampoline() + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getuid() (uid int) { r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0) uid = int(r0) @@ -1384,7 +1392,6 @@ func Getuid() (uid int) { func libc_getuid_trampoline() -//go:linkname libc_getuid libc_getuid //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1397,7 +1404,6 @@ func Issetugid() (tainted bool) { func libc_issetugid_trampoline() -//go:linkname libc_issetugid libc_issetugid //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1413,7 +1419,6 @@ func Kqueue() (fd int, err error) { func libc_kqueue_trampoline() -//go:linkname libc_kqueue libc_kqueue //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1433,7 +1438,6 @@ func Lchown(path string, uid int, gid int) (err error) { func libc_lchown_trampoline() -//go:linkname libc_lchown libc_lchown //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1458,7 +1462,6 @@ func Link(path string, link string) (err error) { func libc_link_trampoline() -//go:linkname libc_link libc_link //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1483,7 +1486,6 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er func libc_linkat_trampoline() -//go:linkname libc_linkat libc_linkat //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1498,7 +1500,6 @@ func Listen(s int, backlog int) (err error) { func libc_listen_trampoline() -//go:linkname libc_listen libc_listen //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1518,7 +1519,6 @@ func Mkdir(path string, mode uint32) (err error) { func libc_mkdir_trampoline() -//go:linkname libc_mkdir libc_mkdir //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1538,7 +1538,6 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { func libc_mkdirat_trampoline() -//go:linkname libc_mkdirat libc_mkdirat //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1558,7 +1557,6 @@ func Mkfifo(path string, mode uint32) (err error) { func libc_mkfifo_trampoline() -//go:linkname libc_mkfifo libc_mkfifo //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1578,7 +1576,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { func libc_mknod_trampoline() -//go:linkname libc_mknod libc_mknod //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1599,7 +1596,6 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { func libc_open_trampoline() -//go:linkname libc_open libc_open //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1620,7 +1616,6 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { func libc_openat_trampoline() -//go:linkname libc_openat libc_openat //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1641,7 +1636,6 @@ func Pathconf(path string, name int) (val int, err error) { func libc_pathconf_trampoline() -//go:linkname libc_pathconf libc_pathconf //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1663,7 +1657,6 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) { func libc_pread_trampoline() -//go:linkname libc_pread libc_pread //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1685,7 +1678,6 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { func libc_pwrite_trampoline() -//go:linkname libc_pwrite libc_pwrite //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1707,7 +1699,6 @@ func read(fd int, p []byte) (n int, err error) { func libc_read_trampoline() -//go:linkname libc_read libc_read //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1734,7 +1725,6 @@ func Readlink(path string, buf []byte) (n int, err error) { func libc_readlink_trampoline() -//go:linkname libc_readlink libc_readlink //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1761,7 +1751,6 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { func libc_readlinkat_trampoline() -//go:linkname libc_readlinkat libc_readlinkat //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1786,7 +1775,6 @@ func Rename(from string, to string) (err error) { func libc_rename_trampoline() -//go:linkname libc_rename libc_rename //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1811,7 +1799,6 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) { func libc_renameat_trampoline() -//go:linkname libc_renameat libc_renameat //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1831,7 +1818,6 @@ func Revoke(path string) (err error) { func libc_revoke_trampoline() -//go:linkname libc_revoke libc_revoke //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1851,7 +1837,6 @@ func Rmdir(path string) (err error) { func libc_rmdir_trampoline() -//go:linkname libc_rmdir libc_rmdir //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1867,7 +1852,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func libc_lseek_trampoline() -//go:linkname libc_lseek libc_lseek //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1883,7 +1867,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err func libc_select_trampoline() -//go:linkname libc_select libc_select //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1898,7 +1881,6 @@ func Setegid(egid int) (err error) { func libc_setegid_trampoline() -//go:linkname libc_setegid libc_setegid //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1913,7 +1895,6 @@ func Seteuid(euid int) (err error) { func libc_seteuid_trampoline() -//go:linkname libc_seteuid libc_seteuid //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1928,7 +1909,6 @@ func Setgid(gid int) (err error) { func libc_setgid_trampoline() -//go:linkname libc_setgid libc_setgid //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1948,7 +1928,6 @@ func Setlogin(name string) (err error) { func libc_setlogin_trampoline() -//go:linkname libc_setlogin libc_setlogin //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1963,7 +1942,6 @@ func Setpgid(pid int, pgid int) (err error) { func libc_setpgid_trampoline() -//go:linkname libc_setpgid libc_setpgid //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1978,7 +1956,6 @@ func Setpriority(which int, who int, prio int) (err error) { func libc_setpriority_trampoline() -//go:linkname libc_setpriority libc_setpriority //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1993,7 +1970,6 @@ func Setprivexec(flag int) (err error) { func libc_setprivexec_trampoline() -//go:linkname libc_setprivexec libc_setprivexec //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2008,7 +1984,6 @@ func Setregid(rgid int, egid int) (err error) { func libc_setregid_trampoline() -//go:linkname libc_setregid libc_setregid //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2023,7 +1998,6 @@ func Setreuid(ruid int, euid int) (err error) { func libc_setreuid_trampoline() -//go:linkname libc_setreuid libc_setreuid //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2038,7 +2012,6 @@ func Setrlimit(which int, lim *Rlimit) (err error) { func libc_setrlimit_trampoline() -//go:linkname libc_setrlimit libc_setrlimit //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2054,7 +2027,6 @@ func Setsid() (pid int, err error) { func libc_setsid_trampoline() -//go:linkname libc_setsid libc_setsid //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2069,7 +2041,6 @@ func Settimeofday(tp *Timeval) (err error) { func libc_settimeofday_trampoline() -//go:linkname libc_settimeofday libc_settimeofday //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2084,7 +2055,6 @@ func Setuid(uid int) (err error) { func libc_setuid_trampoline() -//go:linkname libc_setuid libc_setuid //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2109,7 +2079,6 @@ func Symlink(path string, link string) (err error) { func libc_symlink_trampoline() -//go:linkname libc_symlink libc_symlink //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2134,7 +2103,6 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { func libc_symlinkat_trampoline() -//go:linkname libc_symlinkat libc_symlinkat //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2149,7 +2117,6 @@ func Sync() (err error) { func libc_sync_trampoline() -//go:linkname libc_sync libc_sync //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2169,7 +2136,6 @@ func Truncate(path string, length int64) (err error) { func libc_truncate_trampoline() -//go:linkname libc_truncate libc_truncate //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2182,7 +2148,6 @@ func Umask(newmask int) (oldmask int) { func libc_umask_trampoline() -//go:linkname libc_umask libc_umask //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2202,7 +2167,6 @@ func Undelete(path string) (err error) { func libc_undelete_trampoline() -//go:linkname libc_undelete libc_undelete //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2222,7 +2186,6 @@ func Unlink(path string) (err error) { func libc_unlink_trampoline() -//go:linkname libc_unlink libc_unlink //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2242,7 +2205,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { func libc_unlinkat_trampoline() -//go:linkname libc_unlinkat libc_unlinkat //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2262,7 +2224,6 @@ func Unmount(path string, flags int) (err error) { func libc_unmount_trampoline() -//go:linkname libc_unmount libc_unmount //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2284,7 +2245,6 @@ func write(fd int, p []byte) (n int, err error) { func libc_write_trampoline() -//go:linkname libc_write libc_write //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2300,7 +2260,6 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( func libc_mmap_trampoline() -//go:linkname libc_mmap libc_mmap //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2315,7 +2274,6 @@ func munmap(addr uintptr, length uintptr) (err error) { func libc_munmap_trampoline() -//go:linkname libc_munmap libc_munmap //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2342,38 +2300,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_ptrace_trampoline() - -//go:linkname libc_ptrace libc_ptrace -//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { - r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int64(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_gettimeofday_trampoline() - -//go:linkname libc_gettimeofday libc_gettimeofday -//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2384,7 +2310,6 @@ func Fstat(fd int, stat *Stat_t) (err error) { func libc_fstat64_trampoline() -//go:linkname libc_fstat64 libc_fstat64 //go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2404,7 +2329,6 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { func libc_fstatat64_trampoline() -//go:linkname libc_fstatat64 libc_fstatat64 //go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2419,7 +2343,6 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) { func libc_fstatfs64_trampoline() -//go:linkname libc_fstatfs64 libc_fstatfs64 //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2435,7 +2358,6 @@ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { func libc_getfsstat64_trampoline() -//go:linkname libc_getfsstat64 libc_getfsstat64 //go:cgo_import_dynamic libc_getfsstat64 getfsstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2455,11 +2377,24 @@ func Lstat(path string, stat *Stat_t) (err error) { func libc_lstat64_trampoline() -//go:linkname libc_lstat64 libc_lstat64 //go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_ptrace_trampoline() + +//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Stat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2475,7 +2410,6 @@ func Stat(path string, stat *Stat_t) (err error) { func libc_stat64_trampoline() -//go:linkname libc_stat64 libc_stat64 //go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2495,5 +2429,4 @@ func Statfs(path string, stat *Statfs_t) (err error) { func libc_statfs64_trampoline() -//go:linkname libc_statfs64 libc_statfs64 //go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index a3fdf099d0..c77bd6e20b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -60,8 +60,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) -TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 - JMP libc_getattrlist(SB) TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0 @@ -110,6 +108,10 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 JMP libc_close(SB) +TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefile(SB) +TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefileat(SB) TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 JMP libc_dup(SB) TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0 @@ -132,6 +134,8 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) +TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_fclonefileat(SB) TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0 JMP libc_flock(SB) TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0 @@ -140,6 +144,8 @@ TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) +TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0 @@ -164,6 +170,8 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) +TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0 @@ -264,10 +272,6 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) -TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0 - JMP libc_ptrace(SB) -TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 - JMP libc_gettimeofday(SB) TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_fstat64(SB) TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0 @@ -278,6 +282,8 @@ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_getfsstat64(SB) TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_lstat64(SB) +TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0 + JMP libc_ptrace(SB) TEXT ·libc_stat64_trampoline(SB),NOSPLIT,$0-0 JMP libc_stat64(SB) TEXT ·libc_statfs64_trampoline(SB),NOSPLIT,$0-0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go deleted file mode 100644 index cea04e041c..0000000000 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go +++ /dev/null @@ -1,1784 +0,0 @@ -// go run mksyscall.go -l32 -tags darwin,arm,!go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm.1_11.go syscall_darwin_arm.go -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build darwin,arm,!go1.12 - -package unix - -import ( - "syscall" - "unsafe" -) - -var _ syscall.Errno - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getgroups(ngid int, gid *_Gid_t) (n int, err error) { - r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setgroups(ngid int, gid *_Gid_t) (err error) { - _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { - r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) - wpid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { - r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socket(domain int, typ int, proto int) (fd int, err error) { - r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { - _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { - _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Shutdown(s int, how int) (err error) { - _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { - _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { - r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func utimes(path string, timeval *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func futimes(fd int, timeval *[2]Timeval) (err error) { - _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { - r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Madvise(b []byte, behav int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Msync(b []byte, flags int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func pipe() (r int, w int, err error) { - r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) - r = int(r0) - w = int(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func removexattr(path string, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fremovexattr(fd int, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { - r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_SETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fcntl(fd int, cmd int, arg int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kill(pid int, signum int, posix int) (err error) { - _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func ioctl(fd int, req uint, arg uintptr) (err error) { - _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { - var _p0 unsafe.Pointer - if len(mib) > 0 { - _p0 = unsafe.Pointer(&mib[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { - _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(offset>>32), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Access(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { - _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chflags(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chmod(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Chroot(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Close(fd int) (err error) { - _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup(fd int) (nfd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) - nfd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup2(from int, to int) (err error) { - _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exchangedata(path1 string, path2 string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path1) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(path2) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) { - Syscall(SYS_EXIT, uintptr(code), 0, 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchdir(fd int) (err error) { - _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchflags(fd int, flags int) (err error) { - _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmod(fd int, mode uint32) (err error) { - _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchown(fd int, uid int, gid int) (err error) { - _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Flock(fd int, how int) (err error) { - _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fpathconf(fd int, name int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fsync(fd int) (err error) { - _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Ftruncate(fd int, length int64) (err error) { - _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getdtablesize() (size int) { - r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0) - size = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) - egid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Geteuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) - gid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) - pgid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpgrp() (pgrp int) { - r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) - pgrp = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) - pid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) - ppid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getpriority(which int, who int) (prio int, err error) { - r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) - prio = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getrusage(who int, rusage *Rusage) (err error) { - _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getsid(pid int) (sid int, err error) { - r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) - sid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) - uid = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Issetugid() (tainted bool) { - r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0) - tainted = bool(r0 != 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Kqueue() (fd int, err error) { - r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lchown(path string, uid int, gid int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Link(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Listen(s int, backlog int) (err error) { - _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdir(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkdirat(dirfd int, path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mkfifo(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mknod(path string, mode uint32, dev int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Open(path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) - fd = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pathconf(path string, name int) (val int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pread(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pwrite(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func read(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlink(path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(buf) > 0 { - _p1 = unsafe.Pointer(&buf[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rename(from string, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Renameat(fromfd int, from string, tofd int, to string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(from) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(to) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Revoke(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Rmdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0) - newoffset = int64(int64(r1)<<32 | int64(r0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setegid(egid int) (err error) { - _, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Seteuid(euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setgid(gid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setlogin(name string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(name) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpgid(pid int, pgid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setpriority(which int, who int, prio int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setprivexec(flag int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setregid(rgid int, egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setreuid(ruid int, euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setsid() (pid int, err error) { - r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) - pid = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Settimeofday(tp *Timeval) (err error) { - _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Setuid(uid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlink(path string, link string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(link) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Sync() (err error) { - _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Truncate(path string, length int64) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Umask(newmask int) (oldmask int) { - r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) - oldmask = int(r0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Undelete(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlink(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unlinkat(dirfd int, path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Unmount(path string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func write(fd int, p []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { - r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0) - ret = uintptr(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func munmap(addr uintptr, length uintptr) (err error) { - _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { - r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int32(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatfs(fd int, stat *Statfs_t) (err error) { - _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(buf), uintptr(size), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lstat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Stat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Statfs(path string, stat *Statfs_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go index f519ce9afb..de4738fff8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go @@ -24,7 +24,6 @@ func closedir(dir uintptr) (err error) { func libc_closedir_trampoline() -//go:linkname libc_closedir libc_closedir //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -37,5 +36,4 @@ func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { func libc_readdir_r_trampoline() -//go:linkname libc_readdir_r libc_readdir_r //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go index 63103950ca..8e79ad377b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go @@ -25,7 +25,6 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { func libc_getgroups_trampoline() -//go:linkname libc_getgroups libc_getgroups //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -40,7 +39,6 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { func libc_setgroups_trampoline() -//go:linkname libc_setgroups libc_setgroups //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -56,7 +54,6 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err func libc_wait4_trampoline() -//go:linkname libc_wait4 libc_wait4 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -72,7 +69,6 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { func libc_accept_trampoline() -//go:linkname libc_accept libc_accept //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -87,7 +83,6 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_bind_trampoline() -//go:linkname libc_bind libc_bind //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -102,7 +97,6 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_connect_trampoline() -//go:linkname libc_connect libc_connect //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -118,7 +112,6 @@ func socket(domain int, typ int, proto int) (fd int, err error) { func libc_socket_trampoline() -//go:linkname libc_socket libc_socket //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -133,7 +126,6 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen func libc_getsockopt_trampoline() -//go:linkname libc_getsockopt libc_getsockopt //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -148,7 +140,6 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) func libc_setsockopt_trampoline() -//go:linkname libc_setsockopt libc_setsockopt //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -163,7 +154,6 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getpeername_trampoline() -//go:linkname libc_getpeername libc_getpeername //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -178,7 +168,6 @@ func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getsockname_trampoline() -//go:linkname libc_getsockname libc_getsockname //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -193,7 +182,6 @@ func Shutdown(s int, how int) (err error) { func libc_shutdown_trampoline() -//go:linkname libc_shutdown libc_shutdown //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -208,7 +196,6 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { func libc_socketpair_trampoline() -//go:linkname libc_socketpair libc_socketpair //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -230,7 +217,6 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl func libc_recvfrom_trampoline() -//go:linkname libc_recvfrom libc_recvfrom //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -251,7 +237,6 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( func libc_sendto_trampoline() -//go:linkname libc_sendto libc_sendto //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -267,7 +252,6 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_recvmsg_trampoline() -//go:linkname libc_recvmsg libc_recvmsg //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -283,7 +267,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_sendmsg_trampoline() -//go:linkname libc_sendmsg libc_sendmsg //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -299,7 +282,6 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne func libc_kevent_trampoline() -//go:linkname libc_kevent libc_kevent //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -319,7 +301,6 @@ func utimes(path string, timeval *[2]Timeval) (err error) { func libc_utimes_trampoline() -//go:linkname libc_utimes libc_utimes //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -334,7 +315,6 @@ func futimes(fd int, timeval *[2]Timeval) (err error) { func libc_futimes_trampoline() -//go:linkname libc_futimes libc_futimes //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -350,7 +330,6 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { func libc_poll_trampoline() -//go:linkname libc_poll libc_poll //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -371,7 +350,6 @@ func Madvise(b []byte, behav int) (err error) { func libc_madvise_trampoline() -//go:linkname libc_madvise libc_madvise //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -392,7 +370,6 @@ func Mlock(b []byte) (err error) { func libc_mlock_trampoline() -//go:linkname libc_mlock libc_mlock //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -407,7 +384,6 @@ func Mlockall(flags int) (err error) { func libc_mlockall_trampoline() -//go:linkname libc_mlockall libc_mlockall //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -428,7 +404,6 @@ func Mprotect(b []byte, prot int) (err error) { func libc_mprotect_trampoline() -//go:linkname libc_mprotect libc_mprotect //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -449,7 +424,6 @@ func Msync(b []byte, flags int) (err error) { func libc_msync_trampoline() -//go:linkname libc_msync libc_msync //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -470,7 +444,6 @@ func Munlock(b []byte) (err error) { func libc_munlock_trampoline() -//go:linkname libc_munlock libc_munlock //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -485,26 +458,10 @@ func Munlockall() (err error) { func libc_munlockall_trampoline() -//go:linkname libc_munlockall libc_munlockall //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_getattrlist_trampoline() - -//go:linkname libc_getattrlist libc_getattrlist -//go:cgo_import_dynamic libc_getattrlist getattrlist "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func pipe() (r int, w int, err error) { r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0) r = int(r0) @@ -517,7 +474,6 @@ func pipe() (r int, w int, err error) { func libc_pipe_trampoline() -//go:linkname libc_pipe libc_pipe //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -543,7 +499,6 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o func libc_getxattr_trampoline() -//go:linkname libc_getxattr libc_getxattr //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -564,7 +519,6 @@ func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, optio func libc_fgetxattr_trampoline() -//go:linkname libc_fgetxattr libc_fgetxattr //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -589,7 +543,6 @@ func setxattr(path string, attr string, data *byte, size int, position uint32, o func libc_setxattr_trampoline() -//go:linkname libc_setxattr libc_setxattr //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -609,7 +562,6 @@ func fsetxattr(fd int, attr string, data *byte, size int, position uint32, optio func libc_fsetxattr_trampoline() -//go:linkname libc_fsetxattr libc_fsetxattr //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -634,7 +586,6 @@ func removexattr(path string, attr string, options int) (err error) { func libc_removexattr_trampoline() -//go:linkname libc_removexattr libc_removexattr //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -654,7 +605,6 @@ func fremovexattr(fd int, attr string, options int) (err error) { func libc_fremovexattr_trampoline() -//go:linkname libc_fremovexattr libc_fremovexattr //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -675,7 +625,6 @@ func listxattr(path string, dest *byte, size int, options int) (sz int, err erro func libc_listxattr_trampoline() -//go:linkname libc_listxattr libc_listxattr //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -691,7 +640,6 @@ func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { func libc_flistxattr_trampoline() -//go:linkname libc_flistxattr libc_flistxattr //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -706,7 +654,6 @@ func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp func libc_setattrlist_trampoline() -//go:linkname libc_setattrlist libc_setattrlist //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -722,7 +669,6 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { func libc_fcntl_trampoline() -//go:linkname libc_fcntl libc_fcntl //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -737,7 +683,6 @@ func kill(pid int, signum int, posix int) (err error) { func libc_kill_trampoline() -//go:linkname libc_kill libc_kill //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -752,7 +697,6 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { func libc_ioctl_trampoline() -//go:linkname libc_ioctl libc_ioctl //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -773,7 +717,6 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) func libc_sysctl_trampoline() -//go:linkname libc_sysctl libc_sysctl //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -788,7 +731,6 @@ func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer func libc_sendfile_trampoline() -//go:linkname libc_sendfile libc_sendfile //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -808,7 +750,6 @@ func Access(path string, mode uint32) (err error) { func libc_access_trampoline() -//go:linkname libc_access libc_access //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -823,7 +764,6 @@ func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { func libc_adjtime_trampoline() -//go:linkname libc_adjtime libc_adjtime //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -843,7 +783,6 @@ func Chdir(path string) (err error) { func libc_chdir_trampoline() -//go:linkname libc_chdir libc_chdir //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -863,7 +802,6 @@ func Chflags(path string, flags int) (err error) { func libc_chflags_trampoline() -//go:linkname libc_chflags libc_chflags //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -883,7 +821,6 @@ func Chmod(path string, mode uint32) (err error) { func libc_chmod_trampoline() -//go:linkname libc_chmod libc_chmod //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -903,7 +840,6 @@ func Chown(path string, uid int, gid int) (err error) { func libc_chown_trampoline() -//go:linkname libc_chown libc_chown //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -923,7 +859,6 @@ func Chroot(path string) (err error) { func libc_chroot_trampoline() -//go:linkname libc_chroot libc_chroot //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -938,7 +873,6 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { func libc_clock_gettime_trampoline() -//go:linkname libc_clock_gettime libc_clock_gettime //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -953,11 +887,58 @@ func Close(fd int) (err error) { func libc_close_trampoline() -//go:linkname libc_close libc_close //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Clonefile(src string, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefile_trampoline() + +//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefileat_trampoline() + +//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup(fd int) (nfd int, err error) { r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0) nfd = int(r0) @@ -969,7 +950,6 @@ func Dup(fd int) (nfd int, err error) { func libc_dup_trampoline() -//go:linkname libc_dup libc_dup //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -984,7 +964,6 @@ func Dup2(from int, to int) (err error) { func libc_dup2_trampoline() -//go:linkname libc_dup2 libc_dup2 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1009,7 +988,6 @@ func Exchangedata(path1 string, path2 string, options int) (err error) { func libc_exchangedata_trampoline() -//go:linkname libc_exchangedata libc_exchangedata //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1021,7 +999,6 @@ func Exit(code int) { func libc_exit_trampoline() -//go:linkname libc_exit libc_exit //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1041,7 +1018,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_faccessat_trampoline() -//go:linkname libc_faccessat libc_faccessat //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1056,7 +1032,6 @@ func Fchdir(fd int) (err error) { func libc_fchdir_trampoline() -//go:linkname libc_fchdir libc_fchdir //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1071,7 +1046,6 @@ func Fchflags(fd int, flags int) (err error) { func libc_fchflags_trampoline() -//go:linkname libc_fchflags libc_fchflags //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1086,7 +1060,6 @@ func Fchmod(fd int, mode uint32) (err error) { func libc_fchmod_trampoline() -//go:linkname libc_fchmod libc_fchmod //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1106,7 +1079,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_fchmodat_trampoline() -//go:linkname libc_fchmodat libc_fchmodat //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1121,7 +1093,6 @@ func Fchown(fd int, uid int, gid int) (err error) { func libc_fchown_trampoline() -//go:linkname libc_fchown libc_fchown //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1141,11 +1112,29 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func libc_fchownat_trampoline() -//go:linkname libc_fchownat libc_fchownat //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_fclonefileat_trampoline() + +//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -1156,7 +1145,6 @@ func Flock(fd int, how int) (err error) { func libc_flock_trampoline() -//go:linkname libc_flock libc_flock //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1172,7 +1160,6 @@ func Fpathconf(fd int, name int) (val int, err error) { func libc_fpathconf_trampoline() -//go:linkname libc_fpathconf libc_fpathconf //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1187,7 +1174,6 @@ func Fsync(fd int) (err error) { func libc_fsync_trampoline() -//go:linkname libc_fsync libc_fsync //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1202,11 +1188,31 @@ func Ftruncate(fd int, length int64) (err error) { func libc_ftruncate_trampoline() -//go:linkname libc_ftruncate libc_ftruncate //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_getcwd_trampoline() + +//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdtablesize() (size int) { r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0) size = int(r0) @@ -1215,7 +1221,6 @@ func Getdtablesize() (size int) { func libc_getdtablesize_trampoline() -//go:linkname libc_getdtablesize libc_getdtablesize //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1228,7 +1233,6 @@ func Getegid() (egid int) { func libc_getegid_trampoline() -//go:linkname libc_getegid libc_getegid //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1241,7 +1245,6 @@ func Geteuid() (uid int) { func libc_geteuid_trampoline() -//go:linkname libc_geteuid libc_geteuid //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1254,7 +1257,6 @@ func Getgid() (gid int) { func libc_getgid_trampoline() -//go:linkname libc_getgid libc_getgid //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1270,7 +1272,6 @@ func Getpgid(pid int) (pgid int, err error) { func libc_getpgid_trampoline() -//go:linkname libc_getpgid libc_getpgid //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1283,7 +1284,6 @@ func Getpgrp() (pgrp int) { func libc_getpgrp_trampoline() -//go:linkname libc_getpgrp libc_getpgrp //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1296,7 +1296,6 @@ func Getpid() (pid int) { func libc_getpid_trampoline() -//go:linkname libc_getpid libc_getpid //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1309,7 +1308,6 @@ func Getppid() (ppid int) { func libc_getppid_trampoline() -//go:linkname libc_getppid libc_getppid //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1325,7 +1323,6 @@ func Getpriority(which int, who int) (prio int, err error) { func libc_getpriority_trampoline() -//go:linkname libc_getpriority libc_getpriority //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1340,7 +1337,6 @@ func Getrlimit(which int, lim *Rlimit) (err error) { func libc_getrlimit_trampoline() -//go:linkname libc_getrlimit libc_getrlimit //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1355,7 +1351,6 @@ func Getrusage(who int, rusage *Rusage) (err error) { func libc_getrusage_trampoline() -//go:linkname libc_getrusage libc_getrusage //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1371,11 +1366,24 @@ func Getsid(pid int) (sid int, err error) { func libc_getsid_trampoline() -//go:linkname libc_getsid libc_getsid //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Gettimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_gettimeofday_trampoline() + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getuid() (uid int) { r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0) uid = int(r0) @@ -1384,7 +1392,6 @@ func Getuid() (uid int) { func libc_getuid_trampoline() -//go:linkname libc_getuid libc_getuid //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1397,7 +1404,6 @@ func Issetugid() (tainted bool) { func libc_issetugid_trampoline() -//go:linkname libc_issetugid libc_issetugid //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1413,7 +1419,6 @@ func Kqueue() (fd int, err error) { func libc_kqueue_trampoline() -//go:linkname libc_kqueue libc_kqueue //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1433,7 +1438,6 @@ func Lchown(path string, uid int, gid int) (err error) { func libc_lchown_trampoline() -//go:linkname libc_lchown libc_lchown //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1458,7 +1462,6 @@ func Link(path string, link string) (err error) { func libc_link_trampoline() -//go:linkname libc_link libc_link //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1483,7 +1486,6 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er func libc_linkat_trampoline() -//go:linkname libc_linkat libc_linkat //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1498,7 +1500,6 @@ func Listen(s int, backlog int) (err error) { func libc_listen_trampoline() -//go:linkname libc_listen libc_listen //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1518,7 +1519,6 @@ func Mkdir(path string, mode uint32) (err error) { func libc_mkdir_trampoline() -//go:linkname libc_mkdir libc_mkdir //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1538,7 +1538,6 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { func libc_mkdirat_trampoline() -//go:linkname libc_mkdirat libc_mkdirat //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1558,7 +1557,6 @@ func Mkfifo(path string, mode uint32) (err error) { func libc_mkfifo_trampoline() -//go:linkname libc_mkfifo libc_mkfifo //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1578,7 +1576,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { func libc_mknod_trampoline() -//go:linkname libc_mknod libc_mknod //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1599,7 +1596,6 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { func libc_open_trampoline() -//go:linkname libc_open libc_open //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1620,7 +1616,6 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { func libc_openat_trampoline() -//go:linkname libc_openat libc_openat //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1641,7 +1636,6 @@ func Pathconf(path string, name int) (val int, err error) { func libc_pathconf_trampoline() -//go:linkname libc_pathconf libc_pathconf //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1663,7 +1657,6 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) { func libc_pread_trampoline() -//go:linkname libc_pread libc_pread //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1685,7 +1678,6 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { func libc_pwrite_trampoline() -//go:linkname libc_pwrite libc_pwrite //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1707,7 +1699,6 @@ func read(fd int, p []byte) (n int, err error) { func libc_read_trampoline() -//go:linkname libc_read libc_read //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1734,7 +1725,6 @@ func Readlink(path string, buf []byte) (n int, err error) { func libc_readlink_trampoline() -//go:linkname libc_readlink libc_readlink //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1761,7 +1751,6 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { func libc_readlinkat_trampoline() -//go:linkname libc_readlinkat libc_readlinkat //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1786,7 +1775,6 @@ func Rename(from string, to string) (err error) { func libc_rename_trampoline() -//go:linkname libc_rename libc_rename //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1811,7 +1799,6 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) { func libc_renameat_trampoline() -//go:linkname libc_renameat libc_renameat //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1831,7 +1818,6 @@ func Revoke(path string) (err error) { func libc_revoke_trampoline() -//go:linkname libc_revoke libc_revoke //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1851,7 +1837,6 @@ func Rmdir(path string) (err error) { func libc_rmdir_trampoline() -//go:linkname libc_rmdir libc_rmdir //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1867,7 +1852,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func libc_lseek_trampoline() -//go:linkname libc_lseek libc_lseek //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1883,7 +1867,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err func libc_select_trampoline() -//go:linkname libc_select libc_select //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1898,7 +1881,6 @@ func Setegid(egid int) (err error) { func libc_setegid_trampoline() -//go:linkname libc_setegid libc_setegid //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1913,7 +1895,6 @@ func Seteuid(euid int) (err error) { func libc_seteuid_trampoline() -//go:linkname libc_seteuid libc_seteuid //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1928,7 +1909,6 @@ func Setgid(gid int) (err error) { func libc_setgid_trampoline() -//go:linkname libc_setgid libc_setgid //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1948,7 +1928,6 @@ func Setlogin(name string) (err error) { func libc_setlogin_trampoline() -//go:linkname libc_setlogin libc_setlogin //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1963,7 +1942,6 @@ func Setpgid(pid int, pgid int) (err error) { func libc_setpgid_trampoline() -//go:linkname libc_setpgid libc_setpgid //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1978,7 +1956,6 @@ func Setpriority(which int, who int, prio int) (err error) { func libc_setpriority_trampoline() -//go:linkname libc_setpriority libc_setpriority //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1993,7 +1970,6 @@ func Setprivexec(flag int) (err error) { func libc_setprivexec_trampoline() -//go:linkname libc_setprivexec libc_setprivexec //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2008,7 +1984,6 @@ func Setregid(rgid int, egid int) (err error) { func libc_setregid_trampoline() -//go:linkname libc_setregid libc_setregid //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2023,7 +1998,6 @@ func Setreuid(ruid int, euid int) (err error) { func libc_setreuid_trampoline() -//go:linkname libc_setreuid libc_setreuid //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2038,7 +2012,6 @@ func Setrlimit(which int, lim *Rlimit) (err error) { func libc_setrlimit_trampoline() -//go:linkname libc_setrlimit libc_setrlimit //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2054,7 +2027,6 @@ func Setsid() (pid int, err error) { func libc_setsid_trampoline() -//go:linkname libc_setsid libc_setsid //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2069,7 +2041,6 @@ func Settimeofday(tp *Timeval) (err error) { func libc_settimeofday_trampoline() -//go:linkname libc_settimeofday libc_settimeofday //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2084,7 +2055,6 @@ func Setuid(uid int) (err error) { func libc_setuid_trampoline() -//go:linkname libc_setuid libc_setuid //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2109,7 +2079,6 @@ func Symlink(path string, link string) (err error) { func libc_symlink_trampoline() -//go:linkname libc_symlink libc_symlink //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2134,7 +2103,6 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { func libc_symlinkat_trampoline() -//go:linkname libc_symlinkat libc_symlinkat //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2149,7 +2117,6 @@ func Sync() (err error) { func libc_sync_trampoline() -//go:linkname libc_sync libc_sync //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2169,7 +2136,6 @@ func Truncate(path string, length int64) (err error) { func libc_truncate_trampoline() -//go:linkname libc_truncate libc_truncate //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2182,7 +2148,6 @@ func Umask(newmask int) (oldmask int) { func libc_umask_trampoline() -//go:linkname libc_umask libc_umask //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2202,7 +2167,6 @@ func Undelete(path string) (err error) { func libc_undelete_trampoline() -//go:linkname libc_undelete libc_undelete //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2222,7 +2186,6 @@ func Unlink(path string) (err error) { func libc_unlink_trampoline() -//go:linkname libc_unlink libc_unlink //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2242,7 +2205,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { func libc_unlinkat_trampoline() -//go:linkname libc_unlinkat libc_unlinkat //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2262,7 +2224,6 @@ func Unmount(path string, flags int) (err error) { func libc_unmount_trampoline() -//go:linkname libc_unmount libc_unmount //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2284,7 +2245,6 @@ func write(fd int, p []byte) (n int, err error) { func libc_write_trampoline() -//go:linkname libc_write libc_write //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2300,7 +2260,6 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( func libc_mmap_trampoline() -//go:linkname libc_mmap libc_mmap //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2315,7 +2274,6 @@ func munmap(addr uintptr, length uintptr) (err error) { func libc_munmap_trampoline() -//go:linkname libc_munmap libc_munmap //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2342,23 +2300,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { - r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int32(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_gettimeofday_trampoline() - -//go:linkname libc_gettimeofday libc_gettimeofday -//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2369,7 +2310,6 @@ func Fstat(fd int, stat *Stat_t) (err error) { func libc_fstat_trampoline() -//go:linkname libc_fstat libc_fstat //go:cgo_import_dynamic libc_fstat fstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2389,7 +2329,6 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { func libc_fstatat_trampoline() -//go:linkname libc_fstatat libc_fstatat //go:cgo_import_dynamic libc_fstatat fstatat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2404,7 +2343,6 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) { func libc_fstatfs_trampoline() -//go:linkname libc_fstatfs libc_fstatfs //go:cgo_import_dynamic libc_fstatfs fstatfs "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2420,7 +2358,6 @@ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { func libc_getfsstat_trampoline() -//go:linkname libc_getfsstat libc_getfsstat //go:cgo_import_dynamic libc_getfsstat getfsstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2440,7 +2377,6 @@ func Lstat(path string, stat *Stat_t) (err error) { func libc_lstat_trampoline() -//go:linkname libc_lstat libc_lstat //go:cgo_import_dynamic libc_lstat lstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2460,7 +2396,6 @@ func Stat(path string, stat *Stat_t) (err error) { func libc_stat_trampoline() -//go:linkname libc_stat libc_stat //go:cgo_import_dynamic libc_stat stat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2480,5 +2415,4 @@ func Statfs(path string, stat *Statfs_t) (err error) { func libc_statfs_trampoline() -//go:linkname libc_statfs libc_statfs //go:cgo_import_dynamic libc_statfs statfs "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s index b67f518fa3..5eec5f1d95 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s @@ -60,8 +60,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) -TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 - JMP libc_getattrlist(SB) TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0 @@ -110,6 +108,10 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 JMP libc_close(SB) +TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefile(SB) +TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefileat(SB) TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 JMP libc_dup(SB) TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0 @@ -132,6 +134,8 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) +TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_fclonefileat(SB) TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0 JMP libc_flock(SB) TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0 @@ -140,6 +144,8 @@ TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) +TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0 @@ -164,6 +170,8 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) +TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0 @@ -264,8 +272,6 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) -TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 - JMP libc_gettimeofday(SB) TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go index d64e6c806f..870eb37abf 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go @@ -24,7 +24,6 @@ func closedir(dir uintptr) (err error) { func libc_closedir_trampoline() -//go:linkname libc_closedir libc_closedir //go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -37,5 +36,4 @@ func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) { func libc_readdir_r_trampoline() -//go:linkname libc_readdir_r libc_readdir_r //go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index a8709f72dd..23be592a9f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -25,7 +25,6 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { func libc_getgroups_trampoline() -//go:linkname libc_getgroups libc_getgroups //go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -40,7 +39,6 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { func libc_setgroups_trampoline() -//go:linkname libc_setgroups libc_setgroups //go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -56,7 +54,6 @@ func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err func libc_wait4_trampoline() -//go:linkname libc_wait4 libc_wait4 //go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -72,7 +69,6 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { func libc_accept_trampoline() -//go:linkname libc_accept libc_accept //go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -87,7 +83,6 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_bind_trampoline() -//go:linkname libc_bind libc_bind //go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -102,7 +97,6 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func libc_connect_trampoline() -//go:linkname libc_connect libc_connect //go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -118,7 +112,6 @@ func socket(domain int, typ int, proto int) (fd int, err error) { func libc_socket_trampoline() -//go:linkname libc_socket libc_socket //go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -133,7 +126,6 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen func libc_getsockopt_trampoline() -//go:linkname libc_getsockopt libc_getsockopt //go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -148,7 +140,6 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) func libc_setsockopt_trampoline() -//go:linkname libc_setsockopt libc_setsockopt //go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -163,7 +154,6 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getpeername_trampoline() -//go:linkname libc_getpeername libc_getpeername //go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -178,7 +168,6 @@ func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func libc_getsockname_trampoline() -//go:linkname libc_getsockname libc_getsockname //go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -193,7 +182,6 @@ func Shutdown(s int, how int) (err error) { func libc_shutdown_trampoline() -//go:linkname libc_shutdown libc_shutdown //go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -208,7 +196,6 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { func libc_socketpair_trampoline() -//go:linkname libc_socketpair libc_socketpair //go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -230,7 +217,6 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl func libc_recvfrom_trampoline() -//go:linkname libc_recvfrom libc_recvfrom //go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -251,7 +237,6 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( func libc_sendto_trampoline() -//go:linkname libc_sendto libc_sendto //go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -267,7 +252,6 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_recvmsg_trampoline() -//go:linkname libc_recvmsg libc_recvmsg //go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -283,7 +267,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { func libc_sendmsg_trampoline() -//go:linkname libc_sendmsg libc_sendmsg //go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -299,7 +282,6 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne func libc_kevent_trampoline() -//go:linkname libc_kevent libc_kevent //go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -319,7 +301,6 @@ func utimes(path string, timeval *[2]Timeval) (err error) { func libc_utimes_trampoline() -//go:linkname libc_utimes libc_utimes //go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -334,7 +315,6 @@ func futimes(fd int, timeval *[2]Timeval) (err error) { func libc_futimes_trampoline() -//go:linkname libc_futimes libc_futimes //go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -350,7 +330,6 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { func libc_poll_trampoline() -//go:linkname libc_poll libc_poll //go:cgo_import_dynamic libc_poll poll "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -371,7 +350,6 @@ func Madvise(b []byte, behav int) (err error) { func libc_madvise_trampoline() -//go:linkname libc_madvise libc_madvise //go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -392,7 +370,6 @@ func Mlock(b []byte) (err error) { func libc_mlock_trampoline() -//go:linkname libc_mlock libc_mlock //go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -407,7 +384,6 @@ func Mlockall(flags int) (err error) { func libc_mlockall_trampoline() -//go:linkname libc_mlockall libc_mlockall //go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -428,7 +404,6 @@ func Mprotect(b []byte, prot int) (err error) { func libc_mprotect_trampoline() -//go:linkname libc_mprotect libc_mprotect //go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -449,7 +424,6 @@ func Msync(b []byte, flags int) (err error) { func libc_msync_trampoline() -//go:linkname libc_msync libc_msync //go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -470,7 +444,6 @@ func Munlock(b []byte) (err error) { func libc_munlock_trampoline() -//go:linkname libc_munlock libc_munlock //go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -485,26 +458,10 @@ func Munlockall() (err error) { func libc_munlockall_trampoline() -//go:linkname libc_munlockall libc_munlockall //go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_getattrlist_trampoline() - -//go:linkname libc_getattrlist libc_getattrlist -//go:cgo_import_dynamic libc_getattrlist getattrlist "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func pipe() (r int, w int, err error) { r0, r1, e1 := syscall_rawSyscall(funcPC(libc_pipe_trampoline), 0, 0, 0) r = int(r0) @@ -517,7 +474,6 @@ func pipe() (r int, w int, err error) { func libc_pipe_trampoline() -//go:linkname libc_pipe libc_pipe //go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -543,7 +499,6 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o func libc_getxattr_trampoline() -//go:linkname libc_getxattr libc_getxattr //go:cgo_import_dynamic libc_getxattr getxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -564,7 +519,6 @@ func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, optio func libc_fgetxattr_trampoline() -//go:linkname libc_fgetxattr libc_fgetxattr //go:cgo_import_dynamic libc_fgetxattr fgetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -589,7 +543,6 @@ func setxattr(path string, attr string, data *byte, size int, position uint32, o func libc_setxattr_trampoline() -//go:linkname libc_setxattr libc_setxattr //go:cgo_import_dynamic libc_setxattr setxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -609,7 +562,6 @@ func fsetxattr(fd int, attr string, data *byte, size int, position uint32, optio func libc_fsetxattr_trampoline() -//go:linkname libc_fsetxattr libc_fsetxattr //go:cgo_import_dynamic libc_fsetxattr fsetxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -634,7 +586,6 @@ func removexattr(path string, attr string, options int) (err error) { func libc_removexattr_trampoline() -//go:linkname libc_removexattr libc_removexattr //go:cgo_import_dynamic libc_removexattr removexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -654,7 +605,6 @@ func fremovexattr(fd int, attr string, options int) (err error) { func libc_fremovexattr_trampoline() -//go:linkname libc_fremovexattr libc_fremovexattr //go:cgo_import_dynamic libc_fremovexattr fremovexattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -675,7 +625,6 @@ func listxattr(path string, dest *byte, size int, options int) (sz int, err erro func libc_listxattr_trampoline() -//go:linkname libc_listxattr libc_listxattr //go:cgo_import_dynamic libc_listxattr listxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -691,7 +640,6 @@ func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { func libc_flistxattr_trampoline() -//go:linkname libc_flistxattr libc_flistxattr //go:cgo_import_dynamic libc_flistxattr flistxattr "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -706,7 +654,6 @@ func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp func libc_setattrlist_trampoline() -//go:linkname libc_setattrlist libc_setattrlist //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -722,7 +669,6 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { func libc_fcntl_trampoline() -//go:linkname libc_fcntl libc_fcntl //go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -737,7 +683,6 @@ func kill(pid int, signum int, posix int) (err error) { func libc_kill_trampoline() -//go:linkname libc_kill libc_kill //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -752,7 +697,6 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { func libc_ioctl_trampoline() -//go:linkname libc_ioctl libc_ioctl //go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -773,7 +717,6 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) func libc_sysctl_trampoline() -//go:linkname libc_sysctl libc_sysctl //go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -788,7 +731,6 @@ func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer func libc_sendfile_trampoline() -//go:linkname libc_sendfile libc_sendfile //go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -808,7 +750,6 @@ func Access(path string, mode uint32) (err error) { func libc_access_trampoline() -//go:linkname libc_access libc_access //go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -823,7 +764,6 @@ func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { func libc_adjtime_trampoline() -//go:linkname libc_adjtime libc_adjtime //go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -843,7 +783,6 @@ func Chdir(path string) (err error) { func libc_chdir_trampoline() -//go:linkname libc_chdir libc_chdir //go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -863,7 +802,6 @@ func Chflags(path string, flags int) (err error) { func libc_chflags_trampoline() -//go:linkname libc_chflags libc_chflags //go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -883,7 +821,6 @@ func Chmod(path string, mode uint32) (err error) { func libc_chmod_trampoline() -//go:linkname libc_chmod libc_chmod //go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -903,7 +840,6 @@ func Chown(path string, uid int, gid int) (err error) { func libc_chown_trampoline() -//go:linkname libc_chown libc_chown //go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -923,7 +859,6 @@ func Chroot(path string) (err error) { func libc_chroot_trampoline() -//go:linkname libc_chroot libc_chroot //go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -938,7 +873,6 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { func libc_clock_gettime_trampoline() -//go:linkname libc_clock_gettime libc_clock_gettime //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -953,11 +887,58 @@ func Close(fd int) (err error) { func libc_close_trampoline() -//go:linkname libc_close libc_close //go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Clonefile(src string, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall(funcPC(libc_clonefile_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefile_trampoline() + +//go:cgo_import_dynamic libc_clonefile clonefile "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(src) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_clonefileat_trampoline), uintptr(srcDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clonefileat_trampoline() + +//go:cgo_import_dynamic libc_clonefileat clonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup(fd int) (nfd int, err error) { r0, _, e1 := syscall_syscall(funcPC(libc_dup_trampoline), uintptr(fd), 0, 0) nfd = int(r0) @@ -969,7 +950,6 @@ func Dup(fd int) (nfd int, err error) { func libc_dup_trampoline() -//go:linkname libc_dup libc_dup //go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -984,7 +964,6 @@ func Dup2(from int, to int) (err error) { func libc_dup2_trampoline() -//go:linkname libc_dup2 libc_dup2 //go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1009,7 +988,6 @@ func Exchangedata(path1 string, path2 string, options int) (err error) { func libc_exchangedata_trampoline() -//go:linkname libc_exchangedata libc_exchangedata //go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1021,7 +999,6 @@ func Exit(code int) { func libc_exit_trampoline() -//go:linkname libc_exit libc_exit //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1041,7 +1018,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_faccessat_trampoline() -//go:linkname libc_faccessat libc_faccessat //go:cgo_import_dynamic libc_faccessat faccessat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1056,7 +1032,6 @@ func Fchdir(fd int) (err error) { func libc_fchdir_trampoline() -//go:linkname libc_fchdir libc_fchdir //go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1071,7 +1046,6 @@ func Fchflags(fd int, flags int) (err error) { func libc_fchflags_trampoline() -//go:linkname libc_fchflags libc_fchflags //go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1086,7 +1060,6 @@ func Fchmod(fd int, mode uint32) (err error) { func libc_fchmod_trampoline() -//go:linkname libc_fchmod libc_fchmod //go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1106,7 +1079,6 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { func libc_fchmodat_trampoline() -//go:linkname libc_fchmodat libc_fchmodat //go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1121,7 +1093,6 @@ func Fchown(fd int, uid int, gid int) (err error) { func libc_fchown_trampoline() -//go:linkname libc_fchown libc_fchown //go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1141,11 +1112,29 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func libc_fchownat_trampoline() -//go:linkname libc_fchownat libc_fchownat //go:cgo_import_dynamic libc_fchownat fchownat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(dst) + if err != nil { + return + } + _, _, e1 := syscall_syscall6(funcPC(libc_fclonefileat_trampoline), uintptr(srcDirfd), uintptr(dstDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_fclonefileat_trampoline() + +//go:cgo_import_dynamic libc_fclonefileat fclonefileat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Flock(fd int, how int) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_flock_trampoline), uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -1156,7 +1145,6 @@ func Flock(fd int, how int) (err error) { func libc_flock_trampoline() -//go:linkname libc_flock libc_flock //go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1172,7 +1160,6 @@ func Fpathconf(fd int, name int) (val int, err error) { func libc_fpathconf_trampoline() -//go:linkname libc_fpathconf libc_fpathconf //go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1187,7 +1174,6 @@ func Fsync(fd int) (err error) { func libc_fsync_trampoline() -//go:linkname libc_fsync libc_fsync //go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1202,11 +1188,31 @@ func Ftruncate(fd int, length int64) (err error) { func libc_ftruncate_trampoline() -//go:linkname libc_ftruncate libc_ftruncate //go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(funcPC(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_getcwd_trampoline() + +//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdtablesize() (size int) { r0, _, _ := syscall_syscall(funcPC(libc_getdtablesize_trampoline), 0, 0, 0) size = int(r0) @@ -1215,7 +1221,6 @@ func Getdtablesize() (size int) { func libc_getdtablesize_trampoline() -//go:linkname libc_getdtablesize libc_getdtablesize //go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1228,7 +1233,6 @@ func Getegid() (egid int) { func libc_getegid_trampoline() -//go:linkname libc_getegid libc_getegid //go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1241,7 +1245,6 @@ func Geteuid() (uid int) { func libc_geteuid_trampoline() -//go:linkname libc_geteuid libc_geteuid //go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1254,7 +1257,6 @@ func Getgid() (gid int) { func libc_getgid_trampoline() -//go:linkname libc_getgid libc_getgid //go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1270,7 +1272,6 @@ func Getpgid(pid int) (pgid int, err error) { func libc_getpgid_trampoline() -//go:linkname libc_getpgid libc_getpgid //go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1283,7 +1284,6 @@ func Getpgrp() (pgrp int) { func libc_getpgrp_trampoline() -//go:linkname libc_getpgrp libc_getpgrp //go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1296,7 +1296,6 @@ func Getpid() (pid int) { func libc_getpid_trampoline() -//go:linkname libc_getpid libc_getpid //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1309,7 +1308,6 @@ func Getppid() (ppid int) { func libc_getppid_trampoline() -//go:linkname libc_getppid libc_getppid //go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1325,7 +1323,6 @@ func Getpriority(which int, who int) (prio int, err error) { func libc_getpriority_trampoline() -//go:linkname libc_getpriority libc_getpriority //go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1340,7 +1337,6 @@ func Getrlimit(which int, lim *Rlimit) (err error) { func libc_getrlimit_trampoline() -//go:linkname libc_getrlimit libc_getrlimit //go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1355,7 +1351,6 @@ func Getrusage(who int, rusage *Rusage) (err error) { func libc_getrusage_trampoline() -//go:linkname libc_getrusage libc_getrusage //go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1371,11 +1366,24 @@ func Getsid(pid int) (sid int, err error) { func libc_getsid_trampoline() -//go:linkname libc_getsid libc_getsid //go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Gettimeofday(tp *Timeval) (err error) { + _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_gettimeofday_trampoline() + +//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getuid() (uid int) { r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0) uid = int(r0) @@ -1384,7 +1392,6 @@ func Getuid() (uid int) { func libc_getuid_trampoline() -//go:linkname libc_getuid libc_getuid //go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1397,7 +1404,6 @@ func Issetugid() (tainted bool) { func libc_issetugid_trampoline() -//go:linkname libc_issetugid libc_issetugid //go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1413,7 +1419,6 @@ func Kqueue() (fd int, err error) { func libc_kqueue_trampoline() -//go:linkname libc_kqueue libc_kqueue //go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1433,7 +1438,6 @@ func Lchown(path string, uid int, gid int) (err error) { func libc_lchown_trampoline() -//go:linkname libc_lchown libc_lchown //go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1458,7 +1462,6 @@ func Link(path string, link string) (err error) { func libc_link_trampoline() -//go:linkname libc_link libc_link //go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1483,7 +1486,6 @@ func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err er func libc_linkat_trampoline() -//go:linkname libc_linkat libc_linkat //go:cgo_import_dynamic libc_linkat linkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1498,7 +1500,6 @@ func Listen(s int, backlog int) (err error) { func libc_listen_trampoline() -//go:linkname libc_listen libc_listen //go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1518,7 +1519,6 @@ func Mkdir(path string, mode uint32) (err error) { func libc_mkdir_trampoline() -//go:linkname libc_mkdir libc_mkdir //go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1538,7 +1538,6 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { func libc_mkdirat_trampoline() -//go:linkname libc_mkdirat libc_mkdirat //go:cgo_import_dynamic libc_mkdirat mkdirat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1558,7 +1557,6 @@ func Mkfifo(path string, mode uint32) (err error) { func libc_mkfifo_trampoline() -//go:linkname libc_mkfifo libc_mkfifo //go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1578,7 +1576,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { func libc_mknod_trampoline() -//go:linkname libc_mknod libc_mknod //go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1599,7 +1596,6 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { func libc_open_trampoline() -//go:linkname libc_open libc_open //go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1620,7 +1616,6 @@ func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { func libc_openat_trampoline() -//go:linkname libc_openat libc_openat //go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1641,7 +1636,6 @@ func Pathconf(path string, name int) (val int, err error) { func libc_pathconf_trampoline() -//go:linkname libc_pathconf libc_pathconf //go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1663,7 +1657,6 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) { func libc_pread_trampoline() -//go:linkname libc_pread libc_pread //go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1685,7 +1678,6 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { func libc_pwrite_trampoline() -//go:linkname libc_pwrite libc_pwrite //go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1707,7 +1699,6 @@ func read(fd int, p []byte) (n int, err error) { func libc_read_trampoline() -//go:linkname libc_read libc_read //go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1734,7 +1725,6 @@ func Readlink(path string, buf []byte) (n int, err error) { func libc_readlink_trampoline() -//go:linkname libc_readlink libc_readlink //go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1761,7 +1751,6 @@ func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { func libc_readlinkat_trampoline() -//go:linkname libc_readlinkat libc_readlinkat //go:cgo_import_dynamic libc_readlinkat readlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1786,7 +1775,6 @@ func Rename(from string, to string) (err error) { func libc_rename_trampoline() -//go:linkname libc_rename libc_rename //go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1811,7 +1799,6 @@ func Renameat(fromfd int, from string, tofd int, to string) (err error) { func libc_renameat_trampoline() -//go:linkname libc_renameat libc_renameat //go:cgo_import_dynamic libc_renameat renameat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1831,7 +1818,6 @@ func Revoke(path string) (err error) { func libc_revoke_trampoline() -//go:linkname libc_revoke libc_revoke //go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1851,7 +1837,6 @@ func Rmdir(path string) (err error) { func libc_rmdir_trampoline() -//go:linkname libc_rmdir libc_rmdir //go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1867,7 +1852,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func libc_lseek_trampoline() -//go:linkname libc_lseek libc_lseek //go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1883,7 +1867,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err func libc_select_trampoline() -//go:linkname libc_select libc_select //go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1898,7 +1881,6 @@ func Setegid(egid int) (err error) { func libc_setegid_trampoline() -//go:linkname libc_setegid libc_setegid //go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1913,7 +1895,6 @@ func Seteuid(euid int) (err error) { func libc_seteuid_trampoline() -//go:linkname libc_seteuid libc_seteuid //go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1928,7 +1909,6 @@ func Setgid(gid int) (err error) { func libc_setgid_trampoline() -//go:linkname libc_setgid libc_setgid //go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1948,7 +1928,6 @@ func Setlogin(name string) (err error) { func libc_setlogin_trampoline() -//go:linkname libc_setlogin libc_setlogin //go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1963,7 +1942,6 @@ func Setpgid(pid int, pgid int) (err error) { func libc_setpgid_trampoline() -//go:linkname libc_setpgid libc_setpgid //go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1978,7 +1956,6 @@ func Setpriority(which int, who int, prio int) (err error) { func libc_setpriority_trampoline() -//go:linkname libc_setpriority libc_setpriority //go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1993,7 +1970,6 @@ func Setprivexec(flag int) (err error) { func libc_setprivexec_trampoline() -//go:linkname libc_setprivexec libc_setprivexec //go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2008,7 +1984,6 @@ func Setregid(rgid int, egid int) (err error) { func libc_setregid_trampoline() -//go:linkname libc_setregid libc_setregid //go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2023,7 +1998,6 @@ func Setreuid(ruid int, euid int) (err error) { func libc_setreuid_trampoline() -//go:linkname libc_setreuid libc_setreuid //go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2038,7 +2012,6 @@ func Setrlimit(which int, lim *Rlimit) (err error) { func libc_setrlimit_trampoline() -//go:linkname libc_setrlimit libc_setrlimit //go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2054,7 +2027,6 @@ func Setsid() (pid int, err error) { func libc_setsid_trampoline() -//go:linkname libc_setsid libc_setsid //go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2069,7 +2041,6 @@ func Settimeofday(tp *Timeval) (err error) { func libc_settimeofday_trampoline() -//go:linkname libc_settimeofday libc_settimeofday //go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2084,7 +2055,6 @@ func Setuid(uid int) (err error) { func libc_setuid_trampoline() -//go:linkname libc_setuid libc_setuid //go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2109,7 +2079,6 @@ func Symlink(path string, link string) (err error) { func libc_symlink_trampoline() -//go:linkname libc_symlink libc_symlink //go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2134,7 +2103,6 @@ func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { func libc_symlinkat_trampoline() -//go:linkname libc_symlinkat libc_symlinkat //go:cgo_import_dynamic libc_symlinkat symlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2149,7 +2117,6 @@ func Sync() (err error) { func libc_sync_trampoline() -//go:linkname libc_sync libc_sync //go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2169,7 +2136,6 @@ func Truncate(path string, length int64) (err error) { func libc_truncate_trampoline() -//go:linkname libc_truncate libc_truncate //go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2182,7 +2148,6 @@ func Umask(newmask int) (oldmask int) { func libc_umask_trampoline() -//go:linkname libc_umask libc_umask //go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2202,7 +2167,6 @@ func Undelete(path string) (err error) { func libc_undelete_trampoline() -//go:linkname libc_undelete libc_undelete //go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2222,7 +2186,6 @@ func Unlink(path string) (err error) { func libc_unlink_trampoline() -//go:linkname libc_unlink libc_unlink //go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2242,7 +2205,6 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { func libc_unlinkat_trampoline() -//go:linkname libc_unlinkat libc_unlinkat //go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2262,7 +2224,6 @@ func Unmount(path string, flags int) (err error) { func libc_unmount_trampoline() -//go:linkname libc_unmount libc_unmount //go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2284,7 +2245,6 @@ func write(fd int, p []byte) (n int, err error) { func libc_write_trampoline() -//go:linkname libc_write libc_write //go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2300,7 +2260,6 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( func libc_mmap_trampoline() -//go:linkname libc_mmap libc_mmap //go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2315,7 +2274,6 @@ func munmap(addr uintptr, length uintptr) (err error) { func libc_munmap_trampoline() -//go:linkname libc_munmap libc_munmap //go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2342,23 +2300,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { - r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int64(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -func libc_gettimeofday_trampoline() - -//go:linkname libc_gettimeofday libc_gettimeofday -//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2369,7 +2310,6 @@ func Fstat(fd int, stat *Stat_t) (err error) { func libc_fstat_trampoline() -//go:linkname libc_fstat libc_fstat //go:cgo_import_dynamic libc_fstat fstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2389,7 +2329,6 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { func libc_fstatat_trampoline() -//go:linkname libc_fstatat libc_fstatat //go:cgo_import_dynamic libc_fstatat fstatat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2404,7 +2343,6 @@ func Fstatfs(fd int, stat *Statfs_t) (err error) { func libc_fstatfs_trampoline() -//go:linkname libc_fstatfs libc_fstatfs //go:cgo_import_dynamic libc_fstatfs fstatfs "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2420,7 +2358,6 @@ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { func libc_getfsstat_trampoline() -//go:linkname libc_getfsstat libc_getfsstat //go:cgo_import_dynamic libc_getfsstat getfsstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2440,11 +2377,24 @@ func Lstat(path string, stat *Stat_t) (err error) { func libc_lstat_trampoline() -//go:linkname libc_lstat libc_lstat //go:cgo_import_dynamic libc_lstat lstat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_ptrace_trampoline() + +//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Stat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -2460,7 +2410,6 @@ func Stat(path string, stat *Stat_t) (err error) { func libc_stat_trampoline() -//go:linkname libc_stat libc_stat //go:cgo_import_dynamic libc_stat stat "/usr/lib/libSystem.B.dylib" // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -2480,5 +2429,4 @@ func Statfs(path string, stat *Statfs_t) (err error) { func libc_statfs_trampoline() -//go:linkname libc_statfs libc_statfs //go:cgo_import_dynamic libc_statfs statfs "/usr/lib/libSystem.B.dylib" diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 40cce1bb28..53c402bf68 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -60,8 +60,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) -TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 - JMP libc_getattrlist(SB) TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) TEXT ·libc_getxattr_trampoline(SB),NOSPLIT,$0-0 @@ -110,6 +108,10 @@ TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 JMP libc_close(SB) +TEXT ·libc_clonefile_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefile(SB) +TEXT ·libc_clonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clonefileat(SB) TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 JMP libc_dup(SB) TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0 @@ -132,6 +134,8 @@ TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) TEXT ·libc_fchownat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) +TEXT ·libc_fclonefileat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_fclonefileat(SB) TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0 JMP libc_flock(SB) TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0 @@ -140,6 +144,8 @@ TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) +TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0 + JMP libc_getcwd(SB) TEXT ·libc_getdtablesize_trampoline(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0 @@ -164,6 +170,8 @@ TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) +TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 + JMP libc_gettimeofday(SB) TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0 @@ -264,8 +272,6 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) -TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 - JMP libc_gettimeofday(SB) TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0 @@ -276,6 +282,8 @@ TEXT ·libc_getfsstat_trampoline(SB),NOSPLIT,$0-0 JMP libc_getfsstat(SB) TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) +TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0 + JMP libc_ptrace(SB) TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0 JMP libc_stat(SB) TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index fe1fdd78d7..1aaccd3615 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -214,22 +214,6 @@ func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, ne // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { - var _p0 unsafe.Pointer - if len(mib) > 0 { - _p0 = unsafe.Pointer(&mib[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimes(path string, timeval *[2]Timeval) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -378,6 +362,16 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func extpread(fd int, p []byte, flags int, offset int64) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -439,6 +433,22 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go index 92efa1da3c..d3af083f4e 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go @@ -13,17 +13,23 @@ import ( //go:cgo_import_dynamic libc_preadv preadv "libc.so" //go:cgo_import_dynamic libc_writev writev "libc.so" //go:cgo_import_dynamic libc_pwritev pwritev "libc.so" +//go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so" +//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" //go:linkname procreadv libc_readv //go:linkname procpreadv libc_preadv //go:linkname procwritev libc_writev //go:linkname procpwritev libc_pwritev +//go:linkname procaccept4 libc_accept4 +//go:linkname procpipe2 libc_pipe2 var ( procreadv, procpreadv, procwritev, - procpwritev syscallFunc + procpwritev, + procaccept4, + procpipe2 syscallFunc ) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -85,3 +91,24 @@ func pwritev(fd int, iovs []Iovec, off int64) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procaccept4)), 4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) + fd = int(r0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0) + if e1 != 0 { + err = e1 + } + return +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go index df217825f0..2fbbbe5a89 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -83,6 +83,22 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(open_how)), uintptr(size), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) n = int(r0) @@ -1821,6 +1837,21 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(pathname) @@ -1847,6 +1878,52 @@ func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) { + var _p0 unsafe.Pointer + if len(localIov) > 0 { + _p0 = unsafe.Pointer(&localIov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + var _p1 unsafe.Pointer + if len(remoteIov) > 0 { + _p1 = unsafe.Pointer(&remoteIov[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PROCESS_VM_READV, uintptr(pid), uintptr(_p0), uintptr(len(localIov)), uintptr(_p1), uintptr(len(remoteIov)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) { + var _p0 unsafe.Pointer + if len(localIov) > 0 { + _p0 = unsafe.Pointer(&localIov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + var _p1 unsafe.Pointer + if len(remoteIov) > 0 { + _p1 = unsafe.Pointer(&remoteIov[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PROCESS_VM_WRITEV, uintptr(pid), uintptr(_p0), uintptr(len(localIov)), uintptr(_p1), uintptr(len(remoteIov)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_11.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c3bb3a25d..ec6bd5bb73 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_11.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -1,7 +1,7 @@ -// go run mksyscall.go -tags darwin,arm64,!go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.1_11.go syscall_darwin_arm64.go +// go run mksyscall.go -openbsd -tags openbsd,mips64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_mips64.go // Code generated by the command above; see README.md. DO NOT EDIT. -// +build darwin,arm64,!go1.12 +// +build openbsd,mips64 package unix @@ -350,8 +350,8 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { err = errnoErr(e1) } @@ -360,154 +360,15 @@ func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func pipe() (r int, w int, err error) { - r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) - r = int(r0) - w = int(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(data)), uintptr(size), uintptr(position), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func removexattr(path string, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fremovexattr(fd int, attr string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(attr) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(options)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func listxattr(path string, dest *byte, size int, options int) (sz int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func flistxattr(fd int, dest *byte, size int, options int) (sz int, err error) { - r0, _, e1 := Syscall6(SYS_FLISTXATTR, uintptr(fd), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(options), 0, 0) - sz = int(r0) - if e1 != 0 { - err = errnoErr(e1) +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { - _, _, e1 := Syscall6(SYS_SETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) if e1 != 0 { err = errnoErr(e1) } @@ -516,19 +377,15 @@ func setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintp // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func fcntl(fd int, cmd int, arg int) (val int, err error) { - r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) - val = int(r0) - if e1 != 0 { - err = errnoErr(e1) +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func kill(pid int, signum int, posix int) (err error) { - _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix)) + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) if e1 != 0 { err = errnoErr(e1) } @@ -554,7 +411,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) if e1 != 0 { err = errnoErr(e1) } @@ -563,8 +420,9 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { - _, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) +func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + n = int(r0) if e1 != 0 { err = errnoErr(e1) } @@ -704,18 +562,8 @@ func Dup2(from int, to int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Exchangedata(path1 string, path2 string, options int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path1) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(path2) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) +func Dup3(from int, to int, flags int) (err error) { + _, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags)) if e1 != 0 { err = errnoErr(e1) } @@ -837,8 +685,8 @@ func Fpathconf(fd int, name int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Fsync(fd int) (err error) { - _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { err = errnoErr(e1) } @@ -847,8 +695,13 @@ func Fsync(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Ftruncate(fd int, length int64) (err error) { - _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -857,9 +710,31 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Getdtablesize() (size int) { - r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0) - size = int(r0) +func Fstatfs(fd int, stat *Statfs_t) (err error) { + _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length)) + if e1 != 0 { + err = errnoErr(e1) + } return } @@ -945,6 +820,17 @@ func Getrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getrtable() (rtable int, err error) { + r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { @@ -966,6 +852,16 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getuid() (uid int) { r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) uid = int(r0) @@ -975,13 +871,23 @@ func Getuid() (uid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Issetugid() (tainted bool) { - r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0) + r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0) tainted = bool(r0 != 0) return } // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Kqueue() (fd int, err error) { r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) fd = int(r0) @@ -1058,6 +964,21 @@ func Listen(s int, backlog int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Lstat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Mkdir(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1103,6 +1024,21 @@ func Mkfifo(path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mkfifoat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Mknod(path string, mode uint32, dev int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1118,6 +1054,31 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Open(path string, mode int, perm uint32) (fd int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1173,7 +1134,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1190,7 +1151,7 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { } else { _p0 = unsafe.Pointer(&_zero) } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1332,7 +1293,7 @@ func Rmdir(path string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) + r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0) newoffset = int64(r0) if e1 != 0 { err = errnoErr(e1) @@ -1354,7 +1315,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Setegid(egid int) (err error) { - _, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0) + _, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1418,8 +1379,8 @@ func Setpriority(which int, who int, prio int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setprivexec(flag int) (err error) { - _, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0) +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) if e1 != 0 { err = errnoErr(e1) } @@ -1428,8 +1389,8 @@ func Setprivexec(flag int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setregid(rgid int, egid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) if e1 != 0 { err = errnoErr(e1) } @@ -1438,8 +1399,18 @@ func Setregid(rgid int, egid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setreuid(ruid int, euid int) (err error) { - _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) if e1 != 0 { err = errnoErr(e1) } @@ -1458,6 +1429,16 @@ func Setrlimit(which int, lim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setrtable(rtable int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) @@ -1489,6 +1470,36 @@ func Setuid(uid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Stat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statfs(path string, stat *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Symlink(path string, link string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1545,7 +1556,7 @@ func Truncate(path string, length int64) (err error) { if err != nil { return } - _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) + _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length)) if e1 != 0 { err = errnoErr(e1) } @@ -1562,21 +1573,6 @@ func Umask(newmask int) (oldmask int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Undelete(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Unlink(path string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1640,7 +1636,7 @@ func write(fd int, p []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { - r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) + r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0) ret = uintptr(r0) if e1 != 0 { err = errnoErr(e1) @@ -1682,101 +1678,13 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { - r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) - sec = int64(r0) - usec = int32(r1) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) if err != nil { return } - _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstatfs(fd int, stat *Statfs_t) (err error) { - _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) { - r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(buf), uintptr(size), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Lstat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Stat(path string, stat *Stat_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Statfs(path string, stat *Statfs_t) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go index 37dcc74c2d..102f1ab475 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go @@ -1,4 +1,4 @@ -// mksysctl_openbsd.pl +// go run mksysctl_openbsd.go // Code generated by the command above; DO NOT EDIT. // +build 386,openbsd @@ -30,6 +30,7 @@ var sysctlMib = []mibentry{ {"hw.model", []_C_int{6, 2}}, {"hw.ncpu", []_C_int{6, 3}}, {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, {"hw.pagesize", []_C_int{6, 7}}, {"hw.physmem", []_C_int{6, 19}}, {"hw.product", []_C_int{6, 15}}, diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go index fe6caa6eb7..4866fced8a 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go @@ -31,6 +31,7 @@ var sysctlMib = []mibentry{ {"hw.model", []_C_int{6, 2}}, {"hw.ncpu", []_C_int{6, 3}}, {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, {"hw.pagesize", []_C_int{6, 7}}, {"hw.perfpolicy", []_C_int{6, 23}}, {"hw.physmem", []_C_int{6, 19}}, diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go index 6eb8c0b086..d3801eb24b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go @@ -30,6 +30,7 @@ var sysctlMib = []mibentry{ {"hw.model", []_C_int{6, 2}}, {"hw.ncpu", []_C_int{6, 3}}, {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, {"hw.pagesize", []_C_int{6, 7}}, {"hw.physmem", []_C_int{6, 19}}, {"hw.product", []_C_int{6, 15}}, diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go new file mode 100644 index 0000000000..aca34b3493 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go @@ -0,0 +1,279 @@ +// go run mksysctl_openbsd.go +// Code generated by the command above; DO NOT EDIT. + +// +build mips64,openbsd + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.allowdt", []_C_int{1, 65}}, + {"kern.allowkmem", []_C_int{1, 52}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consbuf", []_C_int{1, 83}}, + {"kern.consbufsize", []_C_int{1, 82}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cpustats", []_C_int{1, 85}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nselcoll", []_C_int{1, 43}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pfstatus", []_C_int{1, 86}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.timeout_stats", []_C_int{1, 87}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.utc_offset", []_C_int{1, 88}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go index f33614532f..ad62324c7c 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go @@ -5,6 +5,7 @@ package unix +// Deprecated: Use libSystem wrappers instead of direct syscalls. const ( SYS_SYSCALL = 0 SYS_EXIT = 1 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go index 654dd3da3b..a2fc91d6a8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go @@ -5,6 +5,7 @@ package unix +// Deprecated: Use libSystem wrappers instead of direct syscalls. const ( SYS_SYSCALL = 0 SYS_EXIT = 1 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go index 103a72ed1c..20d7808ace 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go @@ -5,6 +5,7 @@ package unix +// Deprecated: Use libSystem wrappers instead of direct syscalls. const ( SYS_SYSCALL = 0 SYS_EXIT = 1 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go index 7ab2130b96..527b9588cc 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go @@ -5,6 +5,7 @@ package unix +// Deprecated: Use libSystem wrappers instead of direct syscalls. const ( SYS_SYSCALL = 0 SYS_EXIT = 1 diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go index 464c9a9832..9912c6ee3d 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go @@ -6,129 +6,125 @@ package unix const ( - // SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int - SYS_EXIT = 1 // { void exit(int rval); } - SYS_FORK = 2 // { int fork(void); } - SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); } - SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } - SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } - SYS_CLOSE = 6 // { int close(int fd); } - SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } wait4 wait_args int - SYS_LINK = 9 // { int link(char *path, char *link); } - SYS_UNLINK = 10 // { int unlink(char *path); } - SYS_CHDIR = 12 // { int chdir(char *path); } - SYS_FCHDIR = 13 // { int fchdir(int fd); } - SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } - SYS_CHMOD = 15 // { int chmod(char *path, int mode); } - SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } - SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int - SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } - SYS_GETPID = 20 // { pid_t getpid(void); } - SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } - SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } - SYS_SETUID = 23 // { int setuid(uid_t uid); } - SYS_GETUID = 24 // { uid_t getuid(void); } - SYS_GETEUID = 25 // { uid_t geteuid(void); } - SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } - SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } - SYS_SENDMSG = 28 // { int sendmsg(int s, caddr_t msg, int flags); } - SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, caddr_t from, int *fromlenaddr); } - SYS_ACCEPT = 30 // { int accept(int s, caddr_t name, int *anamelen); } - SYS_GETPEERNAME = 31 // { int getpeername(int fdes, caddr_t asa, int *alen); } - SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, caddr_t asa, int *alen); } - SYS_ACCESS = 33 // { int access(char *path, int flags); } - SYS_CHFLAGS = 34 // { int chflags(char *path, int flags); } - SYS_FCHFLAGS = 35 // { int fchflags(int fd, int flags); } - SYS_SYNC = 36 // { int sync(void); } - SYS_KILL = 37 // { int kill(int pid, int signum); } - SYS_GETPPID = 39 // { pid_t getppid(void); } - SYS_DUP = 41 // { int dup(int fd); } - SYS_PIPE = 42 // { int pipe(void); } - SYS_GETEGID = 43 // { gid_t getegid(void); } - SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); } - SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } - SYS_GETGID = 47 // { gid_t getgid(void); } - SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); } - SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } - SYS_ACCT = 51 // { int acct(char *path); } - SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); } - SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); } - SYS_REBOOT = 55 // { int reboot(int opt); } - SYS_REVOKE = 56 // { int revoke(char *path); } - SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } - SYS_READLINK = 58 // { int readlink(char *path, char *buf, int count); } - SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); } - SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int - SYS_CHROOT = 61 // { int chroot(char *path); } - SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); } - SYS_VFORK = 66 // { pid_t vfork(void); } - SYS_SBRK = 69 // { int sbrk(int incr); } - SYS_SSTK = 70 // { int sstk(int incr); } - SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int mprotect(void *addr, size_t len, int prot); } - SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } - SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } - SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } - SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } - SYS_GETPGRP = 81 // { int getpgrp(void); } - SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } - SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } - SYS_SWAPON = 85 // { int swapon(char *name); } - SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } - SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } - SYS_DUP2 = 90 // { int dup2(int from, int to); } - SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } - SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } - SYS_FSYNC = 95 // { int fsync(int fd); } - SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } - SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } - SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } - SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } - SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } - SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } - SYS_LISTEN = 106 // { int listen(int s, int backlog); } - SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } - SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } - SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } - SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } - SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } - SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } - SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } - SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } - SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } - SYS_SETREGID = 127 // { int setregid(int rgid, int egid); } - SYS_RENAME = 128 // { int rename(char *from, char *to); } - SYS_FLOCK = 131 // { int flock(int fd, int how); } - SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } - SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } - SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } - SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } - SYS_RMDIR = 137 // { int rmdir(char *path); } - SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } - SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } - SYS_SETSID = 147 // { int setsid(void); } - SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } - SYS_STATFS = 157 // { int statfs(char *path, struct statfs *buf); } - SYS_FSTATFS = 158 // { int fstatfs(int fd, struct statfs *buf); } - SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } - SYS_GETDOMAINNAME = 162 // { int getdomainname(char *domainname, int len); } - SYS_SETDOMAINNAME = 163 // { int setdomainname(char *domainname, int len); } - SYS_UNAME = 164 // { int uname(struct utsname *name); } - SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } - SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } - SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, size_t nbyte, int flags, off_t offset); } - SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, size_t nbyte, int flags, off_t offset); } - SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } - SYS_SETGID = 181 // { int setgid(gid_t gid); } - SYS_SETEGID = 182 // { int setegid(gid_t egid); } - SYS_SETEUID = 183 // { int seteuid(uid_t euid); } - SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } - SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } - SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int - SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int - SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } - // SYS_NOSYS = 198; // { int nosys(void); } __syscall __syscall_args int + SYS_EXIT = 1 // { void exit(int rval); } + SYS_FORK = 2 // { int fork(void); } + SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } + SYS_CLOSE = 6 // { int close(int fd); } + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } wait4 wait_args int + // SYS_NOSYS = 8; // { int nosys(void); } __nosys nosys_args int + SYS_LINK = 9 // { int link(char *path, char *link); } + SYS_UNLINK = 10 // { int unlink(char *path); } + SYS_CHDIR = 12 // { int chdir(char *path); } + SYS_FCHDIR = 13 // { int fchdir(int fd); } + SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } + SYS_CHMOD = 15 // { int chmod(char *path, int mode); } + SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } + SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int + SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } + SYS_GETPID = 20 // { pid_t getpid(void); } + SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } + SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } + SYS_SETUID = 23 // { int setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t getuid(void); } + SYS_GETEUID = 25 // { uid_t geteuid(void); } + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { int sendmsg(int s, caddr_t msg, int flags); } + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, caddr_t from, int *fromlenaddr); } + SYS_ACCEPT = 30 // { int accept(int s, caddr_t name, int *anamelen); } + SYS_GETPEERNAME = 31 // { int getpeername(int fdes, caddr_t asa, int *alen); } + SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, caddr_t asa, int *alen); } + SYS_ACCESS = 33 // { int access(char *path, int flags); } + SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } + SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } + SYS_SYNC = 36 // { int sync(void); } + SYS_KILL = 37 // { int kill(int pid, int signum); } + SYS_GETPPID = 39 // { pid_t getppid(void); } + SYS_DUP = 41 // { int dup(int fd); } + SYS_PIPE = 42 // { int pipe(void); } + SYS_GETEGID = 43 // { gid_t getegid(void); } + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } + SYS_GETGID = 47 // { gid_t getgid(void); } + SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, size_t namelen); } + SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } + SYS_ACCT = 51 // { int acct(char *path); } + SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); } + SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); } + SYS_REBOOT = 55 // { int reboot(int opt); } + SYS_REVOKE = 56 // { int revoke(char *path); } + SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } + SYS_READLINK = 58 // { int readlink(char *path, char *buf, int count); } + SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); } + SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int + SYS_CHROOT = 61 // { int chroot(char *path); } + SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); } + SYS_VFORK = 66 // { pid_t vfork(void); } + SYS_SBRK = 69 // { caddr_t sbrk(size_t incr); } + SYS_SSTK = 70 // { int sstk(size_t incr); } + SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } + SYS_GETPGRP = 81 // { int getpgrp(void); } + SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } + SYS_SWAPON = 85 // { int swapon(char *name); } + SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } + SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } + SYS_DUP2 = 90 // { int dup2(int from, int to); } + SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_FSYNC = 95 // { int fsync(int fd); } + SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } + SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } + SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } + SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } + SYS_LISTEN = 106 // { int listen(int s, int backlog); } + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } + SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } + SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } + SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } + SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } + SYS_SETREGID = 127 // { int setregid(int rgid, int egid); } + SYS_RENAME = 128 // { int rename(char *from, char *to); } + SYS_FLOCK = 131 // { int flock(int fd, int how); } + SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } + SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } + SYS_RMDIR = 137 // { int rmdir(char *path); } + SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } + SYS_SETSID = 147 // { int setsid(void); } + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } + SYS_STATFS = 157 // { int statfs(char *path, struct statfs *buf); } + SYS_FSTATFS = 158 // { int fstatfs(int fd, struct statfs *buf); } + SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } + SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } + SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, size_t nbyte, int flags, off_t offset); } + SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, size_t nbyte, int flags, off_t offset); } + SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } + SYS_SETGID = 181 // { int setgid(gid_t gid); } + SYS_SETEGID = 182 // { int setegid(gid_t egid); } + SYS_SETEUID = 183 // { int seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } + SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int + SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } SYS_LSEEK = 199 // { off_t lseek(int fd, int pad, off_t offset, int whence); } SYS_TRUNCATE = 200 // { int truncate(char *path, int pad, off_t length); } SYS_FTRUNCATE = 201 // { int ftruncate(int fd, int pad, off_t length); } @@ -161,8 +157,8 @@ const ( SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); } - SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, struct iovec *iovp, u_int iovcnt, int flags, off_t offset); } - SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, struct iovec *iovp,u_int iovcnt, int flags, off_t offset); } + SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, const struct iovec *iovp, int iovcnt, int flags, off_t offset); } + SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, const struct iovec *iovp, int iovcnt, int flags, off_t offset); } SYS_FHSTATFS = 297 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); } SYS_MODNEXT = 300 // { int modnext(int modid); } @@ -225,7 +221,7 @@ const ( SYS_KQUEUE = 362 // { int kqueue(void); } SYS_KEVENT = 363 // { int kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } SYS_KENV = 390 // { int kenv(int what, const char *name, char *value, int len); } - SYS_LCHFLAGS = 391 // { int lchflags(char *path, int flags); } + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, u_long flags); } SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); } SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); } SYS_VARSYM_SET = 450 // { int varsym_set(int level, const char *name, const char *data); } @@ -302,7 +298,7 @@ const ( SYS_VMM_GUEST_CTL = 534 // { int vmm_guest_ctl(int op, struct vmm_guest_options *options); } SYS_VMM_GUEST_SYNC_ADDR = 535 // { int vmm_guest_sync_addr(long *dstaddr, long *srcaddr); } SYS_PROCCTL = 536 // { int procctl(idtype_t idtype, id_t id, int cmd, void *data); } - SYS_CHFLAGSAT = 537 // { int chflagsat(int fd, const char *path, int flags, int atflags);} + SYS_CHFLAGSAT = 537 // { int chflagsat(int fd, const char *path, u_long flags, int atflags);} SYS_PIPE2 = 538 // { int pipe2(int *fildes, int flags); } SYS_UTIMENSAT = 539 // { int utimensat(int fd, const char *path, const struct timespec *ts, int flags); } SYS_FUTIMENS = 540 // { int futimens(int fd, const struct timespec *ts); } @@ -312,4 +308,9 @@ const ( SYS_LWP_SETAFFINITY = 544 // { int lwp_setaffinity(pid_t pid, lwpid_t tid, const cpumask_t *mask); } SYS_LWP_GETAFFINITY = 545 // { int lwp_getaffinity(pid_t pid, lwpid_t tid, cpumask_t *mask); } SYS_LWP_CREATE2 = 546 // { int lwp_create2(struct lwp_params *params, const cpumask_t *mask); } + SYS_GETCPUCLOCKID = 547 // { int getcpuclockid(pid_t pid, lwpid_t lwp_id, clockid_t *clock_id); } + SYS_WAIT6 = 548 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); } + SYS_LWP_GETNAME = 549 // { int lwp_getname(lwpid_t tid, char *name, size_t len); } + SYS_GETRANDOM = 550 // { ssize_t getrandom(void *buf, size_t len, unsigned flags); } + SYS___REALPATH = 551 // { ssize_t __realpath(const char *path, char *buf, size_t len); } ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 54559a8956..0f5a3f6970 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -431,6 +431,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 054a741b7f..36d5219ef8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -353,6 +353,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 307f2ba12e..3622ba14b4 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -395,6 +395,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index e9404dd545..6193c3dc07 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -298,6 +298,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 68bb6d29b8..640b974345 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -416,6 +416,8 @@ const ( SYS_FSPICK = 4433 SYS_PIDFD_OPEN = 4434 SYS_CLONE3 = 4435 + SYS_CLOSE_RANGE = 4436 SYS_OPENAT2 = 4437 SYS_PIDFD_GETFD = 4438 + SYS_FACCESSAT2 = 4439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 4e5251185f..3467fbb5ff 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -346,6 +346,8 @@ const ( SYS_FSPICK = 5433 SYS_PIDFD_OPEN = 5434 SYS_CLONE3 = 5435 + SYS_CLOSE_RANGE = 5436 SYS_OPENAT2 = 5437 SYS_PIDFD_GETFD = 5438 + SYS_FACCESSAT2 = 5439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 4d9aa3003b..0fc38d5a72 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -346,6 +346,8 @@ const ( SYS_FSPICK = 5433 SYS_PIDFD_OPEN = 5434 SYS_CLONE3 = 5435 + SYS_CLOSE_RANGE = 5436 SYS_OPENAT2 = 5437 SYS_PIDFD_GETFD = 5438 + SYS_FACCESSAT2 = 5439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 64af0707d5..999fd55bcc 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -416,6 +416,8 @@ const ( SYS_FSPICK = 4433 SYS_PIDFD_OPEN = 4434 SYS_CLONE3 = 4435 + SYS_CLOSE_RANGE = 4436 SYS_OPENAT2 = 4437 SYS_PIDFD_GETFD = 4438 + SYS_FACCESSAT2 = 4439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index cc3c067ba3..1df0d79935 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -395,6 +395,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 4050ff9836..4db39cca4d 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -395,6 +395,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 529abb6a7f..e692740144 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -297,6 +297,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 2766500109..a585aec4e7 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -360,6 +360,8 @@ const ( SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 SYS_CLONE3 = 435 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 4dc82bb249..d047e567af 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -374,6 +374,8 @@ const ( SYS_FSMOUNT = 432 SYS_FSPICK = 433 SYS_PIDFD_OPEN = 434 + SYS_CLOSE_RANGE = 436 SYS_OPENAT2 = 437 SYS_PIDFD_GETFD = 438 + SYS_FACCESSAT2 = 439 ) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go new file mode 100644 index 0000000000..5c08d573b3 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go @@ -0,0 +1,220 @@ +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build mips64,openbsd + +package unix + +const ( + SYS_EXIT = 1 // { void sys_exit(int rval); } + SYS_FORK = 2 // { int sys_fork(void); } + SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } + SYS_CLOSE = 6 // { int sys_close(int fd); } + SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } + SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } + SYS_UNLINK = 10 // { int sys_unlink(const char *path); } + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } + SYS_CHDIR = 12 // { int sys_chdir(const char *path); } + SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } + SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } + SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break + SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } + SYS_GETPID = 20 // { pid_t sys_getpid(void); } + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } + SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } + SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t sys_getuid(void); } + SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } + SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } + SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } + SYS_SYNC = 36 // { void sys_sync(void); } + SYS_MSYSCALL = 37 // { int sys_msyscall(void *addr, size_t len); } + SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); } + SYS_GETPPID = 39 // { pid_t sys_getppid(void); } + SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } + SYS_DUP = 41 // { int sys_dup(int fd); } + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } + SYS_GETEGID = 43 // { gid_t sys_getegid(void); } + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } + SYS_GETGID = 47 // { gid_t sys_getgid(void); } + SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } + SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } + SYS_ACCT = 51 // { int sys_acct(const char *path); } + SYS_SIGPENDING = 52 // { int sys_sigpending(void); } + SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } + SYS_REBOOT = 55 // { int sys_reboot(int opt); } + SYS_REVOKE = 56 // { int sys_revoke(const char *path); } + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } + SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } + SYS_CHROOT = 61 // { int sys_chroot(const char *path); } + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } + SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } + SYS_VFORK = 66 // { int sys_vfork(void); } + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } + SYS_GETPGRP = 81 // { int sys_getpgrp(void); } + SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } + SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } + SYS_FSYNC = 95 // { int sys_fsync(int fd); } + SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } + SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } + SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } + SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } + SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } + SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } + SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } + SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS___REALPATH = 115 // { int sys___realpath(const char *pathname, char *resolved); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } + SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } + SYS_KILL = 122 // { int sys_kill(int pid, int signum); } + SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } + SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } + SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); } + SYS_SETREGID = 127 // { int sys_setregid(gid_t rgid, gid_t egid); } + SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } + SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } + SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } + SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } + SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } + SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } + SYS_SETSID = 147 // { int sys_setsid(void); } + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } + SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } + SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } + SYS___TMPFD = 164 // { int sys___tmpfd(int flags); } + SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } + SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } + SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } + SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } + SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } + SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } + SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } + SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } + SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } + SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } + SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_ISSETUGID = 253 // { int sys_issetugid(void); } + SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } + SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } + SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } + SYS_PIPE = 263 // { int sys_pipe(int *fdp); } + SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_KQUEUE = 269 // { int sys_kqueue(void); } + SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } + SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } + SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } + SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } + SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } + SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } + SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } + SYS_GETRTABLE = 311 // { int sys_getrtable(void); } + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } + SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } + SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go index 9f47b87c50..725b4bee27 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go @@ -92,9 +92,9 @@ type Statfs_t struct { Type uint32 Flags uint32 Fssubtype uint32 - Fstypename [16]int8 - Mntonname [1024]int8 - Mntfromname [1024]int8 + Fstypename [16]byte + Mntonname [1024]byte + Mntfromname [1024]byte Reserved [8]uint32 } @@ -145,6 +145,10 @@ type Dirent struct { _ [3]byte } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -190,6 +194,15 @@ type RawSockaddrAny struct { Pad [92]int8 } +type RawSockaddrCtl struct { + Sc_len uint8 + Sc_family uint8 + Ss_sysaddr uint16 + Sc_id uint32 + Sc_unit uint32 + Sc_reserved [5]uint32 +} + type _Socklen uint32 type Linger struct { @@ -254,7 +267,9 @@ const ( SizeofSockaddrAny = 0x6c SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 + SizeofSockaddrCtl = 0x20 SizeofLinger = 0x8 + SizeofIovec = 0x8 SizeofIPMreq = 0x8 SizeofIPv6Mreq = 0x14 SizeofMsghdr = 0x1c @@ -301,7 +316,6 @@ type IfMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Data IfData } @@ -344,7 +358,6 @@ type IfaMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Metric int32 } @@ -365,7 +378,6 @@ type IfmaMsghdr2 struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Refcount int32 } @@ -374,7 +386,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -396,7 +407,8 @@ type RtMetrics struct { Rtt uint32 Rttvar uint32 Pksent uint32 - Filler [4]uint32 + State uint32 + Filler [3]uint32 } const ( @@ -497,3 +509,8 @@ type Clockinfo struct { Stathz int32 Profhz int32 } + +type CtlInfo struct { + Id uint32 + Name [96]byte +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 966798a870..080ffce325 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -70,7 +70,6 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - _ [4]byte Atim Timespec Mtim Timespec Ctim Timespec @@ -97,10 +96,11 @@ type Statfs_t struct { Type uint32 Flags uint32 Fssubtype uint32 - Fstypename [16]int8 - Mntonname [1024]int8 - Mntfromname [1024]int8 - Reserved [8]uint32 + Fstypename [16]byte + Mntonname [1024]byte + Mntfromname [1024]byte + Flags_ext uint32 + Reserved [7]uint32 } type Flock_t struct { @@ -133,8 +133,7 @@ type Fbootstraptransfer_t struct { type Log2phys_t struct { Flags uint32 - _ [8]byte - _ [8]byte + _ [16]byte } type Fsid struct { @@ -151,6 +150,10 @@ type Dirent struct { _ [3]byte } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -196,6 +199,15 @@ type RawSockaddrAny struct { Pad [92]int8 } +type RawSockaddrCtl struct { + Sc_len uint8 + Sc_family uint8 + Ss_sysaddr uint16 + Sc_id uint32 + Sc_unit uint32 + Sc_reserved [5]uint32 +} + type _Socklen uint32 type Linger struct { @@ -221,10 +233,8 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen int32 - _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -262,7 +272,9 @@ const ( SizeofSockaddrAny = 0x6c SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 + SizeofSockaddrCtl = 0x20 SizeofLinger = 0x8 + SizeofIovec = 0x10 SizeofIPMreq = 0x8 SizeofIPv6Mreq = 0x14 SizeofMsghdr = 0x30 @@ -309,7 +321,6 @@ type IfMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Data IfData } @@ -352,7 +363,6 @@ type IfaMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Metric int32 } @@ -373,7 +383,6 @@ type IfmaMsghdr2 struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Refcount int32 } @@ -382,7 +391,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -404,7 +412,8 @@ type RtMetrics struct { Rtt uint32 Rttvar uint32 Pksent uint32 - Filler [4]uint32 + State uint32 + Filler [3]uint32 } const ( @@ -427,7 +436,6 @@ type BpfStat struct { type BpfProgram struct { Len uint32 - _ [4]byte Insns *BpfInsn } @@ -452,7 +460,6 @@ type Termios struct { Cflag uint64 Lflag uint64 Cc [20]uint8 - _ [4]byte Ispeed uint64 Ospeed uint64 } @@ -507,3 +514,8 @@ type Clockinfo struct { Stathz int32 Profhz int32 } + +type CtlInfo struct { + Id uint32 + Name [96]byte +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go index 4fe4c9cd73..f2a77bc4e2 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go @@ -1,6 +1,5 @@ -// NOTE: cgo can't generate struct Stat_t and struct Statfs_t yet -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_darwin.go +// cgo -godefs types_darwin.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,darwin @@ -31,7 +30,7 @@ type Timeval struct { Usec int32 } -type Timeval32 [0]byte +type Timeval32 struct{} type Rusage struct { Utime Timeval @@ -93,9 +92,9 @@ type Statfs_t struct { Type uint32 Flags uint32 Fssubtype uint32 - Fstypename [16]int8 - Mntonname [1024]int8 - Mntfromname [1024]int8 + Fstypename [16]byte + Mntonname [1024]byte + Mntfromname [1024]byte Reserved [8]uint32 } @@ -146,6 +145,10 @@ type Dirent struct { _ [3]byte } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -191,6 +194,15 @@ type RawSockaddrAny struct { Pad [92]int8 } +type RawSockaddrCtl struct { + Sc_len uint8 + Sc_family uint8 + Ss_sysaddr uint16 + Sc_id uint32 + Sc_unit uint32 + Sc_reserved [5]uint32 +} + type _Socklen uint32 type Linger struct { @@ -255,7 +267,9 @@ const ( SizeofSockaddrAny = 0x6c SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 + SizeofSockaddrCtl = 0x20 SizeofLinger = 0x8 + SizeofIovec = 0x8 SizeofIPMreq = 0x8 SizeofIPv6Mreq = 0x14 SizeofMsghdr = 0x1c @@ -302,7 +316,6 @@ type IfMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Data IfData } @@ -345,7 +358,6 @@ type IfaMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Metric int32 } @@ -366,7 +378,6 @@ type IfmaMsghdr2 struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Refcount int32 } @@ -375,7 +386,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -397,7 +407,8 @@ type RtMetrics struct { Rtt uint32 Rttvar uint32 Pksent uint32 - Filler [4]uint32 + State uint32 + Filler [3]uint32 } const ( @@ -498,3 +509,8 @@ type Clockinfo struct { Stathz int32 Profhz int32 } + +type CtlInfo struct { + Id uint32 + Name [96]byte +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 21999e4b0a..c9492428bf 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -70,7 +70,6 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - _ [4]byte Atim Timespec Mtim Timespec Ctim Timespec @@ -97,10 +96,11 @@ type Statfs_t struct { Type uint32 Flags uint32 Fssubtype uint32 - Fstypename [16]int8 - Mntonname [1024]int8 - Mntfromname [1024]int8 - Reserved [8]uint32 + Fstypename [16]byte + Mntonname [1024]byte + Mntfromname [1024]byte + Flags_ext uint32 + Reserved [7]uint32 } type Flock_t struct { @@ -133,8 +133,7 @@ type Fbootstraptransfer_t struct { type Log2phys_t struct { Flags uint32 - _ [8]byte - _ [8]byte + _ [16]byte } type Fsid struct { @@ -151,6 +150,10 @@ type Dirent struct { _ [3]byte } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -196,6 +199,15 @@ type RawSockaddrAny struct { Pad [92]int8 } +type RawSockaddrCtl struct { + Sc_len uint8 + Sc_family uint8 + Ss_sysaddr uint16 + Sc_id uint32 + Sc_unit uint32 + Sc_reserved [5]uint32 +} + type _Socklen uint32 type Linger struct { @@ -221,10 +233,8 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen int32 - _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -262,7 +272,9 @@ const ( SizeofSockaddrAny = 0x6c SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 + SizeofSockaddrCtl = 0x20 SizeofLinger = 0x8 + SizeofIovec = 0x10 SizeofIPMreq = 0x8 SizeofIPv6Mreq = 0x14 SizeofMsghdr = 0x30 @@ -309,7 +321,6 @@ type IfMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Data IfData } @@ -352,7 +363,6 @@ type IfaMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Metric int32 } @@ -373,7 +383,6 @@ type IfmaMsghdr2 struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Refcount int32 } @@ -382,7 +391,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -404,7 +412,8 @@ type RtMetrics struct { Rtt uint32 Rttvar uint32 Pksent uint32 - Filler [4]uint32 + State uint32 + Filler [3]uint32 } const ( @@ -427,7 +436,6 @@ type BpfStat struct { type BpfProgram struct { Len uint32 - _ [4]byte Insns *BpfInsn } @@ -452,7 +460,6 @@ type Termios struct { Cflag uint64 Lflag uint64 Cc [20]uint8 - _ [4]byte Ispeed uint64 Ospeed uint64 } @@ -507,3 +514,8 @@ type Clockinfo struct { Stathz int32 Profhz int32 } + +type CtlInfo struct { + Id uint32 + Name [96]byte +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go index 71ea1d6d23..c4772df23b 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go @@ -70,11 +70,11 @@ type Stat_t struct { Ctim Timespec Size int64 Blocks int64 - Blksize uint32 + _ uint32 Flags uint32 Gen uint32 Lspare int32 - Qspare1 int64 + Blksize int64 Qspare2 int64 } @@ -91,17 +91,15 @@ type Statfs_t struct { Owner uint32 Type int32 Flags int32 - _ [4]byte Syncwrites int64 Asyncwrites int64 - Fstypename [16]int8 - Mntonname [80]int8 + Fstypename [16]byte + Mntonname [80]byte Syncreads int64 Asyncreads int64 Spares1 int16 - Mntfromname [80]int8 + Mntfromname [80]byte Spares2 int16 - _ [4]byte Spare [2]int64 } @@ -202,10 +200,8 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen int32 - _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -269,7 +265,7 @@ type FdSet struct { const ( SizeofIfMsghdr = 0xb0 SizeofIfData = 0xa0 - SizeofIfaMsghdr = 0x14 + SizeofIfaMsghdr = 0x18 SizeofIfmaMsghdr = 0x10 SizeofIfAnnounceMsghdr = 0x18 SizeofRtMsghdr = 0x98 @@ -280,10 +276,9 @@ type IfMsghdr struct { Msglen uint16 Version uint8 Type uint8 - Addrs int32 - Flags int32 Index uint16 - _ [2]byte + Flags int32 + Addrs int32 Data IfData } @@ -294,7 +289,6 @@ type IfData struct { Hdrlen uint8 Recvquota uint8 Xmitquota uint8 - _ [2]byte Mtu uint64 Metric uint64 Link_state uint64 @@ -316,24 +310,23 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - _ [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Addrflags int32 + Metric int32 } type IfmaMsghdr struct { Msglen uint16 Version uint8 Type uint8 - Addrs int32 - Flags int32 Index uint16 - _ [2]byte + Flags int32 + Addrs int32 } type IfAnnounceMsghdr struct { @@ -350,7 +343,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -374,7 +366,6 @@ type RtMetrics struct { Hopcount uint64 Mssopt uint16 Pad uint16 - _ [4]byte Msl uint64 Iwmaxsegs uint64 Iwcapsegs uint64 @@ -400,7 +391,6 @@ type BpfStat struct { type BpfProgram struct { Len uint32 - _ [4]byte Insns *BpfInsn } diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 6f79227d74..b91c2ae0f0 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -125,9 +125,9 @@ type Statfs_t struct { Owner uint32 Fsid Fsid Charspare [80]int8 - Fstypename [16]int8 - Mntfromname [1024]int8 - Mntonname [1024]int8 + Fstypename [16]byte + Mntfromname [1024]byte + Mntonname [1024]byte } type statfs_freebsd11_t struct { @@ -150,9 +150,9 @@ type statfs_freebsd11_t struct { Owner uint32 Fsid Fsid Charspare [80]int8 - Fstypename [16]int8 - Mntfromname [88]int8 - Mntonname [88]int8 + Fstypename [16]byte + Mntfromname [88]byte + Mntonname [88]byte } type Flock_t struct { diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go index 416f7767e7..504ef131fb 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -67,13 +67,30 @@ type Statx_t struct { Rdev_minor uint32 Dev_major uint32 Dev_minor uint32 - _ [14]uint64 + Mnt_id uint64 + _ uint64 + _ [12]uint64 } type Fsid struct { Val [2]int32 } +type FileCloneRange struct { + Src_fd int64 + Src_offset uint64 + Src_length uint64 + Dest_offset uint64 +} + +type FileDedupeRange struct { + Src_offset uint64 + Src_length uint64 + Dest_count uint16 + Reserved1 uint16 + Reserved2 uint32 +} + type FscryptPolicy struct { Version uint8 Contents_encryption_mode uint8 @@ -138,6 +155,48 @@ type FscryptGetKeyStatusArg struct { _ [13]uint32 } +type DmIoctl struct { + Version [3]uint32 + Data_size uint32 + Data_start uint32 + Target_count uint32 + Open_count int32 + Flags uint32 + Event_nr uint32 + _ uint32 + Dev uint64 + Name [128]byte + Uuid [129]byte + Data [7]byte +} + +type DmTargetSpec struct { + Sector_start uint64 + Length uint64 + Status int32 + Next uint32 + Target_type [16]byte +} + +type DmTargetDeps struct { + Count uint32 + _ uint32 +} + +type DmTargetVersions struct { + Next uint32 + Version [3]uint32 +} + +type DmTargetMsg struct { + Sector uint64 +} + +const ( + SizeofDmIoctl = 0x138 + SizeofDmTargetSpec = 0x28 +) + type KeyctlDHParams struct { Private int32 Prime int32 @@ -266,6 +325,15 @@ type RawSockaddrL2TPIP6 struct { Conn_id uint32 } +type RawSockaddrIUCV struct { + Family uint16 + Port uint16 + Addr uint32 + Nodeid [8]int8 + User_id [8]int8 + Name [8]int8 +} + type _Socklen uint32 type Linger struct { @@ -378,6 +446,7 @@ const ( SizeofSockaddrTIPC = 0x10 SizeofSockaddrL2TPIP = 0x10 SizeofSockaddrL2TPIP6 = 0x20 + SizeofSockaddrIUCV = 0x20 SizeofLinger = 0x8 SizeofIPMreq = 0x8 SizeofIPMreqn = 0xc @@ -393,166 +462,107 @@ const ( ) const ( - NDA_UNSPEC = 0x0 - NDA_DST = 0x1 - NDA_LLADDR = 0x2 - NDA_CACHEINFO = 0x3 - NDA_PROBES = 0x4 - NDA_VLAN = 0x5 - NDA_PORT = 0x6 - NDA_VNI = 0x7 - NDA_IFINDEX = 0x8 - NDA_MASTER = 0x9 - NDA_LINK_NETNSID = 0xa - NDA_SRC_VNI = 0xb - NTF_USE = 0x1 - NTF_SELF = 0x2 - NTF_MASTER = 0x4 - NTF_PROXY = 0x8 - NTF_EXT_LEARNED = 0x10 - NTF_OFFLOADED = 0x20 - NTF_ROUTER = 0x80 - NUD_INCOMPLETE = 0x1 - NUD_REACHABLE = 0x2 - NUD_STALE = 0x4 - NUD_DELAY = 0x8 - NUD_PROBE = 0x10 - NUD_FAILED = 0x20 - NUD_NOARP = 0x40 - NUD_PERMANENT = 0x80 - NUD_NONE = 0x0 - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFA_FLAGS = 0x8 - IFA_RT_PRIORITY = 0x9 - IFA_TARGET_NETNSID = 0xa - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_TARGET_NETNSID = 0x2e - IFLA_CARRIER_UP_COUNT = 0x2f - IFLA_CARRIER_DOWN_COUNT = 0x30 - IFLA_NEW_IFINDEX = 0x31 - IFLA_MIN_MTU = 0x32 - IFLA_MAX_MTU = 0x33 - IFLA_MAX = 0x36 - IFLA_INFO_KIND = 0x1 - IFLA_INFO_DATA = 0x2 - IFLA_INFO_XSTATS = 0x3 - IFLA_INFO_SLAVE_KIND = 0x4 - IFLA_INFO_SLAVE_DATA = 0x5 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofIfaCacheinfo = 0x10 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 - SizeofNdUseroptmsg = 0x10 - SizeofNdMsg = 0xc + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofIfaCacheinfo = 0x10 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -671,6 +681,8 @@ type InotifyEvent struct { const SizeofInotifyEvent = 0x10 +const SI_LOAD_SHIFT = 0x10 + type Utsname struct { Sysname [65]byte Nodename [65]byte @@ -696,6 +708,22 @@ const ( AT_EACCESS = 0x200 ) +type OpenHow struct { + Flags uint64 + Mode uint64 + Resolve uint64 +} + +const SizeofOpenHow = 0x18 + +const ( + RESOLVE_BENEATH = 0x8 + RESOLVE_IN_ROOT = 0x10 + RESOLVE_NO_MAGICLINKS = 0x2 + RESOLVE_NO_SYMLINKS = 0x4 + RESOLVE_NO_XDEV = 0x1 +) + type PollFd struct { Fd int32 Events int16 @@ -736,8 +764,6 @@ type SignalfdSiginfo struct { _ [28]uint8 } -const PERF_IOC_FLAG_GROUP = 0x1 - type Winsize struct { Row uint16 Col uint16 @@ -861,7 +887,10 @@ type PerfEventMmapPage struct { Time_offset uint64 Time_zero uint64 Size uint32 - _ [948]uint8 + _ uint32 + Time_cycles uint64 + Time_mask uint64 + _ [928]uint8 Data_head uint64 Data_tail uint64 Data_offset uint64 @@ -903,13 +932,13 @@ const ( ) const ( - PERF_TYPE_HARDWARE = 0x0 - PERF_TYPE_SOFTWARE = 0x1 - PERF_TYPE_TRACEPOINT = 0x2 - PERF_TYPE_HW_CACHE = 0x3 - PERF_TYPE_RAW = 0x4 - PERF_TYPE_BREAKPOINT = 0x5 - + PERF_TYPE_HARDWARE = 0x0 + PERF_TYPE_SOFTWARE = 0x1 + PERF_TYPE_TRACEPOINT = 0x2 + PERF_TYPE_HW_CACHE = 0x3 + PERF_TYPE_RAW = 0x4 + PERF_TYPE_BREAKPOINT = 0x5 + PERF_TYPE_MAX = 0x6 PERF_COUNT_HW_CPU_CYCLES = 0x0 PERF_COUNT_HW_INSTRUCTIONS = 0x1 PERF_COUNT_HW_CACHE_REFERENCES = 0x2 @@ -920,99 +949,163 @@ const ( PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 - - PERF_COUNT_HW_CACHE_L1D = 0x0 - PERF_COUNT_HW_CACHE_L1I = 0x1 - PERF_COUNT_HW_CACHE_LL = 0x2 - PERF_COUNT_HW_CACHE_DTLB = 0x3 - PERF_COUNT_HW_CACHE_ITLB = 0x4 - PERF_COUNT_HW_CACHE_BPU = 0x5 - PERF_COUNT_HW_CACHE_NODE = 0x6 - - PERF_COUNT_HW_CACHE_OP_READ = 0x0 - PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 - PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 - - PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 - PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 - - PERF_COUNT_SW_CPU_CLOCK = 0x0 - PERF_COUNT_SW_TASK_CLOCK = 0x1 - PERF_COUNT_SW_PAGE_FAULTS = 0x2 - PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 - PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 - PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 - PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 - PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 - PERF_COUNT_SW_EMULATION_FAULTS = 0x8 - PERF_COUNT_SW_DUMMY = 0x9 - PERF_COUNT_SW_BPF_OUTPUT = 0xa - - PERF_SAMPLE_IP = 0x1 - PERF_SAMPLE_TID = 0x2 - PERF_SAMPLE_TIME = 0x4 - PERF_SAMPLE_ADDR = 0x8 - PERF_SAMPLE_READ = 0x10 - PERF_SAMPLE_CALLCHAIN = 0x20 - PERF_SAMPLE_ID = 0x40 - PERF_SAMPLE_CPU = 0x80 - PERF_SAMPLE_PERIOD = 0x100 - PERF_SAMPLE_STREAM_ID = 0x200 - PERF_SAMPLE_RAW = 0x400 - PERF_SAMPLE_BRANCH_STACK = 0x800 - - PERF_SAMPLE_BRANCH_USER = 0x1 - PERF_SAMPLE_BRANCH_KERNEL = 0x2 - PERF_SAMPLE_BRANCH_HV = 0x4 - PERF_SAMPLE_BRANCH_ANY = 0x8 - PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 - PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 - PERF_SAMPLE_BRANCH_IND_CALL = 0x40 - PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 - PERF_SAMPLE_BRANCH_IN_TX = 0x100 - PERF_SAMPLE_BRANCH_NO_TX = 0x200 - PERF_SAMPLE_BRANCH_COND = 0x400 - PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 - PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 - PERF_SAMPLE_BRANCH_CALL = 0x2000 - PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 - PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 - PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 - - PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 - PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 - PERF_FORMAT_ID = 0x4 - PERF_FORMAT_GROUP = 0x8 - - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 - PERF_RECORD_MMAP2 = 0xa - PERF_RECORD_AUX = 0xb - PERF_RECORD_ITRACE_START = 0xc - PERF_RECORD_LOST_SAMPLES = 0xd - PERF_RECORD_SWITCH = 0xe - PERF_RECORD_SWITCH_CPU_WIDE = 0xf - PERF_RECORD_NAMESPACES = 0x10 - - PERF_CONTEXT_HV = -0x20 - PERF_CONTEXT_KERNEL = -0x80 - PERF_CONTEXT_USER = -0x200 - - PERF_CONTEXT_GUEST = -0x800 - PERF_CONTEXT_GUEST_KERNEL = -0x880 - PERF_CONTEXT_GUEST_USER = -0xa00 - - PERF_FLAG_FD_NO_GROUP = 0x1 - PERF_FLAG_FD_OUTPUT = 0x2 - PERF_FLAG_PID_CGROUP = 0x4 - PERF_FLAG_FD_CLOEXEC = 0x8 + PERF_COUNT_HW_MAX = 0xa + PERF_COUNT_HW_CACHE_L1D = 0x0 + PERF_COUNT_HW_CACHE_L1I = 0x1 + PERF_COUNT_HW_CACHE_LL = 0x2 + PERF_COUNT_HW_CACHE_DTLB = 0x3 + PERF_COUNT_HW_CACHE_ITLB = 0x4 + PERF_COUNT_HW_CACHE_BPU = 0x5 + PERF_COUNT_HW_CACHE_NODE = 0x6 + PERF_COUNT_HW_CACHE_MAX = 0x7 + PERF_COUNT_HW_CACHE_OP_READ = 0x0 + PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 + PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 + PERF_COUNT_HW_CACHE_OP_MAX = 0x3 + PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 + PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 + PERF_COUNT_HW_CACHE_RESULT_MAX = 0x2 + PERF_COUNT_SW_CPU_CLOCK = 0x0 + PERF_COUNT_SW_TASK_CLOCK = 0x1 + PERF_COUNT_SW_PAGE_FAULTS = 0x2 + PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 + PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 + PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 + PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 + PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 + PERF_COUNT_SW_EMULATION_FAULTS = 0x8 + PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa + PERF_COUNT_SW_MAX = 0xb + PERF_SAMPLE_IP = 0x1 + PERF_SAMPLE_TID = 0x2 + PERF_SAMPLE_TIME = 0x4 + PERF_SAMPLE_ADDR = 0x8 + PERF_SAMPLE_READ = 0x10 + PERF_SAMPLE_CALLCHAIN = 0x20 + PERF_SAMPLE_ID = 0x40 + PERF_SAMPLE_CPU = 0x80 + PERF_SAMPLE_PERIOD = 0x100 + PERF_SAMPLE_STREAM_ID = 0x200 + PERF_SAMPLE_RAW = 0x400 + PERF_SAMPLE_BRANCH_STACK = 0x800 + PERF_SAMPLE_REGS_USER = 0x1000 + PERF_SAMPLE_STACK_USER = 0x2000 + PERF_SAMPLE_WEIGHT = 0x4000 + PERF_SAMPLE_DATA_SRC = 0x8000 + PERF_SAMPLE_IDENTIFIER = 0x10000 + PERF_SAMPLE_TRANSACTION = 0x20000 + PERF_SAMPLE_REGS_INTR = 0x40000 + PERF_SAMPLE_PHYS_ADDR = 0x80000 + PERF_SAMPLE_AUX = 0x100000 + PERF_SAMPLE_CGROUP = 0x200000 + PERF_SAMPLE_MAX = 0x400000 + PERF_SAMPLE_BRANCH_USER_SHIFT = 0x0 + PERF_SAMPLE_BRANCH_KERNEL_SHIFT = 0x1 + PERF_SAMPLE_BRANCH_HV_SHIFT = 0x2 + PERF_SAMPLE_BRANCH_ANY_SHIFT = 0x3 + PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT = 0x4 + PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT = 0x5 + PERF_SAMPLE_BRANCH_IND_CALL_SHIFT = 0x6 + PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT = 0x7 + PERF_SAMPLE_BRANCH_IN_TX_SHIFT = 0x8 + PERF_SAMPLE_BRANCH_NO_TX_SHIFT = 0x9 + PERF_SAMPLE_BRANCH_COND_SHIFT = 0xa + PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 0xb + PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 0xc + PERF_SAMPLE_BRANCH_CALL_SHIFT = 0xd + PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 0xe + PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 0xf + PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 0x10 + PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 0x11 + PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x12 + PERF_SAMPLE_BRANCH_USER = 0x1 + PERF_SAMPLE_BRANCH_KERNEL = 0x2 + PERF_SAMPLE_BRANCH_HV = 0x4 + PERF_SAMPLE_BRANCH_ANY = 0x8 + PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 + PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 + PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 + PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000 + PERF_SAMPLE_BRANCH_MAX = 0x40000 + PERF_BR_UNKNOWN = 0x0 + PERF_BR_COND = 0x1 + PERF_BR_UNCOND = 0x2 + PERF_BR_IND = 0x3 + PERF_BR_CALL = 0x4 + PERF_BR_IND_CALL = 0x5 + PERF_BR_RET = 0x6 + PERF_BR_SYSCALL = 0x7 + PERF_BR_SYSRET = 0x8 + PERF_BR_COND_CALL = 0x9 + PERF_BR_COND_RET = 0xa + PERF_BR_MAX = 0xb + PERF_SAMPLE_REGS_ABI_NONE = 0x0 + PERF_SAMPLE_REGS_ABI_32 = 0x1 + PERF_SAMPLE_REGS_ABI_64 = 0x2 + PERF_TXN_ELISION = 0x1 + PERF_TXN_TRANSACTION = 0x2 + PERF_TXN_SYNC = 0x4 + PERF_TXN_ASYNC = 0x8 + PERF_TXN_RETRY = 0x10 + PERF_TXN_CONFLICT = 0x20 + PERF_TXN_CAPACITY_WRITE = 0x40 + PERF_TXN_CAPACITY_READ = 0x80 + PERF_TXN_MAX = 0x100 + PERF_TXN_ABORT_MASK = -0x100000000 + PERF_TXN_ABORT_SHIFT = 0x20 + PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 + PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 + PERF_FORMAT_ID = 0x4 + PERF_FORMAT_GROUP = 0x8 + PERF_FORMAT_MAX = 0x10 + PERF_IOC_FLAG_GROUP = 0x1 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 + PERF_RECORD_KSYMBOL = 0x11 + PERF_RECORD_BPF_EVENT = 0x12 + PERF_RECORD_CGROUP = 0x13 + PERF_RECORD_TEXT_POKE = 0x14 + PERF_RECORD_MAX = 0x15 + PERF_RECORD_KSYMBOL_TYPE_UNKNOWN = 0x0 + PERF_RECORD_KSYMBOL_TYPE_BPF = 0x1 + PERF_RECORD_KSYMBOL_TYPE_OOL = 0x2 + PERF_RECORD_KSYMBOL_TYPE_MAX = 0x3 + PERF_BPF_EVENT_UNKNOWN = 0x0 + PERF_BPF_EVENT_PROG_LOAD = 0x1 + PERF_BPF_EVENT_PROG_UNLOAD = 0x2 + PERF_BPF_EVENT_MAX = 0x3 + PERF_CONTEXT_HV = -0x20 + PERF_CONTEXT_KERNEL = -0x80 + PERF_CONTEXT_USER = -0x200 + PERF_CONTEXT_GUEST = -0x800 + PERF_CONTEXT_GUEST_KERNEL = -0x880 + PERF_CONTEXT_GUEST_USER = -0xa00 + PERF_CONTEXT_MAX = -0xfff ) type TCPMD5Sig struct { @@ -1232,6 +1325,394 @@ const ( ) const ( + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_PROP_LIST = 0x34 + IFLA_ALT_IFNAME = 0x35 + IFLA_PERM_ADDRESS = 0x36 + IFLA_INET_UNSPEC = 0x0 + IFLA_INET_CONF = 0x1 + IFLA_INET6_UNSPEC = 0x0 + IFLA_INET6_FLAGS = 0x1 + IFLA_INET6_CONF = 0x2 + IFLA_INET6_STATS = 0x3 + IFLA_INET6_MCAST = 0x4 + IFLA_INET6_CACHEINFO = 0x5 + IFLA_INET6_ICMP6STATS = 0x6 + IFLA_INET6_TOKEN = 0x7 + IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_BR_UNSPEC = 0x0 + IFLA_BR_FORWARD_DELAY = 0x1 + IFLA_BR_HELLO_TIME = 0x2 + IFLA_BR_MAX_AGE = 0x3 + IFLA_BR_AGEING_TIME = 0x4 + IFLA_BR_STP_STATE = 0x5 + IFLA_BR_PRIORITY = 0x6 + IFLA_BR_VLAN_FILTERING = 0x7 + IFLA_BR_VLAN_PROTOCOL = 0x8 + IFLA_BR_GROUP_FWD_MASK = 0x9 + IFLA_BR_ROOT_ID = 0xa + IFLA_BR_BRIDGE_ID = 0xb + IFLA_BR_ROOT_PORT = 0xc + IFLA_BR_ROOT_PATH_COST = 0xd + IFLA_BR_TOPOLOGY_CHANGE = 0xe + IFLA_BR_TOPOLOGY_CHANGE_DETECTED = 0xf + IFLA_BR_HELLO_TIMER = 0x10 + IFLA_BR_TCN_TIMER = 0x11 + IFLA_BR_TOPOLOGY_CHANGE_TIMER = 0x12 + IFLA_BR_GC_TIMER = 0x13 + IFLA_BR_GROUP_ADDR = 0x14 + IFLA_BR_FDB_FLUSH = 0x15 + IFLA_BR_MCAST_ROUTER = 0x16 + IFLA_BR_MCAST_SNOOPING = 0x17 + IFLA_BR_MCAST_QUERY_USE_IFADDR = 0x18 + IFLA_BR_MCAST_QUERIER = 0x19 + IFLA_BR_MCAST_HASH_ELASTICITY = 0x1a + IFLA_BR_MCAST_HASH_MAX = 0x1b + IFLA_BR_MCAST_LAST_MEMBER_CNT = 0x1c + IFLA_BR_MCAST_STARTUP_QUERY_CNT = 0x1d + IFLA_BR_MCAST_LAST_MEMBER_INTVL = 0x1e + IFLA_BR_MCAST_MEMBERSHIP_INTVL = 0x1f + IFLA_BR_MCAST_QUERIER_INTVL = 0x20 + IFLA_BR_MCAST_QUERY_INTVL = 0x21 + IFLA_BR_MCAST_QUERY_RESPONSE_INTVL = 0x22 + IFLA_BR_MCAST_STARTUP_QUERY_INTVL = 0x23 + IFLA_BR_NF_CALL_IPTABLES = 0x24 + IFLA_BR_NF_CALL_IP6TABLES = 0x25 + IFLA_BR_NF_CALL_ARPTABLES = 0x26 + IFLA_BR_VLAN_DEFAULT_PVID = 0x27 + IFLA_BR_PAD = 0x28 + IFLA_BR_VLAN_STATS_ENABLED = 0x29 + IFLA_BR_MCAST_STATS_ENABLED = 0x2a + IFLA_BR_MCAST_IGMP_VERSION = 0x2b + IFLA_BR_MCAST_MLD_VERSION = 0x2c + IFLA_BR_VLAN_STATS_PER_PORT = 0x2d + IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BRPORT_UNSPEC = 0x0 + IFLA_BRPORT_STATE = 0x1 + IFLA_BRPORT_PRIORITY = 0x2 + IFLA_BRPORT_COST = 0x3 + IFLA_BRPORT_MODE = 0x4 + IFLA_BRPORT_GUARD = 0x5 + IFLA_BRPORT_PROTECT = 0x6 + IFLA_BRPORT_FAST_LEAVE = 0x7 + IFLA_BRPORT_LEARNING = 0x8 + IFLA_BRPORT_UNICAST_FLOOD = 0x9 + IFLA_BRPORT_PROXYARP = 0xa + IFLA_BRPORT_LEARNING_SYNC = 0xb + IFLA_BRPORT_PROXYARP_WIFI = 0xc + IFLA_BRPORT_ROOT_ID = 0xd + IFLA_BRPORT_BRIDGE_ID = 0xe + IFLA_BRPORT_DESIGNATED_PORT = 0xf + IFLA_BRPORT_DESIGNATED_COST = 0x10 + IFLA_BRPORT_ID = 0x11 + IFLA_BRPORT_NO = 0x12 + IFLA_BRPORT_TOPOLOGY_CHANGE_ACK = 0x13 + IFLA_BRPORT_CONFIG_PENDING = 0x14 + IFLA_BRPORT_MESSAGE_AGE_TIMER = 0x15 + IFLA_BRPORT_FORWARD_DELAY_TIMER = 0x16 + IFLA_BRPORT_HOLD_TIMER = 0x17 + IFLA_BRPORT_FLUSH = 0x18 + IFLA_BRPORT_MULTICAST_ROUTER = 0x19 + IFLA_BRPORT_PAD = 0x1a + IFLA_BRPORT_MCAST_FLOOD = 0x1b + IFLA_BRPORT_MCAST_TO_UCAST = 0x1c + IFLA_BRPORT_VLAN_TUNNEL = 0x1d + IFLA_BRPORT_BCAST_FLOOD = 0x1e + IFLA_BRPORT_GROUP_FWD_MASK = 0x1f + IFLA_BRPORT_NEIGH_SUPPRESS = 0x20 + IFLA_BRPORT_ISOLATED = 0x21 + IFLA_BRPORT_BACKUP_PORT = 0x22 + IFLA_BRPORT_MRP_RING_OPEN = 0x23 + IFLA_INFO_UNSPEC = 0x0 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + IFLA_VLAN_UNSPEC = 0x0 + IFLA_VLAN_ID = 0x1 + IFLA_VLAN_FLAGS = 0x2 + IFLA_VLAN_EGRESS_QOS = 0x3 + IFLA_VLAN_INGRESS_QOS = 0x4 + IFLA_VLAN_PROTOCOL = 0x5 + IFLA_VLAN_QOS_UNSPEC = 0x0 + IFLA_VLAN_QOS_MAPPING = 0x1 + IFLA_MACVLAN_UNSPEC = 0x0 + IFLA_MACVLAN_MODE = 0x1 + IFLA_MACVLAN_FLAGS = 0x2 + IFLA_MACVLAN_MACADDR_MODE = 0x3 + IFLA_MACVLAN_MACADDR = 0x4 + IFLA_MACVLAN_MACADDR_DATA = 0x5 + IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_VRF_UNSPEC = 0x0 + IFLA_VRF_TABLE = 0x1 + IFLA_VRF_PORT_UNSPEC = 0x0 + IFLA_VRF_PORT_TABLE = 0x1 + IFLA_MACSEC_UNSPEC = 0x0 + IFLA_MACSEC_SCI = 0x1 + IFLA_MACSEC_PORT = 0x2 + IFLA_MACSEC_ICV_LEN = 0x3 + IFLA_MACSEC_CIPHER_SUITE = 0x4 + IFLA_MACSEC_WINDOW = 0x5 + IFLA_MACSEC_ENCODING_SA = 0x6 + IFLA_MACSEC_ENCRYPT = 0x7 + IFLA_MACSEC_PROTECT = 0x8 + IFLA_MACSEC_INC_SCI = 0x9 + IFLA_MACSEC_ES = 0xa + IFLA_MACSEC_SCB = 0xb + IFLA_MACSEC_REPLAY_PROTECT = 0xc + IFLA_MACSEC_VALIDATION = 0xd + IFLA_MACSEC_PAD = 0xe + IFLA_MACSEC_OFFLOAD = 0xf + IFLA_XFRM_UNSPEC = 0x0 + IFLA_XFRM_LINK = 0x1 + IFLA_XFRM_IF_ID = 0x2 + IFLA_IPVLAN_UNSPEC = 0x0 + IFLA_IPVLAN_MODE = 0x1 + IFLA_IPVLAN_FLAGS = 0x2 + IFLA_VXLAN_UNSPEC = 0x0 + IFLA_VXLAN_ID = 0x1 + IFLA_VXLAN_GROUP = 0x2 + IFLA_VXLAN_LINK = 0x3 + IFLA_VXLAN_LOCAL = 0x4 + IFLA_VXLAN_TTL = 0x5 + IFLA_VXLAN_TOS = 0x6 + IFLA_VXLAN_LEARNING = 0x7 + IFLA_VXLAN_AGEING = 0x8 + IFLA_VXLAN_LIMIT = 0x9 + IFLA_VXLAN_PORT_RANGE = 0xa + IFLA_VXLAN_PROXY = 0xb + IFLA_VXLAN_RSC = 0xc + IFLA_VXLAN_L2MISS = 0xd + IFLA_VXLAN_L3MISS = 0xe + IFLA_VXLAN_PORT = 0xf + IFLA_VXLAN_GROUP6 = 0x10 + IFLA_VXLAN_LOCAL6 = 0x11 + IFLA_VXLAN_UDP_CSUM = 0x12 + IFLA_VXLAN_UDP_ZERO_CSUM6_TX = 0x13 + IFLA_VXLAN_UDP_ZERO_CSUM6_RX = 0x14 + IFLA_VXLAN_REMCSUM_TX = 0x15 + IFLA_VXLAN_REMCSUM_RX = 0x16 + IFLA_VXLAN_GBP = 0x17 + IFLA_VXLAN_REMCSUM_NOPARTIAL = 0x18 + IFLA_VXLAN_COLLECT_METADATA = 0x19 + IFLA_VXLAN_LABEL = 0x1a + IFLA_VXLAN_GPE = 0x1b + IFLA_VXLAN_TTL_INHERIT = 0x1c + IFLA_VXLAN_DF = 0x1d + IFLA_GENEVE_UNSPEC = 0x0 + IFLA_GENEVE_ID = 0x1 + IFLA_GENEVE_REMOTE = 0x2 + IFLA_GENEVE_TTL = 0x3 + IFLA_GENEVE_TOS = 0x4 + IFLA_GENEVE_PORT = 0x5 + IFLA_GENEVE_COLLECT_METADATA = 0x6 + IFLA_GENEVE_REMOTE6 = 0x7 + IFLA_GENEVE_UDP_CSUM = 0x8 + IFLA_GENEVE_UDP_ZERO_CSUM6_TX = 0x9 + IFLA_GENEVE_UDP_ZERO_CSUM6_RX = 0xa + IFLA_GENEVE_LABEL = 0xb + IFLA_GENEVE_TTL_INHERIT = 0xc + IFLA_GENEVE_DF = 0xd + IFLA_BAREUDP_UNSPEC = 0x0 + IFLA_BAREUDP_PORT = 0x1 + IFLA_BAREUDP_ETHERTYPE = 0x2 + IFLA_BAREUDP_SRCPORT_MIN = 0x3 + IFLA_BAREUDP_MULTIPROTO_MODE = 0x4 + IFLA_PPP_UNSPEC = 0x0 + IFLA_PPP_DEV_FD = 0x1 + IFLA_GTP_UNSPEC = 0x0 + IFLA_GTP_FD0 = 0x1 + IFLA_GTP_FD1 = 0x2 + IFLA_GTP_PDP_HASHSIZE = 0x3 + IFLA_GTP_ROLE = 0x4 + IFLA_BOND_UNSPEC = 0x0 + IFLA_BOND_MODE = 0x1 + IFLA_BOND_ACTIVE_SLAVE = 0x2 + IFLA_BOND_MIIMON = 0x3 + IFLA_BOND_UPDELAY = 0x4 + IFLA_BOND_DOWNDELAY = 0x5 + IFLA_BOND_USE_CARRIER = 0x6 + IFLA_BOND_ARP_INTERVAL = 0x7 + IFLA_BOND_ARP_IP_TARGET = 0x8 + IFLA_BOND_ARP_VALIDATE = 0x9 + IFLA_BOND_ARP_ALL_TARGETS = 0xa + IFLA_BOND_PRIMARY = 0xb + IFLA_BOND_PRIMARY_RESELECT = 0xc + IFLA_BOND_FAIL_OVER_MAC = 0xd + IFLA_BOND_XMIT_HASH_POLICY = 0xe + IFLA_BOND_RESEND_IGMP = 0xf + IFLA_BOND_NUM_PEER_NOTIF = 0x10 + IFLA_BOND_ALL_SLAVES_ACTIVE = 0x11 + IFLA_BOND_MIN_LINKS = 0x12 + IFLA_BOND_LP_INTERVAL = 0x13 + IFLA_BOND_PACKETS_PER_SLAVE = 0x14 + IFLA_BOND_AD_LACP_RATE = 0x15 + IFLA_BOND_AD_SELECT = 0x16 + IFLA_BOND_AD_INFO = 0x17 + IFLA_BOND_AD_ACTOR_SYS_PRIO = 0x18 + IFLA_BOND_AD_USER_PORT_KEY = 0x19 + IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a + IFLA_BOND_TLB_DYNAMIC_LB = 0x1b + IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_INFO_UNSPEC = 0x0 + IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 + IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 + IFLA_BOND_AD_INFO_ACTOR_KEY = 0x3 + IFLA_BOND_AD_INFO_PARTNER_KEY = 0x4 + IFLA_BOND_AD_INFO_PARTNER_MAC = 0x5 + IFLA_BOND_SLAVE_UNSPEC = 0x0 + IFLA_BOND_SLAVE_STATE = 0x1 + IFLA_BOND_SLAVE_MII_STATUS = 0x2 + IFLA_BOND_SLAVE_LINK_FAILURE_COUNT = 0x3 + IFLA_BOND_SLAVE_PERM_HWADDR = 0x4 + IFLA_BOND_SLAVE_QUEUE_ID = 0x5 + IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 + IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 + IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_VF_INFO_UNSPEC = 0x0 + IFLA_VF_INFO = 0x1 + IFLA_VF_UNSPEC = 0x0 + IFLA_VF_MAC = 0x1 + IFLA_VF_VLAN = 0x2 + IFLA_VF_TX_RATE = 0x3 + IFLA_VF_SPOOFCHK = 0x4 + IFLA_VF_LINK_STATE = 0x5 + IFLA_VF_RATE = 0x6 + IFLA_VF_RSS_QUERY_EN = 0x7 + IFLA_VF_STATS = 0x8 + IFLA_VF_TRUST = 0x9 + IFLA_VF_IB_NODE_GUID = 0xa + IFLA_VF_IB_PORT_GUID = 0xb + IFLA_VF_VLAN_LIST = 0xc + IFLA_VF_BROADCAST = 0xd + IFLA_VF_VLAN_INFO_UNSPEC = 0x0 + IFLA_VF_VLAN_INFO = 0x1 + IFLA_VF_LINK_STATE_AUTO = 0x0 + IFLA_VF_LINK_STATE_ENABLE = 0x1 + IFLA_VF_LINK_STATE_DISABLE = 0x2 + IFLA_VF_STATS_RX_PACKETS = 0x0 + IFLA_VF_STATS_TX_PACKETS = 0x1 + IFLA_VF_STATS_RX_BYTES = 0x2 + IFLA_VF_STATS_TX_BYTES = 0x3 + IFLA_VF_STATS_BROADCAST = 0x4 + IFLA_VF_STATS_MULTICAST = 0x5 + IFLA_VF_STATS_PAD = 0x6 + IFLA_VF_STATS_RX_DROPPED = 0x7 + IFLA_VF_STATS_TX_DROPPED = 0x8 + IFLA_VF_PORT_UNSPEC = 0x0 + IFLA_VF_PORT = 0x1 + IFLA_PORT_UNSPEC = 0x0 + IFLA_PORT_VF = 0x1 + IFLA_PORT_PROFILE = 0x2 + IFLA_PORT_VSI_TYPE = 0x3 + IFLA_PORT_INSTANCE_UUID = 0x4 + IFLA_PORT_HOST_UUID = 0x5 + IFLA_PORT_REQUEST = 0x6 + IFLA_PORT_RESPONSE = 0x7 + IFLA_IPOIB_UNSPEC = 0x0 + IFLA_IPOIB_PKEY = 0x1 + IFLA_IPOIB_MODE = 0x2 + IFLA_IPOIB_UMCAST = 0x3 + IFLA_HSR_UNSPEC = 0x0 + IFLA_HSR_SLAVE1 = 0x1 + IFLA_HSR_SLAVE2 = 0x2 + IFLA_HSR_MULTICAST_SPEC = 0x3 + IFLA_HSR_SUPERVISION_ADDR = 0x4 + IFLA_HSR_SEQ_NR = 0x5 + IFLA_HSR_VERSION = 0x6 + IFLA_STATS_UNSPEC = 0x0 + IFLA_STATS_LINK_64 = 0x1 + IFLA_STATS_LINK_XSTATS = 0x2 + IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 + IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 + IFLA_STATS_AF_SPEC = 0x5 + IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_XDP_UNSPEC = 0x0 + IFLA_XDP_FD = 0x1 + IFLA_XDP_ATTACHED = 0x2 + IFLA_XDP_FLAGS = 0x3 + IFLA_XDP_PROG_ID = 0x4 + IFLA_XDP_DRV_PROG_ID = 0x5 + IFLA_XDP_SKB_PROG_ID = 0x6 + IFLA_XDP_HW_PROG_ID = 0x7 + IFLA_XDP_EXPECTED_FD = 0x8 + IFLA_EVENT_NONE = 0x0 + IFLA_EVENT_REBOOT = 0x1 + IFLA_EVENT_FEATURES = 0x2 + IFLA_EVENT_BONDING_FAILOVER = 0x3 + IFLA_EVENT_NOTIFY_PEERS = 0x4 + IFLA_EVENT_IGMP_RESEND = 0x5 + IFLA_EVENT_BONDING_OPTIONS = 0x6 + IFLA_TUN_UNSPEC = 0x0 + IFLA_TUN_OWNER = 0x1 + IFLA_TUN_GROUP = 0x2 + IFLA_TUN_TYPE = 0x3 + IFLA_TUN_PI = 0x4 + IFLA_TUN_VNET_HDR = 0x5 + IFLA_TUN_PERSIST = 0x6 + IFLA_TUN_MULTI_QUEUE = 0x7 + IFLA_TUN_NUM_QUEUES = 0x8 + IFLA_TUN_NUM_DISABLED_QUEUES = 0x9 + IFLA_RMNET_UNSPEC = 0x0 + IFLA_RMNET_MUX_ID = 0x1 + IFLA_RMNET_FLAGS = 0x2 +) + +const ( NF_INET_PRE_ROUTING = 0x0 NF_INET_LOCAL_IN = 0x1 NF_INET_FORWARD = 0x2 @@ -1318,7 +1799,7 @@ const ( NFT_MSG_DELOBJ = 0x14 NFT_MSG_GETOBJ_RESET = 0x15 NFT_MSG_MAX = 0x19 - NFTA_LIST_UNPEC = 0x0 + NFTA_LIST_UNSPEC = 0x0 NFTA_LIST_ELEM = 0x1 NFTA_HOOK_UNSPEC = 0x0 NFTA_HOOK_HOOKNUM = 0x1 @@ -1689,6 +2170,21 @@ const ( NFT_NG_RANDOM = 0x1 ) +const ( + NFTA_TARGET_UNSPEC = 0x0 + NFTA_TARGET_NAME = 0x1 + NFTA_TARGET_REV = 0x2 + NFTA_TARGET_INFO = 0x3 + NFTA_MATCH_UNSPEC = 0x0 + NFTA_MATCH_NAME = 0x1 + NFTA_MATCH_REV = 0x2 + NFTA_MATCH_INFO = 0x3 + NFTA_COMPAT_UNSPEC = 0x0 + NFTA_COMPAT_NAME = 0x1 + NFTA_COMPAT_REV = 0x2 + NFTA_COMPAT_TYPE = 0x3 +) + type RTCTime struct { Sec int32 Min int32 @@ -1742,9 +2238,12 @@ type XDPMmapOffsets struct { } type XDPStatistics struct { - Rx_dropped uint64 - Rx_invalid_descs uint64 - Tx_invalid_descs uint64 + Rx_dropped uint64 + Rx_invalid_descs uint64 + Tx_invalid_descs uint64 + Rx_ring_full uint64 + Rx_fill_ring_empty_descs uint64 + Tx_ring_empty_descs uint64 } type XDPDesc struct { @@ -1871,175 +2370,281 @@ const ( ) const ( - BPF_REG_0 = 0x0 - BPF_REG_1 = 0x1 - BPF_REG_2 = 0x2 - BPF_REG_3 = 0x3 - BPF_REG_4 = 0x4 - BPF_REG_5 = 0x5 - BPF_REG_6 = 0x6 - BPF_REG_7 = 0x7 - BPF_REG_8 = 0x8 - BPF_REG_9 = 0x9 - BPF_REG_10 = 0xa - BPF_MAP_CREATE = 0x0 - BPF_MAP_LOOKUP_ELEM = 0x1 - BPF_MAP_UPDATE_ELEM = 0x2 - BPF_MAP_DELETE_ELEM = 0x3 - BPF_MAP_GET_NEXT_KEY = 0x4 - BPF_PROG_LOAD = 0x5 - BPF_OBJ_PIN = 0x6 - BPF_OBJ_GET = 0x7 - BPF_PROG_ATTACH = 0x8 - BPF_PROG_DETACH = 0x9 - BPF_PROG_TEST_RUN = 0xa - BPF_PROG_GET_NEXT_ID = 0xb - BPF_MAP_GET_NEXT_ID = 0xc - BPF_PROG_GET_FD_BY_ID = 0xd - BPF_MAP_GET_FD_BY_ID = 0xe - BPF_OBJ_GET_INFO_BY_FD = 0xf - BPF_PROG_QUERY = 0x10 - BPF_RAW_TRACEPOINT_OPEN = 0x11 - BPF_BTF_LOAD = 0x12 - BPF_BTF_GET_FD_BY_ID = 0x13 - BPF_TASK_FD_QUERY = 0x14 - BPF_MAP_LOOKUP_AND_DELETE_ELEM = 0x15 - BPF_MAP_FREEZE = 0x16 - BPF_BTF_GET_NEXT_ID = 0x17 - BPF_MAP_TYPE_UNSPEC = 0x0 - BPF_MAP_TYPE_HASH = 0x1 - BPF_MAP_TYPE_ARRAY = 0x2 - BPF_MAP_TYPE_PROG_ARRAY = 0x3 - BPF_MAP_TYPE_PERF_EVENT_ARRAY = 0x4 - BPF_MAP_TYPE_PERCPU_HASH = 0x5 - BPF_MAP_TYPE_PERCPU_ARRAY = 0x6 - BPF_MAP_TYPE_STACK_TRACE = 0x7 - BPF_MAP_TYPE_CGROUP_ARRAY = 0x8 - BPF_MAP_TYPE_LRU_HASH = 0x9 - BPF_MAP_TYPE_LRU_PERCPU_HASH = 0xa - BPF_MAP_TYPE_LPM_TRIE = 0xb - BPF_MAP_TYPE_ARRAY_OF_MAPS = 0xc - BPF_MAP_TYPE_HASH_OF_MAPS = 0xd - BPF_MAP_TYPE_DEVMAP = 0xe - BPF_MAP_TYPE_SOCKMAP = 0xf - BPF_MAP_TYPE_CPUMAP = 0x10 - BPF_MAP_TYPE_XSKMAP = 0x11 - BPF_MAP_TYPE_SOCKHASH = 0x12 - BPF_MAP_TYPE_CGROUP_STORAGE = 0x13 - BPF_MAP_TYPE_REUSEPORT_SOCKARRAY = 0x14 - BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE = 0x15 - BPF_MAP_TYPE_QUEUE = 0x16 - BPF_MAP_TYPE_STACK = 0x17 - BPF_MAP_TYPE_SK_STORAGE = 0x18 - BPF_MAP_TYPE_DEVMAP_HASH = 0x19 - BPF_PROG_TYPE_UNSPEC = 0x0 - BPF_PROG_TYPE_SOCKET_FILTER = 0x1 - BPF_PROG_TYPE_KPROBE = 0x2 - BPF_PROG_TYPE_SCHED_CLS = 0x3 - BPF_PROG_TYPE_SCHED_ACT = 0x4 - BPF_PROG_TYPE_TRACEPOINT = 0x5 - BPF_PROG_TYPE_XDP = 0x6 - BPF_PROG_TYPE_PERF_EVENT = 0x7 - BPF_PROG_TYPE_CGROUP_SKB = 0x8 - BPF_PROG_TYPE_CGROUP_SOCK = 0x9 - BPF_PROG_TYPE_LWT_IN = 0xa - BPF_PROG_TYPE_LWT_OUT = 0xb - BPF_PROG_TYPE_LWT_XMIT = 0xc - BPF_PROG_TYPE_SOCK_OPS = 0xd - BPF_PROG_TYPE_SK_SKB = 0xe - BPF_PROG_TYPE_CGROUP_DEVICE = 0xf - BPF_PROG_TYPE_SK_MSG = 0x10 - BPF_PROG_TYPE_RAW_TRACEPOINT = 0x11 - BPF_PROG_TYPE_CGROUP_SOCK_ADDR = 0x12 - BPF_PROG_TYPE_LWT_SEG6LOCAL = 0x13 - BPF_PROG_TYPE_LIRC_MODE2 = 0x14 - BPF_PROG_TYPE_SK_REUSEPORT = 0x15 - BPF_PROG_TYPE_FLOW_DISSECTOR = 0x16 - BPF_PROG_TYPE_CGROUP_SYSCTL = 0x17 - BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE = 0x18 - BPF_PROG_TYPE_CGROUP_SOCKOPT = 0x19 - BPF_PROG_TYPE_TRACING = 0x1a - BPF_CGROUP_INET_INGRESS = 0x0 - BPF_CGROUP_INET_EGRESS = 0x1 - BPF_CGROUP_INET_SOCK_CREATE = 0x2 - BPF_CGROUP_SOCK_OPS = 0x3 - BPF_SK_SKB_STREAM_PARSER = 0x4 - BPF_SK_SKB_STREAM_VERDICT = 0x5 - BPF_CGROUP_DEVICE = 0x6 - BPF_SK_MSG_VERDICT = 0x7 - BPF_CGROUP_INET4_BIND = 0x8 - BPF_CGROUP_INET6_BIND = 0x9 - BPF_CGROUP_INET4_CONNECT = 0xa - BPF_CGROUP_INET6_CONNECT = 0xb - BPF_CGROUP_INET4_POST_BIND = 0xc - BPF_CGROUP_INET6_POST_BIND = 0xd - BPF_CGROUP_UDP4_SENDMSG = 0xe - BPF_CGROUP_UDP6_SENDMSG = 0xf - BPF_LIRC_MODE2 = 0x10 - BPF_FLOW_DISSECTOR = 0x11 - BPF_CGROUP_SYSCTL = 0x12 - BPF_CGROUP_UDP4_RECVMSG = 0x13 - BPF_CGROUP_UDP6_RECVMSG = 0x14 - BPF_CGROUP_GETSOCKOPT = 0x15 - BPF_CGROUP_SETSOCKOPT = 0x16 - BPF_TRACE_RAW_TP = 0x17 - BPF_TRACE_FENTRY = 0x18 - BPF_TRACE_FEXIT = 0x19 - BPF_STACK_BUILD_ID_EMPTY = 0x0 - BPF_STACK_BUILD_ID_VALID = 0x1 - BPF_STACK_BUILD_ID_IP = 0x2 - BPF_ADJ_ROOM_NET = 0x0 - BPF_ADJ_ROOM_MAC = 0x1 - BPF_HDR_START_MAC = 0x0 - BPF_HDR_START_NET = 0x1 - BPF_LWT_ENCAP_SEG6 = 0x0 - BPF_LWT_ENCAP_SEG6_INLINE = 0x1 - BPF_LWT_ENCAP_IP = 0x2 - BPF_OK = 0x0 - BPF_DROP = 0x2 - BPF_REDIRECT = 0x7 - BPF_LWT_REROUTE = 0x80 - BPF_SOCK_OPS_VOID = 0x0 - BPF_SOCK_OPS_TIMEOUT_INIT = 0x1 - BPF_SOCK_OPS_RWND_INIT = 0x2 - BPF_SOCK_OPS_TCP_CONNECT_CB = 0x3 - BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB = 0x4 - BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB = 0x5 - BPF_SOCK_OPS_NEEDS_ECN = 0x6 - BPF_SOCK_OPS_BASE_RTT = 0x7 - BPF_SOCK_OPS_RTO_CB = 0x8 - BPF_SOCK_OPS_RETRANS_CB = 0x9 - BPF_SOCK_OPS_STATE_CB = 0xa - BPF_SOCK_OPS_TCP_LISTEN_CB = 0xb - BPF_SOCK_OPS_RTT_CB = 0xc - BPF_TCP_ESTABLISHED = 0x1 - BPF_TCP_SYN_SENT = 0x2 - BPF_TCP_SYN_RECV = 0x3 - BPF_TCP_FIN_WAIT1 = 0x4 - BPF_TCP_FIN_WAIT2 = 0x5 - BPF_TCP_TIME_WAIT = 0x6 - BPF_TCP_CLOSE = 0x7 - BPF_TCP_CLOSE_WAIT = 0x8 - BPF_TCP_LAST_ACK = 0x9 - BPF_TCP_LISTEN = 0xa - BPF_TCP_CLOSING = 0xb - BPF_TCP_NEW_SYN_RECV = 0xc - BPF_TCP_MAX_STATES = 0xd - BPF_FIB_LKUP_RET_SUCCESS = 0x0 - BPF_FIB_LKUP_RET_BLACKHOLE = 0x1 - BPF_FIB_LKUP_RET_UNREACHABLE = 0x2 - BPF_FIB_LKUP_RET_PROHIBIT = 0x3 - BPF_FIB_LKUP_RET_NOT_FWDED = 0x4 - BPF_FIB_LKUP_RET_FWD_DISABLED = 0x5 - BPF_FIB_LKUP_RET_UNSUPP_LWT = 0x6 - BPF_FIB_LKUP_RET_NO_NEIGH = 0x7 - BPF_FIB_LKUP_RET_FRAG_NEEDED = 0x8 - BPF_FD_TYPE_RAW_TRACEPOINT = 0x0 - BPF_FD_TYPE_TRACEPOINT = 0x1 - BPF_FD_TYPE_KPROBE = 0x2 - BPF_FD_TYPE_KRETPROBE = 0x3 - BPF_FD_TYPE_UPROBE = 0x4 - BPF_FD_TYPE_URETPROBE = 0x5 + BPF_REG_0 = 0x0 + BPF_REG_1 = 0x1 + BPF_REG_2 = 0x2 + BPF_REG_3 = 0x3 + BPF_REG_4 = 0x4 + BPF_REG_5 = 0x5 + BPF_REG_6 = 0x6 + BPF_REG_7 = 0x7 + BPF_REG_8 = 0x8 + BPF_REG_9 = 0x9 + BPF_REG_10 = 0xa + BPF_MAP_CREATE = 0x0 + BPF_MAP_LOOKUP_ELEM = 0x1 + BPF_MAP_UPDATE_ELEM = 0x2 + BPF_MAP_DELETE_ELEM = 0x3 + BPF_MAP_GET_NEXT_KEY = 0x4 + BPF_PROG_LOAD = 0x5 + BPF_OBJ_PIN = 0x6 + BPF_OBJ_GET = 0x7 + BPF_PROG_ATTACH = 0x8 + BPF_PROG_DETACH = 0x9 + BPF_PROG_TEST_RUN = 0xa + BPF_PROG_GET_NEXT_ID = 0xb + BPF_MAP_GET_NEXT_ID = 0xc + BPF_PROG_GET_FD_BY_ID = 0xd + BPF_MAP_GET_FD_BY_ID = 0xe + BPF_OBJ_GET_INFO_BY_FD = 0xf + BPF_PROG_QUERY = 0x10 + BPF_RAW_TRACEPOINT_OPEN = 0x11 + BPF_BTF_LOAD = 0x12 + BPF_BTF_GET_FD_BY_ID = 0x13 + BPF_TASK_FD_QUERY = 0x14 + BPF_MAP_LOOKUP_AND_DELETE_ELEM = 0x15 + BPF_MAP_FREEZE = 0x16 + BPF_BTF_GET_NEXT_ID = 0x17 + BPF_MAP_LOOKUP_BATCH = 0x18 + BPF_MAP_LOOKUP_AND_DELETE_BATCH = 0x19 + BPF_MAP_UPDATE_BATCH = 0x1a + BPF_MAP_DELETE_BATCH = 0x1b + BPF_LINK_CREATE = 0x1c + BPF_LINK_UPDATE = 0x1d + BPF_LINK_GET_FD_BY_ID = 0x1e + BPF_LINK_GET_NEXT_ID = 0x1f + BPF_ENABLE_STATS = 0x20 + BPF_ITER_CREATE = 0x21 + BPF_MAP_TYPE_UNSPEC = 0x0 + BPF_MAP_TYPE_HASH = 0x1 + BPF_MAP_TYPE_ARRAY = 0x2 + BPF_MAP_TYPE_PROG_ARRAY = 0x3 + BPF_MAP_TYPE_PERF_EVENT_ARRAY = 0x4 + BPF_MAP_TYPE_PERCPU_HASH = 0x5 + BPF_MAP_TYPE_PERCPU_ARRAY = 0x6 + BPF_MAP_TYPE_STACK_TRACE = 0x7 + BPF_MAP_TYPE_CGROUP_ARRAY = 0x8 + BPF_MAP_TYPE_LRU_HASH = 0x9 + BPF_MAP_TYPE_LRU_PERCPU_HASH = 0xa + BPF_MAP_TYPE_LPM_TRIE = 0xb + BPF_MAP_TYPE_ARRAY_OF_MAPS = 0xc + BPF_MAP_TYPE_HASH_OF_MAPS = 0xd + BPF_MAP_TYPE_DEVMAP = 0xe + BPF_MAP_TYPE_SOCKMAP = 0xf + BPF_MAP_TYPE_CPUMAP = 0x10 + BPF_MAP_TYPE_XSKMAP = 0x11 + BPF_MAP_TYPE_SOCKHASH = 0x12 + BPF_MAP_TYPE_CGROUP_STORAGE = 0x13 + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY = 0x14 + BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE = 0x15 + BPF_MAP_TYPE_QUEUE = 0x16 + BPF_MAP_TYPE_STACK = 0x17 + BPF_MAP_TYPE_SK_STORAGE = 0x18 + BPF_MAP_TYPE_DEVMAP_HASH = 0x19 + BPF_MAP_TYPE_STRUCT_OPS = 0x1a + BPF_MAP_TYPE_RINGBUF = 0x1b + BPF_PROG_TYPE_UNSPEC = 0x0 + BPF_PROG_TYPE_SOCKET_FILTER = 0x1 + BPF_PROG_TYPE_KPROBE = 0x2 + BPF_PROG_TYPE_SCHED_CLS = 0x3 + BPF_PROG_TYPE_SCHED_ACT = 0x4 + BPF_PROG_TYPE_TRACEPOINT = 0x5 + BPF_PROG_TYPE_XDP = 0x6 + BPF_PROG_TYPE_PERF_EVENT = 0x7 + BPF_PROG_TYPE_CGROUP_SKB = 0x8 + BPF_PROG_TYPE_CGROUP_SOCK = 0x9 + BPF_PROG_TYPE_LWT_IN = 0xa + BPF_PROG_TYPE_LWT_OUT = 0xb + BPF_PROG_TYPE_LWT_XMIT = 0xc + BPF_PROG_TYPE_SOCK_OPS = 0xd + BPF_PROG_TYPE_SK_SKB = 0xe + BPF_PROG_TYPE_CGROUP_DEVICE = 0xf + BPF_PROG_TYPE_SK_MSG = 0x10 + BPF_PROG_TYPE_RAW_TRACEPOINT = 0x11 + BPF_PROG_TYPE_CGROUP_SOCK_ADDR = 0x12 + BPF_PROG_TYPE_LWT_SEG6LOCAL = 0x13 + BPF_PROG_TYPE_LIRC_MODE2 = 0x14 + BPF_PROG_TYPE_SK_REUSEPORT = 0x15 + BPF_PROG_TYPE_FLOW_DISSECTOR = 0x16 + BPF_PROG_TYPE_CGROUP_SYSCTL = 0x17 + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE = 0x18 + BPF_PROG_TYPE_CGROUP_SOCKOPT = 0x19 + BPF_PROG_TYPE_TRACING = 0x1a + BPF_PROG_TYPE_STRUCT_OPS = 0x1b + BPF_PROG_TYPE_EXT = 0x1c + BPF_PROG_TYPE_LSM = 0x1d + BPF_CGROUP_INET_INGRESS = 0x0 + BPF_CGROUP_INET_EGRESS = 0x1 + BPF_CGROUP_INET_SOCK_CREATE = 0x2 + BPF_CGROUP_SOCK_OPS = 0x3 + BPF_SK_SKB_STREAM_PARSER = 0x4 + BPF_SK_SKB_STREAM_VERDICT = 0x5 + BPF_CGROUP_DEVICE = 0x6 + BPF_SK_MSG_VERDICT = 0x7 + BPF_CGROUP_INET4_BIND = 0x8 + BPF_CGROUP_INET6_BIND = 0x9 + BPF_CGROUP_INET4_CONNECT = 0xa + BPF_CGROUP_INET6_CONNECT = 0xb + BPF_CGROUP_INET4_POST_BIND = 0xc + BPF_CGROUP_INET6_POST_BIND = 0xd + BPF_CGROUP_UDP4_SENDMSG = 0xe + BPF_CGROUP_UDP6_SENDMSG = 0xf + BPF_LIRC_MODE2 = 0x10 + BPF_FLOW_DISSECTOR = 0x11 + BPF_CGROUP_SYSCTL = 0x12 + BPF_CGROUP_UDP4_RECVMSG = 0x13 + BPF_CGROUP_UDP6_RECVMSG = 0x14 + BPF_CGROUP_GETSOCKOPT = 0x15 + BPF_CGROUP_SETSOCKOPT = 0x16 + BPF_TRACE_RAW_TP = 0x17 + BPF_TRACE_FENTRY = 0x18 + BPF_TRACE_FEXIT = 0x19 + BPF_MODIFY_RETURN = 0x1a + BPF_LSM_MAC = 0x1b + BPF_TRACE_ITER = 0x1c + BPF_CGROUP_INET4_GETPEERNAME = 0x1d + BPF_CGROUP_INET6_GETPEERNAME = 0x1e + BPF_CGROUP_INET4_GETSOCKNAME = 0x1f + BPF_CGROUP_INET6_GETSOCKNAME = 0x20 + BPF_XDP_DEVMAP = 0x21 + BPF_LINK_TYPE_UNSPEC = 0x0 + BPF_LINK_TYPE_RAW_TRACEPOINT = 0x1 + BPF_LINK_TYPE_TRACING = 0x2 + BPF_LINK_TYPE_CGROUP = 0x3 + BPF_LINK_TYPE_ITER = 0x4 + BPF_LINK_TYPE_NETNS = 0x5 + BPF_ANY = 0x0 + BPF_NOEXIST = 0x1 + BPF_EXIST = 0x2 + BPF_F_LOCK = 0x4 + BPF_F_NO_PREALLOC = 0x1 + BPF_F_NO_COMMON_LRU = 0x2 + BPF_F_NUMA_NODE = 0x4 + BPF_F_RDONLY = 0x8 + BPF_F_WRONLY = 0x10 + BPF_F_STACK_BUILD_ID = 0x20 + BPF_F_ZERO_SEED = 0x40 + BPF_F_RDONLY_PROG = 0x80 + BPF_F_WRONLY_PROG = 0x100 + BPF_F_CLONE = 0x200 + BPF_F_MMAPABLE = 0x400 + BPF_STATS_RUN_TIME = 0x0 + BPF_STACK_BUILD_ID_EMPTY = 0x0 + BPF_STACK_BUILD_ID_VALID = 0x1 + BPF_STACK_BUILD_ID_IP = 0x2 + BPF_F_RECOMPUTE_CSUM = 0x1 + BPF_F_INVALIDATE_HASH = 0x2 + BPF_F_HDR_FIELD_MASK = 0xf + BPF_F_PSEUDO_HDR = 0x10 + BPF_F_MARK_MANGLED_0 = 0x20 + BPF_F_MARK_ENFORCE = 0x40 + BPF_F_INGRESS = 0x1 + BPF_F_TUNINFO_IPV6 = 0x1 + BPF_F_SKIP_FIELD_MASK = 0xff + BPF_F_USER_STACK = 0x100 + BPF_F_FAST_STACK_CMP = 0x200 + BPF_F_REUSE_STACKID = 0x400 + BPF_F_USER_BUILD_ID = 0x800 + BPF_F_ZERO_CSUM_TX = 0x2 + BPF_F_DONT_FRAGMENT = 0x4 + BPF_F_SEQ_NUMBER = 0x8 + BPF_F_INDEX_MASK = 0xffffffff + BPF_F_CURRENT_CPU = 0xffffffff + BPF_F_CTXLEN_MASK = 0xfffff00000000 + BPF_F_CURRENT_NETNS = -0x1 + BPF_CSUM_LEVEL_QUERY = 0x0 + BPF_CSUM_LEVEL_INC = 0x1 + BPF_CSUM_LEVEL_DEC = 0x2 + BPF_CSUM_LEVEL_RESET = 0x3 + BPF_F_ADJ_ROOM_FIXED_GSO = 0x1 + BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = 0x2 + BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = 0x4 + BPF_F_ADJ_ROOM_ENCAP_L4_GRE = 0x8 + BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10 + BPF_F_ADJ_ROOM_NO_CSUM_RESET = 0x20 + BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff + BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38 + BPF_F_SYSCTL_BASE_NAME = 0x1 + BPF_SK_STORAGE_GET_F_CREATE = 0x1 + BPF_F_GET_BRANCH_RECORDS_SIZE = 0x1 + BPF_RB_NO_WAKEUP = 0x1 + BPF_RB_FORCE_WAKEUP = 0x2 + BPF_RB_AVAIL_DATA = 0x0 + BPF_RB_RING_SIZE = 0x1 + BPF_RB_CONS_POS = 0x2 + BPF_RB_PROD_POS = 0x3 + BPF_RINGBUF_BUSY_BIT = 0x80000000 + BPF_RINGBUF_DISCARD_BIT = 0x40000000 + BPF_RINGBUF_HDR_SZ = 0x8 + BPF_ADJ_ROOM_NET = 0x0 + BPF_ADJ_ROOM_MAC = 0x1 + BPF_HDR_START_MAC = 0x0 + BPF_HDR_START_NET = 0x1 + BPF_LWT_ENCAP_SEG6 = 0x0 + BPF_LWT_ENCAP_SEG6_INLINE = 0x1 + BPF_LWT_ENCAP_IP = 0x2 + BPF_OK = 0x0 + BPF_DROP = 0x2 + BPF_REDIRECT = 0x7 + BPF_LWT_REROUTE = 0x80 + BPF_SOCK_OPS_RTO_CB_FLAG = 0x1 + BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2 + BPF_SOCK_OPS_STATE_CB_FLAG = 0x4 + BPF_SOCK_OPS_RTT_CB_FLAG = 0x8 + BPF_SOCK_OPS_ALL_CB_FLAGS = 0xf + BPF_SOCK_OPS_VOID = 0x0 + BPF_SOCK_OPS_TIMEOUT_INIT = 0x1 + BPF_SOCK_OPS_RWND_INIT = 0x2 + BPF_SOCK_OPS_TCP_CONNECT_CB = 0x3 + BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB = 0x4 + BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB = 0x5 + BPF_SOCK_OPS_NEEDS_ECN = 0x6 + BPF_SOCK_OPS_BASE_RTT = 0x7 + BPF_SOCK_OPS_RTO_CB = 0x8 + BPF_SOCK_OPS_RETRANS_CB = 0x9 + BPF_SOCK_OPS_STATE_CB = 0xa + BPF_SOCK_OPS_TCP_LISTEN_CB = 0xb + BPF_SOCK_OPS_RTT_CB = 0xc + BPF_TCP_ESTABLISHED = 0x1 + BPF_TCP_SYN_SENT = 0x2 + BPF_TCP_SYN_RECV = 0x3 + BPF_TCP_FIN_WAIT1 = 0x4 + BPF_TCP_FIN_WAIT2 = 0x5 + BPF_TCP_TIME_WAIT = 0x6 + BPF_TCP_CLOSE = 0x7 + BPF_TCP_CLOSE_WAIT = 0x8 + BPF_TCP_LAST_ACK = 0x9 + BPF_TCP_LISTEN = 0xa + BPF_TCP_CLOSING = 0xb + BPF_TCP_NEW_SYN_RECV = 0xc + BPF_TCP_MAX_STATES = 0xd + TCP_BPF_IW = 0x3e9 + TCP_BPF_SNDCWND_CLAMP = 0x3ea + BPF_DEVCG_ACC_MKNOD = 0x1 + BPF_DEVCG_ACC_READ = 0x2 + BPF_DEVCG_ACC_WRITE = 0x4 + BPF_DEVCG_DEV_BLOCK = 0x1 + BPF_DEVCG_DEV_CHAR = 0x2 + BPF_FIB_LOOKUP_DIRECT = 0x1 + BPF_FIB_LOOKUP_OUTPUT = 0x2 + BPF_FIB_LKUP_RET_SUCCESS = 0x0 + BPF_FIB_LKUP_RET_BLACKHOLE = 0x1 + BPF_FIB_LKUP_RET_UNREACHABLE = 0x2 + BPF_FIB_LKUP_RET_PROHIBIT = 0x3 + BPF_FIB_LKUP_RET_NOT_FWDED = 0x4 + BPF_FIB_LKUP_RET_FWD_DISABLED = 0x5 + BPF_FIB_LKUP_RET_UNSUPP_LWT = 0x6 + BPF_FIB_LKUP_RET_NO_NEIGH = 0x7 + BPF_FIB_LKUP_RET_FRAG_NEEDED = 0x8 + BPF_FD_TYPE_RAW_TRACEPOINT = 0x0 + BPF_FD_TYPE_TRACEPOINT = 0x1 + BPF_FD_TYPE_KPROBE = 0x2 + BPF_FD_TYPE_KRETPROBE = 0x3 + BPF_FD_TYPE_UPROBE = 0x4 + BPF_FD_TYPE_URETPROBE = 0x5 + BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = 0x1 + BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2 + BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = 0x4 ) const ( @@ -2205,7 +2810,7 @@ const ( DEVLINK_CMD_DPIPE_ENTRIES_GET = 0x20 DEVLINK_CMD_DPIPE_HEADERS_GET = 0x21 DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET = 0x22 - DEVLINK_CMD_MAX = 0x44 + DEVLINK_CMD_MAX = 0x48 DEVLINK_PORT_TYPE_NOTSET = 0x0 DEVLINK_PORT_TYPE_AUTO = 0x1 DEVLINK_PORT_TYPE_ETH = 0x2 @@ -2285,7 +2890,7 @@ const ( DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE = 0x3c DEVLINK_ATTR_PAD = 0x3d DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 0x3e - DEVLINK_ATTR_MAX = 0x8c + DEVLINK_ATTR_MAX = 0x94 DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE = 0x0 DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX = 0x1 DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT = 0x0 @@ -2343,3 +2948,54 @@ const ( NHA_GROUPS = 0x9 NHA_MASTER = 0xa ) + +const ( + CAN_RAW_FILTER = 0x1 + CAN_RAW_ERR_FILTER = 0x2 + CAN_RAW_LOOPBACK = 0x3 + CAN_RAW_RECV_OWN_MSGS = 0x4 + CAN_RAW_FD_FRAMES = 0x5 + CAN_RAW_JOIN_FILTERS = 0x6 +) + +type WatchdogInfo struct { + Options uint32 + Version uint32 + Identity [32]uint8 +} + +type PPSFData struct { + Info PPSKInfo + Timeout PPSKTime +} + +type PPSKParams struct { + Api_version int32 + Mode int32 + Assert_off_tu PPSKTime + Clear_off_tu PPSKTime +} + +type PPSKTime struct { + Sec int64 + Nsec int32 + Flags uint32 +} + +const ( + LWTUNNEL_ENCAP_NONE = 0x0 + LWTUNNEL_ENCAP_MPLS = 0x1 + LWTUNNEL_ENCAP_IP = 0x2 + LWTUNNEL_ENCAP_ILA = 0x3 + LWTUNNEL_ENCAP_IP6 = 0x4 + LWTUNNEL_ENCAP_SEG6 = 0x5 + LWTUNNEL_ENCAP_BPF = 0x6 + LWTUNNEL_ENCAP_SEG6_LOCAL = 0x7 + LWTUNNEL_ENCAP_RPL = 0x8 + LWTUNNEL_ENCAP_MAX = 0x8 + + MPLS_IPTUNNEL_UNSPEC = 0x0 + MPLS_IPTUNNEL_DST = 0x1 + MPLS_IPTUNNEL_TTL = 0x2 + MPLS_IPTUNNEL_MAX = 0x2 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 761b67c864..d54618aa61 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -117,6 +117,11 @@ type Flock_t struct { Pid int32 } +type DmNameList struct { + Dev uint64 + Next uint32 +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -597,3 +602,18 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 +} + +const ( + PPS_GETPARAMS = 0x800470a1 + PPS_SETPARAMS = 0x400470a2 + PPS_GETCAP = 0x800470a3 + PPS_FETCH = 0xc00470a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 201fb3482d..741d25be95 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -117,6 +117,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -612,3 +619,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x800870a1 + PPS_SETPARAMS = 0x400870a2 + PPS_GETCAP = 0x800870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index 8051b56108..e8d982c3df 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -121,6 +121,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -589,3 +596,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]uint8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x800470a1 + PPS_SETPARAMS = 0x400470a2 + PPS_GETCAP = 0x800470a3 + PPS_FETCH = 0xc00470a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index a936f21692..311cf2155d 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -118,6 +118,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -591,3 +598,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x800870a1 + PPS_SETPARAMS = 0x400870a2 + PPS_GETCAP = 0x800870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index aaca03dd7d..1312bdf77f 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -120,6 +120,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -595,3 +602,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400470a1 + PPS_SETPARAMS = 0x800470a2 + PPS_GETCAP = 0x400470a3 + PPS_FETCH = 0xc00470a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 2e7f3b8ca4..2a99348195 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -118,6 +118,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -594,3 +601,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400870a1 + PPS_SETPARAMS = 0x800870a2 + PPS_GETCAP = 0x400870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 16add5a257..f964307b29 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -118,6 +118,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -594,3 +601,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400870a1 + PPS_SETPARAMS = 0x800870a2 + PPS_GETCAP = 0x400870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 4ed2c8e54c..ca0fab2702 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -120,6 +120,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -595,3 +602,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400470a1 + PPS_SETPARAMS = 0x800470a2 + PPS_GETCAP = 0x400470a3 + PPS_FETCH = 0xc00470a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 7415190997..257e004247 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -119,6 +119,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -601,3 +608,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]uint8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400870a1 + PPS_SETPARAMS = 0x800870a2 + PPS_GETCAP = 0x400870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 046c2debd4..980dd31736 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -119,6 +119,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -601,3 +608,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]uint8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400870a1 + PPS_SETPARAMS = 0x800870a2 + PPS_GETCAP = 0x400870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 0f2f61a6ad..d9fdab20b8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -118,6 +118,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -619,3 +626,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]uint8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x800870a1 + PPS_SETPARAMS = 0x400870a2 + PPS_GETCAP = 0x800870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cca1b6be27..c25de8c679 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -117,6 +117,13 @@ type Flock_t struct { _ [4]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x6 FADV_NOREUSE = 0x7 @@ -615,3 +622,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x800870a1 + PPS_SETPARAMS = 0x400870a2 + PPS_GETCAP = 0x800870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 33a73bf183..97fca65340 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -121,6 +121,13 @@ type Flock_t struct { _ [2]byte } +type DmNameList struct { + Dev uint64 + Next uint32 + Name [0]byte + _ [4]byte +} + const ( FADV_DONTNEED = 0x4 FADV_NOREUSE = 0x5 @@ -596,3 +603,19 @@ type TIPCSIOCNodeIDReq struct { Peer uint32 Id [16]int8 } + +type PPSKInfo struct { + Assert_sequence uint32 + Clear_sequence uint32 + Assert_tu PPSKTime + Clear_tu PPSKTime + Current_mode int32 + _ [4]byte +} + +const ( + PPS_GETPARAMS = 0x400870a1 + PPS_SETPARAMS = 0x800870a2 + PPS_GETCAP = 0x400870a3 + PPS_FETCH = 0xc00870a4 +) diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go new file mode 100644 index 0000000000..992a1f8c01 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go @@ -0,0 +1,565 @@ +// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build mips64,openbsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ Timespec +} + +type Statfs_t struct { + F_flags uint32 + F_bsize uint32 + F_iosize uint32 + F_blocks uint64 + F_bfree uint64 + F_bavail int64 + F_files uint64 + F_ffree uint64 + F_favail int64 + F_syncwrites uint64 + F_syncreads uint64 + F_asyncwrites uint64 + F_asyncreads uint64 + F_fsid Fsid + F_namemax uint32 + F_owner uint32 + F_ctime uint64 + F_fstypename [16]int8 + F_mntonname [90]int8 + F_mntfromname [90]int8 + F_mntfromspec [90]int8 + _ [2]byte + Mount_info [160]byte +} + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 +} + +type Dirent struct { + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 +} + +type Fsid struct { + Val [2]int32 +} + +const ( + PathMax = 0x400 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [24]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + Iov *Iovec + Iovlen uint32 + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x20 + SizeofLinger = 0x8 + SizeofIPMreq = 0x8 + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter int16 + Flags uint16 + Fflags uint32 + Data int64 + Udata *byte +} + +type FdSet struct { + Bits [32]uint32 +} + +const ( + SizeofIfMsghdr = 0xa8 + SizeofIfData = 0x90 + SizeofIfaMsghdr = 0x18 + SizeofIfAnnounceMsghdr = 0x1a + SizeofRtMsghdr = 0x60 + SizeofRtMetrics = 0x38 +) + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Xflags int32 + Data IfData +} + +type IfData struct { + Type uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Mtu uint32 + Metric uint32 + Rdomain uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Oqdrops uint64 + Noproto uint64 + Capabilities uint32 + Lastchange Timeval +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Metric int32 +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + What uint16 + Name [16]int8 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Priority uint8 + Mpls uint8 + Addrs int32 + Flags int32 + Fmask int32 + Pid int32 + Seq int32 + Errno int32 + Inits uint32 + Rmx RtMetrics +} + +type RtMetrics struct { + Pksent uint64 + Expire int64 + Locks uint32 + Mtu uint32 + Refcnt uint32 + Hopcount uint32 + Recvpipe uint32 + Sendpipe uint32 + Ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Pad uint32 +} + +type Mclpool struct{} + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x8 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x14 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint32 + Drop uint32 +} + +type BpfProgram struct { + Len uint32 + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte +} + +type BpfTimeval struct { + Sec uint32 + Usec uint32 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_FOLLOW = 0x4 + AT_SYMLINK_NOFOLLOW = 0x2 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Sigset_t uint32 + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} + +const SizeofUvmexp = 0x158 + +type Uvmexp struct { + Pagesize int32 + Pagemask int32 + Pageshift int32 + Npages int32 + Free int32 + Active int32 + Inactive int32 + Paging int32 + Wired int32 + Zeropages int32 + Reserve_pagedaemon int32 + Reserve_kernel int32 + Unused01 int32 + Vnodepages int32 + Vtextpages int32 + Freemin int32 + Freetarg int32 + Inactarg int32 + Wiredmax int32 + Anonmin int32 + Vtextmin int32 + Vnodemin int32 + Anonminpct int32 + Vtextminpct int32 + Vnodeminpct int32 + Nswapdev int32 + Swpages int32 + Swpginuse int32 + Swpgonly int32 + Nswget int32 + Nanon int32 + Unused05 int32 + Unused06 int32 + Faults int32 + Traps int32 + Intrs int32 + Swtch int32 + Softs int32 + Syscalls int32 + Pageins int32 + Unused07 int32 + Unused08 int32 + Pgswapin int32 + Pgswapout int32 + Forks int32 + Forks_ppwait int32 + Forks_sharevm int32 + Pga_zerohit int32 + Pga_zeromiss int32 + Unused09 int32 + Fltnoram int32 + Fltnoanon int32 + Fltnoamap int32 + Fltpgwait int32 + Fltpgrele int32 + Fltrelck int32 + Fltrelckok int32 + Fltanget int32 + Fltanretry int32 + Fltamcopy int32 + Fltnamap int32 + Fltnomap int32 + Fltlget int32 + Fltget int32 + Flt_anon int32 + Flt_acow int32 + Flt_obj int32 + Flt_prcopy int32 + Flt_przero int32 + Pdwoke int32 + Pdrevs int32 + Pdswout int32 + Pdfreed int32 + Pdscans int32 + Pdanscan int32 + Pdobscan int32 + Pdreact int32 + Pdbusy int32 + Pdpageouts int32 + Pdpending int32 + Pddeact int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 + Fpswtch int32 + Kmapent int32 +} + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index 23ed9fe51d..db817f3ba8 100644 --- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -88,7 +88,6 @@ type Stat_t struct { Mtim Timespec Ctim Timespec Blksize int32 - _ [4]byte Blocks int64 Fstype [16]int8 } @@ -96,7 +95,6 @@ type Stat_t struct { type Flock_t struct { Type int16 Whence int16 - _ [4]byte Start int64 Len int64 Sysid int32 @@ -138,12 +136,12 @@ type RawSockaddrInet4 struct { } type RawSockaddrInet6 struct { - Family uint16 - Port uint16 - Flowinfo uint32 - Addr [16]byte /* in6_addr */ - Scope_id uint32 - X__sin6_src_id uint32 + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 + _ uint32 } type RawSockaddrUnix struct { @@ -196,10 +194,8 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen int32 - _ [4]byte Accrights *int8 Accrightslen int32 _ [4]byte @@ -228,7 +224,7 @@ type IPv6MTUInfo struct { } type ICMPv6Filter struct { - X__icmp6_filt [8]uint32 + Filt [8]uint32 } const ( @@ -291,7 +287,6 @@ type IfMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Data IfData } @@ -299,7 +294,6 @@ type IfData struct { Type uint8 Addrlen uint8 Hdrlen uint8 - _ [1]byte Mtu uint32 Metric uint32 Baudrate uint32 @@ -324,7 +318,6 @@ type IfaMsghdr struct { Addrs int32 Flags int32 Index uint16 - _ [2]byte Metric int32 } @@ -333,7 +326,6 @@ type RtMsghdr struct { Version uint8 Type uint8 Index uint16 - _ [2]byte Flags int32 Addrs int32 Pid int32 @@ -371,15 +363,14 @@ type BpfVersion struct { } type BpfStat struct { - Recv uint64 - Drop uint64 - Capt uint64 - Padding [13]uint64 + Recv uint64 + Drop uint64 + Capt uint64 + _ [13]uint64 } type BpfProgram struct { Len uint32 - _ [4]byte Insns *BpfInsn } diff --git a/src/cmd/vendor/golang.org/x/sys/windows/dll_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/dll_windows.go index d777113415..115341fba6 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/dll_windows.go @@ -32,6 +32,8 @@ type DLLError struct { func (e *DLLError) Error() string { return e.Msg } +func (e *DLLError) Unwrap() error { return e.Err } + // A DLL implements access to a single DLL. type DLL struct { Name string @@ -104,6 +106,35 @@ func (d *DLL) MustFindProc(name string) *Proc { return p } +// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) { + a, e := GetProcAddressByOrdinal(d.Handle, ordinal) + name := "#" + itoa(int(ordinal)) + if e != nil { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails. +func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc { + p, e := d.FindProcByOrdinal(ordinal) + if e != nil { + panic(e) + } + return p +} + // Release unloads DLL d from memory. func (d *DLL) Release() (err error) { return FreeLibrary(d.Handle) @@ -360,7 +391,6 @@ func loadLibraryEx(name string, system bool) (*DLL, error) { var flags uintptr if system { if canDoSearchSystem32() { - const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 flags = LOAD_LIBRARY_SEARCH_SYSTEM32 } else if isBaseName(name) { // WindowsXP or unpatched Windows machine diff --git a/src/cmd/vendor/golang.org/x/sys/windows/env_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/env_windows.go index f482a9fab3..92ac05ff4e 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/env_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/env_windows.go @@ -8,7 +8,6 @@ package windows import ( "syscall" - "unicode/utf16" "unsafe" ) @@ -40,17 +39,11 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { defer DestroyEnvironmentBlock(block) blockp := uintptr(unsafe.Pointer(block)) for { - entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:] - for i, v := range entry { - if v == 0 { - entry = entry[:i] - break - } - } + entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp))) if len(entry) == 0 { break } - env = append(env, string(utf16.Decode(entry))) + env = append(env, entry) blockp += 2 * (uintptr(len(entry)) + 1) } return env, nil diff --git a/src/cmd/vendor/golang.org/x/sys/windows/memory_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/memory_windows.go index f80a4204f0..1adb60739a 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/memory_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/memory_windows.go @@ -16,11 +16,22 @@ const ( MEM_RESET_UNDO = 0x01000000 MEM_LARGE_PAGES = 0x20000000 - PAGE_NOACCESS = 0x01 - PAGE_READONLY = 0x02 - PAGE_READWRITE = 0x04 - PAGE_WRITECOPY = 0x08 - PAGE_EXECUTE_READ = 0x20 - PAGE_EXECUTE_READWRITE = 0x40 - PAGE_EXECUTE_WRITECOPY = 0x80 + PAGE_NOACCESS = 0x00000001 + PAGE_READONLY = 0x00000002 + PAGE_READWRITE = 0x00000004 + PAGE_WRITECOPY = 0x00000008 + PAGE_EXECUTE = 0x00000010 + PAGE_EXECUTE_READ = 0x00000020 + PAGE_EXECUTE_READWRITE = 0x00000040 + PAGE_EXECUTE_WRITECOPY = 0x00000080 + PAGE_GUARD = 0x00000100 + PAGE_NOCACHE = 0x00000200 + PAGE_WRITECOMBINE = 0x00000400 + PAGE_TARGETS_INVALID = 0x40000000 + PAGE_TARGETS_NO_UPDATE = 0x40000000 + + QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002 + QUOTA_LIMITS_HARDWS_MIN_ENABLE = 0x00000001 + QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008 + QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004 ) diff --git a/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go index 4b6eff1868..69eb462c59 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/security_windows.go @@ -7,6 +7,8 @@ package windows import ( "syscall" "unsafe" + + "golang.org/x/sys/internal/unsafeheader" ) const ( @@ -622,6 +624,7 @@ func (tml *Tokenmandatorylabel) Size() uint32 { // Authorization Functions //sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership +//sys isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted //sys OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken //sys OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken //sys ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf @@ -835,6 +838,16 @@ func (t Token) IsMember(sid *SID) (bool, error) { return b != 0, nil } +// IsRestricted reports whether the access token t is a restricted token. +func (t Token) IsRestricted() (isRestricted bool, err error) { + isRestricted, err = isTokenRestricted(t) + if !isRestricted && err == syscall.EINVAL { + // If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token. + err = nil + } + return +} + const ( WTS_CONSOLE_CONNECT = 0x1 WTS_CONSOLE_DISCONNECT = 0x2 @@ -1101,9 +1114,10 @@ type OBJECTS_AND_NAME struct { } //sys getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetSecurityInfo -//sys SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) = advapi32.SetSecurityInfo +//sys SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo //sys getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetNamedSecurityInfoW //sys SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW +//sys SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity //sys buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) = advapi32.BuildSecurityDescriptorW //sys initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor @@ -1229,7 +1243,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string { return "" } defer LocalFree(Handle(unsafe.Pointer(sddl))) - return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(sddl))[:]) + return UTF16PtrToString(sddl) } // ToAbsolute converts a self-relative security descriptor into an absolute one. @@ -1307,9 +1321,17 @@ func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURIT } func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR { - sdBytes := make([]byte, selfRelativeSD.Length()) - copy(sdBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(selfRelativeSD))[:len(sdBytes)]) - return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&sdBytes[0])) + sdLen := (int)(selfRelativeSD.Length()) + + var src []byte + h := (*unsafeheader.Slice)(unsafe.Pointer(&src)) + h.Data = unsafe.Pointer(selfRelativeSD) + h.Len = sdLen + h.Cap = sdLen + + dst := make([]byte, sdLen) + copy(dst, src) + return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0])) } // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a @@ -1391,6 +1413,6 @@ func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL } defer LocalFree(Handle(unsafe.Pointer(winHeapACL))) aclBytes := make([]byte, winHeapACL.aclSize) - copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes)]) + copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)]) return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil } diff --git a/src/cmd/vendor/golang.org/x/sys/windows/service.go b/src/cmd/vendor/golang.org/x/sys/windows/service.go index 847e00bc99..b269850d06 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/service.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/service.go @@ -65,6 +65,7 @@ const ( SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 SERVICE_ACCEPT_POWEREVENT = 64 SERVICE_ACCEPT_SESSIONCHANGE = 128 + SERVICE_ACCEPT_PRESHUTDOWN = 256 SERVICE_CONTROL_STOP = 1 SERVICE_CONTROL_PAUSE = 2 @@ -80,6 +81,7 @@ const ( SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 SERVICE_CONTROL_POWEREVENT = 13 SERVICE_CONTROL_SESSIONCHANGE = 14 + SERVICE_CONTROL_PRESHUTDOWN = 15 SERVICE_ACTIVE = 1 SERVICE_INACTIVE = 2 @@ -126,6 +128,10 @@ const ( SERVICE_NOTIFY_CREATED = 0x00000080 SERVICE_NOTIFY_DELETED = 0x00000100 SERVICE_NOTIFY_DELETE_PENDING = 0x00000200 + + SC_EVENT_DATABASE_CHANGE = 0 + SC_EVENT_PROPERTY_CHANGE = 1 + SC_EVENT_STATUS_CHANGE = 2 ) type SERVICE_STATUS struct { @@ -227,3 +233,5 @@ type QUERY_SERVICE_LOCK_STATUS struct { //sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW //sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx //sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW +//sys SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) = sechost.SubscribeServiceChangeNotifications? +//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications? diff --git a/src/cmd/vendor/golang.org/x/sys/windows/setupapierrors_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/setupapierrors_windows.go new file mode 100644 index 0000000000..1681810e04 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/windows/setupapierrors_windows.go @@ -0,0 +1,100 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import "syscall" + +const ( + ERROR_EXPECTED_SECTION_NAME syscall.Errno = 0x20000000 | 0xC0000000 | 0 + ERROR_BAD_SECTION_NAME_LINE syscall.Errno = 0x20000000 | 0xC0000000 | 1 + ERROR_SECTION_NAME_TOO_LONG syscall.Errno = 0x20000000 | 0xC0000000 | 2 + ERROR_GENERAL_SYNTAX syscall.Errno = 0x20000000 | 0xC0000000 | 3 + ERROR_WRONG_INF_STYLE syscall.Errno = 0x20000000 | 0xC0000000 | 0x100 + ERROR_SECTION_NOT_FOUND syscall.Errno = 0x20000000 | 0xC0000000 | 0x101 + ERROR_LINE_NOT_FOUND syscall.Errno = 0x20000000 | 0xC0000000 | 0x102 + ERROR_NO_BACKUP syscall.Errno = 0x20000000 | 0xC0000000 | 0x103 + ERROR_NO_ASSOCIATED_CLASS syscall.Errno = 0x20000000 | 0xC0000000 | 0x200 + ERROR_CLASS_MISMATCH syscall.Errno = 0x20000000 | 0xC0000000 | 0x201 + ERROR_DUPLICATE_FOUND syscall.Errno = 0x20000000 | 0xC0000000 | 0x202 + ERROR_NO_DRIVER_SELECTED syscall.Errno = 0x20000000 | 0xC0000000 | 0x203 + ERROR_KEY_DOES_NOT_EXIST syscall.Errno = 0x20000000 | 0xC0000000 | 0x204 + ERROR_INVALID_DEVINST_NAME syscall.Errno = 0x20000000 | 0xC0000000 | 0x205 + ERROR_INVALID_CLASS syscall.Errno = 0x20000000 | 0xC0000000 | 0x206 + ERROR_DEVINST_ALREADY_EXISTS syscall.Errno = 0x20000000 | 0xC0000000 | 0x207 + ERROR_DEVINFO_NOT_REGISTERED syscall.Errno = 0x20000000 | 0xC0000000 | 0x208 + ERROR_INVALID_REG_PROPERTY syscall.Errno = 0x20000000 | 0xC0000000 | 0x209 + ERROR_NO_INF syscall.Errno = 0x20000000 | 0xC0000000 | 0x20A + ERROR_NO_SUCH_DEVINST syscall.Errno = 0x20000000 | 0xC0000000 | 0x20B + ERROR_CANT_LOAD_CLASS_ICON syscall.Errno = 0x20000000 | 0xC0000000 | 0x20C + ERROR_INVALID_CLASS_INSTALLER syscall.Errno = 0x20000000 | 0xC0000000 | 0x20D + ERROR_DI_DO_DEFAULT syscall.Errno = 0x20000000 | 0xC0000000 | 0x20E + ERROR_DI_NOFILECOPY syscall.Errno = 0x20000000 | 0xC0000000 | 0x20F + ERROR_INVALID_HWPROFILE syscall.Errno = 0x20000000 | 0xC0000000 | 0x210 + ERROR_NO_DEVICE_SELECTED syscall.Errno = 0x20000000 | 0xC0000000 | 0x211 + ERROR_DEVINFO_LIST_LOCKED syscall.Errno = 0x20000000 | 0xC0000000 | 0x212 + ERROR_DEVINFO_DATA_LOCKED syscall.Errno = 0x20000000 | 0xC0000000 | 0x213 + ERROR_DI_BAD_PATH syscall.Errno = 0x20000000 | 0xC0000000 | 0x214 + ERROR_NO_CLASSINSTALL_PARAMS syscall.Errno = 0x20000000 | 0xC0000000 | 0x215 + ERROR_FILEQUEUE_LOCKED syscall.Errno = 0x20000000 | 0xC0000000 | 0x216 + ERROR_BAD_SERVICE_INSTALLSECT syscall.Errno = 0x20000000 | 0xC0000000 | 0x217 + ERROR_NO_CLASS_DRIVER_LIST syscall.Errno = 0x20000000 | 0xC0000000 | 0x218 + ERROR_NO_ASSOCIATED_SERVICE syscall.Errno = 0x20000000 | 0xC0000000 | 0x219 + ERROR_NO_DEFAULT_DEVICE_INTERFACE syscall.Errno = 0x20000000 | 0xC0000000 | 0x21A + ERROR_DEVICE_INTERFACE_ACTIVE syscall.Errno = 0x20000000 | 0xC0000000 | 0x21B + ERROR_DEVICE_INTERFACE_REMOVED syscall.Errno = 0x20000000 | 0xC0000000 | 0x21C + ERROR_BAD_INTERFACE_INSTALLSECT syscall.Errno = 0x20000000 | 0xC0000000 | 0x21D + ERROR_NO_SUCH_INTERFACE_CLASS syscall.Errno = 0x20000000 | 0xC0000000 | 0x21E + ERROR_INVALID_REFERENCE_STRING syscall.Errno = 0x20000000 | 0xC0000000 | 0x21F + ERROR_INVALID_MACHINENAME syscall.Errno = 0x20000000 | 0xC0000000 | 0x220 + ERROR_REMOTE_COMM_FAILURE syscall.Errno = 0x20000000 | 0xC0000000 | 0x221 + ERROR_MACHINE_UNAVAILABLE syscall.Errno = 0x20000000 | 0xC0000000 | 0x222 + ERROR_NO_CONFIGMGR_SERVICES syscall.Errno = 0x20000000 | 0xC0000000 | 0x223 + ERROR_INVALID_PROPPAGE_PROVIDER syscall.Errno = 0x20000000 | 0xC0000000 | 0x224 + ERROR_NO_SUCH_DEVICE_INTERFACE syscall.Errno = 0x20000000 | 0xC0000000 | 0x225 + ERROR_DI_POSTPROCESSING_REQUIRED syscall.Errno = 0x20000000 | 0xC0000000 | 0x226 + ERROR_INVALID_COINSTALLER syscall.Errno = 0x20000000 | 0xC0000000 | 0x227 + ERROR_NO_COMPAT_DRIVERS syscall.Errno = 0x20000000 | 0xC0000000 | 0x228 + ERROR_NO_DEVICE_ICON syscall.Errno = 0x20000000 | 0xC0000000 | 0x229 + ERROR_INVALID_INF_LOGCONFIG syscall.Errno = 0x20000000 | 0xC0000000 | 0x22A + ERROR_DI_DONT_INSTALL syscall.Errno = 0x20000000 | 0xC0000000 | 0x22B + ERROR_INVALID_FILTER_DRIVER syscall.Errno = 0x20000000 | 0xC0000000 | 0x22C + ERROR_NON_WINDOWS_NT_DRIVER syscall.Errno = 0x20000000 | 0xC0000000 | 0x22D + ERROR_NON_WINDOWS_DRIVER syscall.Errno = 0x20000000 | 0xC0000000 | 0x22E + ERROR_NO_CATALOG_FOR_OEM_INF syscall.Errno = 0x20000000 | 0xC0000000 | 0x22F + ERROR_DEVINSTALL_QUEUE_NONNATIVE syscall.Errno = 0x20000000 | 0xC0000000 | 0x230 + ERROR_NOT_DISABLEABLE syscall.Errno = 0x20000000 | 0xC0000000 | 0x231 + ERROR_CANT_REMOVE_DEVINST syscall.Errno = 0x20000000 | 0xC0000000 | 0x232 + ERROR_INVALID_TARGET syscall.Errno = 0x20000000 | 0xC0000000 | 0x233 + ERROR_DRIVER_NONNATIVE syscall.Errno = 0x20000000 | 0xC0000000 | 0x234 + ERROR_IN_WOW64 syscall.Errno = 0x20000000 | 0xC0000000 | 0x235 + ERROR_SET_SYSTEM_RESTORE_POINT syscall.Errno = 0x20000000 | 0xC0000000 | 0x236 + ERROR_SCE_DISABLED syscall.Errno = 0x20000000 | 0xC0000000 | 0x238 + ERROR_UNKNOWN_EXCEPTION syscall.Errno = 0x20000000 | 0xC0000000 | 0x239 + ERROR_PNP_REGISTRY_ERROR syscall.Errno = 0x20000000 | 0xC0000000 | 0x23A + ERROR_REMOTE_REQUEST_UNSUPPORTED syscall.Errno = 0x20000000 | 0xC0000000 | 0x23B + ERROR_NOT_AN_INSTALLED_OEM_INF syscall.Errno = 0x20000000 | 0xC0000000 | 0x23C + ERROR_INF_IN_USE_BY_DEVICES syscall.Errno = 0x20000000 | 0xC0000000 | 0x23D + ERROR_DI_FUNCTION_OBSOLETE syscall.Errno = 0x20000000 | 0xC0000000 | 0x23E + ERROR_NO_AUTHENTICODE_CATALOG syscall.Errno = 0x20000000 | 0xC0000000 | 0x23F + ERROR_AUTHENTICODE_DISALLOWED syscall.Errno = 0x20000000 | 0xC0000000 | 0x240 + ERROR_AUTHENTICODE_TRUSTED_PUBLISHER syscall.Errno = 0x20000000 | 0xC0000000 | 0x241 + ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED syscall.Errno = 0x20000000 | 0xC0000000 | 0x242 + ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED syscall.Errno = 0x20000000 | 0xC0000000 | 0x243 + ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH syscall.Errno = 0x20000000 | 0xC0000000 | 0x244 + ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE syscall.Errno = 0x20000000 | 0xC0000000 | 0x245 + ERROR_DEVICE_INSTALLER_NOT_READY syscall.Errno = 0x20000000 | 0xC0000000 | 0x246 + ERROR_DRIVER_STORE_ADD_FAILED syscall.Errno = 0x20000000 | 0xC0000000 | 0x247 + ERROR_DEVICE_INSTALL_BLOCKED syscall.Errno = 0x20000000 | 0xC0000000 | 0x248 + ERROR_DRIVER_INSTALL_BLOCKED syscall.Errno = 0x20000000 | 0xC0000000 | 0x249 + ERROR_WRONG_INF_TYPE syscall.Errno = 0x20000000 | 0xC0000000 | 0x24A + ERROR_FILE_HASH_NOT_IN_CATALOG syscall.Errno = 0x20000000 | 0xC0000000 | 0x24B + ERROR_DRIVER_STORE_DELETE_FAILED syscall.Errno = 0x20000000 | 0xC0000000 | 0x24C + ERROR_UNRECOVERABLE_STACK_OVERFLOW syscall.Errno = 0x20000000 | 0xC0000000 | 0x300 + EXCEPTION_SPAPI_UNRECOVERABLE_STACK_OVERFLOW syscall.Errno = ERROR_UNRECOVERABLE_STACK_OVERFLOW + ERROR_NO_DEFAULT_INTERFACE_DEVICE syscall.Errno = ERROR_NO_DEFAULT_DEVICE_INTERFACE + ERROR_INTERFACE_DEVICE_ACTIVE syscall.Errno = ERROR_DEVICE_INTERFACE_ACTIVE + ERROR_INTERFACE_DEVICE_REMOVED syscall.Errno = ERROR_DEVICE_INTERFACE_REMOVED + ERROR_NO_SUCH_INTERFACE_DEVICE syscall.Errno = ERROR_NO_SUCH_DEVICE_INTERFACE +) diff --git a/src/cmd/vendor/golang.org/x/sys/windows/syscall.go b/src/cmd/vendor/golang.org/x/sys/windows/syscall.go index af828a91bc..6122f557a0 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/syscall.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/syscall.go @@ -25,17 +25,20 @@ package windows // import "golang.org/x/sys/windows" import ( + "bytes" + "strings" "syscall" + "unsafe" + + "golang.org/x/sys/internal/unsafeheader" ) // ByteSliceFromString returns a NUL-terminated slice of bytes // containing the text of s. If s contains a NUL byte at any // location, it returns (nil, syscall.EINVAL). func ByteSliceFromString(s string) ([]byte, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, syscall.EINVAL - } + if strings.IndexByte(s, 0) != -1 { + return nil, syscall.EINVAL } a := make([]byte, len(s)+1) copy(a, s) @@ -53,6 +56,41 @@ func BytePtrFromString(s string) (*byte, error) { return &a[0], nil } +// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any +// bytes after the NUL removed. +func ByteSliceToString(s []byte) string { + if i := bytes.IndexByte(s, 0); i != -1 { + s = s[:i] + } + return string(s) +} + +// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string. +// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated +// at a zero byte; if the zero byte is not present, the program may crash. +func BytePtrToString(p *byte) string { + if p == nil { + return "" + } + if *p == 0 { + return "" + } + + // Find NUL terminator. + n := 0 + for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ { + ptr = unsafe.Pointer(uintptr(ptr) + 1) + } + + var s []byte + h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) + h.Data = unsafe.Pointer(p) + h.Len = n + h.Cap = n + + return string(s) +} + // Single-word zero for use when we need a valid pointer to 0 bytes. // See mksyscall.pl. var _zero uintptr diff --git a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go index 053d664d0b..c71bad127d 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -13,6 +13,8 @@ import ( "time" "unicode/utf16" "unsafe" + + "golang.org/x/sys/internal/unsafeheader" ) type Handle uintptr @@ -90,11 +92,11 @@ func UTF16FromString(s string) ([]uint16, error) { } // UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, -// with a terminating NUL removed. +// with a terminating NUL and any bytes after the NUL removed. func UTF16ToString(s []uint16) string { for i, v := range s { if v == 0 { - s = s[0:i] + s = s[:i] break } } @@ -117,6 +119,32 @@ func UTF16PtrFromString(s string) (*uint16, error) { return &a[0], nil } +// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string. +// If the pointer is nil, it returns the empty string. It assumes that the UTF-16 sequence is terminated +// at a zero word; if the zero word is not present, the program may crash. +func UTF16PtrToString(p *uint16) string { + if p == nil { + return "" + } + if *p == 0 { + return "" + } + + // Find NUL terminator. + n := 0 + for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { + ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) + } + + var s []uint16 + h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) + h.Data = unsafe.Pointer(p) + h.Len = n + h.Cap = n + + return string(utf16.Decode(s)) +} + func Getpagesize() int { return 4096 } // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. @@ -142,10 +170,13 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) //sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW //sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW +//sys SetDefaultDllDirectories(directoryFlags uint32) (err error) +//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW //sys GetVersion() (ver uint32, err error) //sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW //sys ExitProcess(exitcode uint32) //sys IsWow64Process(handle Handle, isWow64 *bool) (err error) = IsWow64Process +//sys IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) = IsWow64Process2? //sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW //sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) //sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) @@ -159,6 +190,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys FindClose(handle Handle) (err error) //sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) //sys GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) +//sys SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) //sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW //sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW //sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW @@ -215,6 +247,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW //sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW //sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW +//sys GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW //sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW //sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) //sys UnmapViewOfFile(addr uintptr) (err error) @@ -227,10 +260,11 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile //sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW //sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW -//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore +//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore //sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore //sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore //sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore +//sys CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore //sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain //sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain //sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext @@ -242,9 +276,11 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW //sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW //sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId +//sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId //sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo +//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot @@ -275,11 +311,14 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys ResumeThread(thread Handle) (ret uint32, err error) [failretval==0xffffffff] = kernel32.ResumeThread //sys SetPriorityClass(process Handle, priorityClass uint32) (err error) = kernel32.SetPriorityClass //sys GetPriorityClass(process Handle) (ret uint32, err error) = kernel32.GetPriorityClass +//sys QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) = kernel32.QueryInformationJobObject //sys SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) //sys GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) //sys GetProcessId(process Handle) (id uint32, err error) //sys OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) //sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost +//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) +//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) // Volume Management Functions //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW @@ -357,11 +396,7 @@ func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) proc = uintptr(r0) if proc == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -1058,11 +1093,7 @@ func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlap } r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return err } @@ -1074,11 +1105,7 @@ func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overl } r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return err } @@ -1181,7 +1208,12 @@ type IPv6Mreq struct { Interface uint32 } -func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS } +func GetsockoptInt(fd Handle, level, opt int) (int, error) { + v := int32(0) + l := int32(unsafe.Sizeof(v)) + err := Getsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), &l) + return int(v), err +} func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} @@ -1378,7 +1410,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e return "", err } defer CoTaskMemFree(unsafe.Pointer(p)) - return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]), nil + return UTF16PtrToString(p), nil } // RtlGetVersion returns the version of the underlying operating system, ignoring @@ -1452,3 +1484,7 @@ func getUILanguages(flags uint32, f func(flags uint32, numLanguages *uint32, buf return languages, nil } } + +func SetConsoleCursorPosition(console Handle, position Coord) error { + return setConsoleCursorPosition(console, *((*uint32)(unsafe.Pointer(&position)))) +} diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go index 809fff0b49..265d797cac 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go @@ -1584,18 +1584,6 @@ const ( JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001 ) -type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { - PerProcessUserTimeLimit int64 - PerJobUserTimeLimit int64 - LimitFlags uint32 - MinimumWorkingSetSize uintptr - MaximumWorkingSetSize uintptr - ActiveProcessLimit uint32 - Affinity uintptr - PriorityClass uint32 - SchedulingClass uint32 -} - type IO_COUNTERS struct { ReadOperationCount uint64 WriteOperationCount uint64 @@ -1784,3 +1772,51 @@ const ( MUI_LANGUAGE_INSTALLED = 0x20 MUI_LANGUAGE_LICENSED = 0x40 ) + +// FILE_INFO_BY_HANDLE_CLASS constants for SetFileInformationByHandle/GetFileInformationByHandleEx +const ( + FileBasicInfo = 0 + FileStandardInfo = 1 + FileNameInfo = 2 + FileRenameInfo = 3 + FileDispositionInfo = 4 + FileAllocationInfo = 5 + FileEndOfFileInfo = 6 + FileStreamInfo = 7 + FileCompressionInfo = 8 + FileAttributeTagInfo = 9 + FileIdBothDirectoryInfo = 10 + FileIdBothDirectoryRestartInfo = 11 + FileIoPriorityHintInfo = 12 + FileRemoteProtocolInfo = 13 + FileFullDirectoryInfo = 14 + FileFullDirectoryRestartInfo = 15 + FileStorageInfo = 16 + FileAlignmentInfo = 17 + FileIdInfo = 18 + FileIdExtdDirectoryInfo = 19 + FileIdExtdDirectoryRestartInfo = 20 + FileDispositionInfoEx = 21 + FileRenameInfoEx = 22 + FileCaseSensitiveInfo = 23 + FileNormalizedNameInfo = 24 +) + +// LoadLibrary flags for determining from where to search for a DLL +const ( + DONT_RESOLVE_DLL_REFERENCES = 0x1 + LOAD_LIBRARY_AS_DATAFILE = 0x2 + LOAD_WITH_ALTERED_SEARCH_PATH = 0x8 + LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x10 + LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x20 + LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x40 + LOAD_LIBRARY_REQUIRE_SIGNED_TARGET = 0x80 + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100 + LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x200 + LOAD_LIBRARY_SEARCH_USER_DIRS = 0x400 + LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x800 + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000 + LOAD_LIBRARY_SAFE_CURRENT_DIRS = 0x00002000 + LOAD_LIBRARY_SEARCH_SYSTEM32_NO_FORWARDER = 0x00004000 + LOAD_LIBRARY_OS_INTEGRITY_CONTINUITY = 0x00008000 +) diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_386.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_386.go index fe0ddd0316..8bce3e2fc1 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_386.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_386.go @@ -20,3 +20,16 @@ type Servent struct { Port uint16 Proto *byte } + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 + _ uint32 // pad to 8 byte boundary +} diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_amd64.go index 7e154c2df2..fdddc0c70a 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_amd64.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_amd64.go @@ -20,3 +20,15 @@ type Servent struct { Proto *byte Port uint16 } + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 +} diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm.go index 74571e3600..321872c3e0 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm.go @@ -20,3 +20,16 @@ type Servent struct { Port uint16 Proto *byte } + +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags uint32 + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass uint32 + SchedulingClass uint32 + _ uint32 // pad to 8 byte boundary +} diff --git a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 2aa4fa642a..a933c0ee37 100644 --- a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -17,6 +17,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -24,7 +25,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -36,2063 +37,1634 @@ func errnoErr(e syscall.Errno) error { var ( modadvapi32 = NewLazySystemDLL("advapi32.dll") + modcrypt32 = NewLazySystemDLL("crypt32.dll") + moddnsapi = NewLazySystemDLL("dnsapi.dll") + modiphlpapi = NewLazySystemDLL("iphlpapi.dll") modkernel32 = NewLazySystemDLL("kernel32.dll") - modshell32 = NewLazySystemDLL("shell32.dll") - moduserenv = NewLazySystemDLL("userenv.dll") modmswsock = NewLazySystemDLL("mswsock.dll") - modcrypt32 = NewLazySystemDLL("crypt32.dll") - moduser32 = NewLazySystemDLL("user32.dll") - modole32 = NewLazySystemDLL("ole32.dll") + modnetapi32 = NewLazySystemDLL("netapi32.dll") modntdll = NewLazySystemDLL("ntdll.dll") + modole32 = NewLazySystemDLL("ole32.dll") modpsapi = NewLazySystemDLL("psapi.dll") - modws2_32 = NewLazySystemDLL("ws2_32.dll") - moddnsapi = NewLazySystemDLL("dnsapi.dll") - modiphlpapi = NewLazySystemDLL("iphlpapi.dll") + modsechost = NewLazySystemDLL("sechost.dll") modsecur32 = NewLazySystemDLL("secur32.dll") - modnetapi32 = NewLazySystemDLL("netapi32.dll") + modshell32 = NewLazySystemDLL("shell32.dll") + moduser32 = NewLazySystemDLL("user32.dll") + moduserenv = NewLazySystemDLL("userenv.dll") + modws2_32 = NewLazySystemDLL("ws2_32.dll") modwtsapi32 = NewLazySystemDLL("wtsapi32.dll") - procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") - procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") - procReportEventW = modadvapi32.NewProc("ReportEventW") - procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") + procAdjustTokenGroups = modadvapi32.NewProc("AdjustTokenGroups") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") + procBuildSecurityDescriptorW = modadvapi32.NewProc("BuildSecurityDescriptorW") + procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") + procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") + procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") + procControlService = modadvapi32.NewProc("ControlService") + procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") + procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") + procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") + procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") + procCopySid = modadvapi32.NewProc("CopySid") procCreateServiceW = modadvapi32.NewProc("CreateServiceW") - procOpenServiceW = modadvapi32.NewProc("OpenServiceW") + procCreateWellKnownSid = modadvapi32.NewProc("CreateWellKnownSid") + procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") + procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") + procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") procDeleteService = modadvapi32.NewProc("DeleteService") - procStartServiceW = modadvapi32.NewProc("StartServiceW") - procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") - procQueryServiceLockStatusW = modadvapi32.NewProc("QueryServiceLockStatusW") - procControlService = modadvapi32.NewProc("ControlService") - procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") - procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") - procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") - procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") - procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") - procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") + procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") - procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx") + procEqualSid = modadvapi32.NewProc("EqualSid") + procFreeSid = modadvapi32.NewProc("FreeSid") + procGetLengthSid = modadvapi32.NewProc("GetLengthSid") + procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") + procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") + procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl") + procGetSecurityDescriptorGroup = modadvapi32.NewProc("GetSecurityDescriptorGroup") + procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") + procGetSecurityDescriptorOwner = modadvapi32.NewProc("GetSecurityDescriptorOwner") + procGetSecurityDescriptorRMControl = modadvapi32.NewProc("GetSecurityDescriptorRMControl") + procGetSecurityDescriptorSacl = modadvapi32.NewProc("GetSecurityDescriptorSacl") + procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo") + procGetSidIdentifierAuthority = modadvapi32.NewProc("GetSidIdentifierAuthority") + procGetSidSubAuthority = modadvapi32.NewProc("GetSidSubAuthority") + procGetSidSubAuthorityCount = modadvapi32.NewProc("GetSidSubAuthorityCount") + procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") + procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") + procInitializeSecurityDescriptor = modadvapi32.NewProc("InitializeSecurityDescriptor") + procInitiateSystemShutdownExW = modadvapi32.NewProc("InitiateSystemShutdownExW") + procIsTokenRestricted = modadvapi32.NewProc("IsTokenRestricted") + procIsValidSecurityDescriptor = modadvapi32.NewProc("IsValidSecurityDescriptor") + procIsValidSid = modadvapi32.NewProc("IsValidSid") + procIsWellKnownSid = modadvapi32.NewProc("IsWellKnownSid") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procMakeAbsoluteSD = modadvapi32.NewProc("MakeAbsoluteSD") + procMakeSelfRelativeSD = modadvapi32.NewProc("MakeSelfRelativeSD") procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW") - procGetLastError = modkernel32.NewProc("GetLastError") - procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") - procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") - procFreeLibrary = modkernel32.NewProc("FreeLibrary") - procGetProcAddress = modkernel32.NewProc("GetProcAddress") - procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") - procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") - procGetVersion = modkernel32.NewProc("GetVersion") - procFormatMessageW = modkernel32.NewProc("FormatMessageW") - procExitProcess = modkernel32.NewProc("ExitProcess") - procIsWow64Process = modkernel32.NewProc("IsWow64Process") - procCreateFileW = modkernel32.NewProc("CreateFileW") - procReadFile = modkernel32.NewProc("ReadFile") - procWriteFile = modkernel32.NewProc("WriteFile") - procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") - procSetFilePointer = modkernel32.NewProc("SetFilePointer") - procCloseHandle = modkernel32.NewProc("CloseHandle") - procGetStdHandle = modkernel32.NewProc("GetStdHandle") - procSetStdHandle = modkernel32.NewProc("SetStdHandle") - procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") - procFindNextFileW = modkernel32.NewProc("FindNextFileW") - procFindClose = modkernel32.NewProc("FindClose") - procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") - procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") - procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") - procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") - procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") - procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") - procDeleteFileW = modkernel32.NewProc("DeleteFileW") - procMoveFileW = modkernel32.NewProc("MoveFileW") - procMoveFileExW = modkernel32.NewProc("MoveFileExW") - procLockFileEx = modkernel32.NewProc("LockFileEx") - procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") - procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") - procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") - procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") - procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") - procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") - procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") - procCancelIo = modkernel32.NewProc("CancelIo") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procCreateProcessW = modkernel32.NewProc("CreateProcessW") - procOpenProcess = modkernel32.NewProc("OpenProcess") - procShellExecuteW = modshell32.NewProc("ShellExecuteW") - procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") - procTerminateProcess = modkernel32.NewProc("TerminateProcess") - procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") - procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") - procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") - procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") - procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") - procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects") - procGetTempPathW = modkernel32.NewProc("GetTempPathW") - procCreatePipe = modkernel32.NewProc("CreatePipe") - procGetFileType = modkernel32.NewProc("GetFileType") - procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") - procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") - procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") - procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") - procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") - procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") - procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") - procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") - procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") - procGetTickCount64 = modkernel32.NewProc("GetTickCount64") - procSetFileTime = modkernel32.NewProc("SetFileTime") - procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") - procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") - procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") - procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") - procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") - procLocalFree = modkernel32.NewProc("LocalFree") - procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") - procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") - procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") - procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") - procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") - procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") - procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") - procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") - procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") - procVirtualLock = modkernel32.NewProc("VirtualLock") - procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") - procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") - procVirtualFree = modkernel32.NewProc("VirtualFree") - procVirtualProtect = modkernel32.NewProc("VirtualProtect") - procTransmitFile = modmswsock.NewProc("TransmitFile") - procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") - procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") - procCertOpenStore = modcrypt32.NewProc("CertOpenStore") - procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") + procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") + procOpenServiceW = modadvapi32.NewProc("OpenServiceW") + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") + procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") + procQueryServiceLockStatusW = modadvapi32.NewProc("QueryServiceLockStatusW") + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx") + procRegCloseKey = modadvapi32.NewProc("RegCloseKey") + procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") + procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") + procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") + procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") + procReportEventW = modadvapi32.NewProc("ReportEventW") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") + procSetKernelObjectSecurity = modadvapi32.NewProc("SetKernelObjectSecurity") + procSetNamedSecurityInfoW = modadvapi32.NewProc("SetNamedSecurityInfoW") + procSetSecurityDescriptorControl = modadvapi32.NewProc("SetSecurityDescriptorControl") + procSetSecurityDescriptorDacl = modadvapi32.NewProc("SetSecurityDescriptorDacl") + procSetSecurityDescriptorGroup = modadvapi32.NewProc("SetSecurityDescriptorGroup") + procSetSecurityDescriptorOwner = modadvapi32.NewProc("SetSecurityDescriptorOwner") + procSetSecurityDescriptorRMControl = modadvapi32.NewProc("SetSecurityDescriptorRMControl") + procSetSecurityDescriptorSacl = modadvapi32.NewProc("SetSecurityDescriptorSacl") + procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") + procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") + procSetThreadToken = modadvapi32.NewProc("SetThreadToken") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") + procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") + procStartServiceW = modadvapi32.NewProc("StartServiceW") procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore") procCertCloseStore = modcrypt32.NewProc("CertCloseStore") - procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") - procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") + procCertDeleteCertificateFromStore = modcrypt32.NewProc("CertDeleteCertificateFromStore") + procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") + procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") + procCertOpenStore = modcrypt32.NewProc("CertOpenStore") + procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") - procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") - procRegCloseKey = modadvapi32.NewProc("RegCloseKey") - procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") - procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") - procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") - procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") - procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") - procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") - procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") - procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") - procReadConsoleW = modkernel32.NewProc("ReadConsoleW") - procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") - procProcess32FirstW = modkernel32.NewProc("Process32FirstW") - procProcess32NextW = modkernel32.NewProc("Process32NextW") - procThread32First = modkernel32.NewProc("Thread32First") - procThread32Next = modkernel32.NewProc("Thread32Next") - procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") - procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") - procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") - procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") - procCreateEventW = modkernel32.NewProc("CreateEventW") + procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") + procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") + procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") + procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") + procCancelIo = modkernel32.NewProc("CancelIo") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procCloseHandle = modkernel32.NewProc("CloseHandle") + procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") procCreateEventExW = modkernel32.NewProc("CreateEventExW") - procOpenEventW = modkernel32.NewProc("OpenEventW") - procSetEvent = modkernel32.NewProc("SetEvent") - procResetEvent = modkernel32.NewProc("ResetEvent") - procPulseEvent = modkernel32.NewProc("PulseEvent") - procCreateMutexW = modkernel32.NewProc("CreateMutexW") - procCreateMutexExW = modkernel32.NewProc("CreateMutexExW") - procOpenMutexW = modkernel32.NewProc("OpenMutexW") - procReleaseMutex = modkernel32.NewProc("ReleaseMutex") - procSleepEx = modkernel32.NewProc("SleepEx") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") + procCreateFileW = modkernel32.NewProc("CreateFileW") + procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") procCreateJobObjectW = modkernel32.NewProc("CreateJobObjectW") - procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") - procTerminateJobObject = modkernel32.NewProc("TerminateJobObject") - procSetErrorMode = modkernel32.NewProc("SetErrorMode") - procResumeThread = modkernel32.NewProc("ResumeThread") - procSetPriorityClass = modkernel32.NewProc("SetPriorityClass") - procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") - procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject") - procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") - procGetProcessId = modkernel32.NewProc("GetProcessId") - procOpenThread = modkernel32.NewProc("OpenThread") - procSetProcessPriorityBoost = modkernel32.NewProc("SetProcessPriorityBoost") + procCreateMutexExW = modkernel32.NewProc("CreateMutexExW") + procCreateMutexW = modkernel32.NewProc("CreateMutexW") + procCreatePipe = modkernel32.NewProc("CreatePipe") + procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") + procDeleteFileW = modkernel32.NewProc("DeleteFileW") procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") - procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") + procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") + procExitProcess = modkernel32.NewProc("ExitProcess") + procFindClose = modkernel32.NewProc("FindClose") + procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") - procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindNextFileW = modkernel32.NewProc("FindNextFileW") procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") + procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") + procFormatMessageW = modkernel32.NewProc("FormatMessageW") + procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") + procFreeLibrary = modkernel32.NewProc("FreeLibrary") + procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") + procGetACP = modkernel32.NewProc("GetACP") + procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") + procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") + procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") + procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") + procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") - procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") + procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") + procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") + procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") + procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") + procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") + procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = modkernel32.NewProc("GetFileType") + procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") + procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLastError = modkernel32.NewProc("GetLastError") procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") - procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") + procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") + procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") + procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") + procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") + procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") + procGetProcAddress = modkernel32.NewProc("GetProcAddress") + procGetProcessId = modkernel32.NewProc("GetProcessId") + procGetProcessPreferredUILanguages = modkernel32.NewProc("GetProcessPreferredUILanguages") + procGetProcessShutdownParameters = modkernel32.NewProc("GetProcessShutdownParameters") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") + procGetProcessWorkingSetSizeEx = modkernel32.NewProc("GetProcessWorkingSetSizeEx") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") + procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") + procGetStdHandle = modkernel32.NewProc("GetStdHandle") + procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW") + procGetSystemPreferredUILanguages = modkernel32.NewProc("GetSystemPreferredUILanguages") + procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") + procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") + procGetSystemWindowsDirectoryW = modkernel32.NewProc("GetSystemWindowsDirectoryW") + procGetTempPathW = modkernel32.NewProc("GetTempPathW") + procGetThreadPreferredUILanguages = modkernel32.NewProc("GetThreadPreferredUILanguages") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") + procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") + procGetUserPreferredUILanguages = modkernel32.NewProc("GetUserPreferredUILanguages") + procGetVersion = modkernel32.NewProc("GetVersion") procGetVolumeInformationByHandleW = modkernel32.NewProc("GetVolumeInformationByHandleW") + procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") procGetVolumeNameForVolumeMountPointW = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW") procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW") procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW") + procIsWow64Process = modkernel32.NewProc("IsWow64Process") + procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2") + procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") + procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") + procLocalFree = modkernel32.NewProc("LocalFree") + procLockFileEx = modkernel32.NewProc("LockFileEx") + procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") + procMoveFileExW = modkernel32.NewProc("MoveFileExW") + procMoveFileW = modkernel32.NewProc("MoveFileW") + procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") + procOpenEventW = modkernel32.NewProc("OpenEventW") + procOpenMutexW = modkernel32.NewProc("OpenMutexW") + procOpenProcess = modkernel32.NewProc("OpenProcess") + procOpenThread = modkernel32.NewProc("OpenThread") + procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId") + procPulseEvent = modkernel32.NewProc("PulseEvent") procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") + procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject") + procReadConsoleW = modkernel32.NewProc("ReadConsoleW") + procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") + procReadFile = modkernel32.NewProc("ReadFile") + procReleaseMutex = modkernel32.NewProc("ReleaseMutex") + procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") + procResetEvent = modkernel32.NewProc("ResetEvent") + procResumeThread = modkernel32.NewProc("ResumeThread") + procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") + procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") + procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") + procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") + procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") + procSetErrorMode = modkernel32.NewProc("SetErrorMode") + procSetEvent = modkernel32.NewProc("SetEvent") + procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") + procSetFilePointer = modkernel32.NewProc("SetFilePointer") + procSetFileTime = modkernel32.NewProc("SetFileTime") + procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") + procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject") + procSetPriorityClass = modkernel32.NewProc("SetPriorityClass") + procSetProcessPriorityBoost = modkernel32.NewProc("SetProcessPriorityBoost") + procSetProcessShutdownParameters = modkernel32.NewProc("SetProcessShutdownParameters") + procSetProcessWorkingSetSizeEx = modkernel32.NewProc("SetProcessWorkingSetSizeEx") + procSetStdHandle = modkernel32.NewProc("SetStdHandle") procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") - procMessageBoxW = moduser32.NewProc("MessageBoxW") - procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") - procInitiateSystemShutdownExW = modadvapi32.NewProc("InitiateSystemShutdownExW") - procSetProcessShutdownParameters = modkernel32.NewProc("SetProcessShutdownParameters") - procGetProcessShutdownParameters = modkernel32.NewProc("GetProcessShutdownParameters") + procSleepEx = modkernel32.NewProc("SleepEx") + procTerminateJobObject = modkernel32.NewProc("TerminateJobObject") + procTerminateProcess = modkernel32.NewProc("TerminateProcess") + procThread32First = modkernel32.NewProc("Thread32First") + procThread32Next = modkernel32.NewProc("Thread32Next") + procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") + procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") + procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") + procVirtualFree = modkernel32.NewProc("VirtualFree") + procVirtualLock = modkernel32.NewProc("VirtualLock") + procVirtualProtect = modkernel32.NewProc("VirtualProtect") + procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") + procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects") + procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") + procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") + procWriteFile = modkernel32.NewProc("WriteFile") + procAcceptEx = modmswsock.NewProc("AcceptEx") + procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") + procTransmitFile = modmswsock.NewProc("TransmitFile") + procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") + procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") + procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") + procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers") + procRtlGetVersion = modntdll.NewProc("RtlGetVersion") procCLSIDFromString = modole32.NewProc("CLSIDFromString") - procStringFromGUID2 = modole32.NewProc("StringFromGUID2") procCoCreateGuid = modole32.NewProc("CoCreateGuid") procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") - procRtlGetVersion = modntdll.NewProc("RtlGetVersion") - procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers") - procGetProcessPreferredUILanguages = modkernel32.NewProc("GetProcessPreferredUILanguages") - procGetThreadPreferredUILanguages = modkernel32.NewProc("GetThreadPreferredUILanguages") - procGetUserPreferredUILanguages = modkernel32.NewProc("GetUserPreferredUILanguages") - procGetSystemPreferredUILanguages = modkernel32.NewProc("GetSystemPreferredUILanguages") + procStringFromGUID2 = modole32.NewProc("StringFromGUID2") procEnumProcesses = modpsapi.NewProc("EnumProcesses") - procWSAStartup = modws2_32.NewProc("WSAStartup") + procSubscribeServiceChangeNotifications = modsechost.NewProc("SubscribeServiceChangeNotifications") + procUnsubscribeServiceChangeNotifications = modsechost.NewProc("UnsubscribeServiceChangeNotifications") + procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") + procTranslateNameW = modsecur32.NewProc("TranslateNameW") + procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") + procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") + procShellExecuteW = modshell32.NewProc("ShellExecuteW") + procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") + procMessageBoxW = moduser32.NewProc("MessageBoxW") + procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") + procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") + procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") + procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") + procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") procWSAIoctl = modws2_32.NewProc("WSAIoctl") - procsocket = modws2_32.NewProc("socket") - procsendto = modws2_32.NewProc("sendto") - procrecvfrom = modws2_32.NewProc("recvfrom") - procsetsockopt = modws2_32.NewProc("setsockopt") - procgetsockopt = modws2_32.NewProc("getsockopt") - procbind = modws2_32.NewProc("bind") - procconnect = modws2_32.NewProc("connect") - procgetsockname = modws2_32.NewProc("getsockname") - procgetpeername = modws2_32.NewProc("getpeername") - proclisten = modws2_32.NewProc("listen") - procshutdown = modws2_32.NewProc("shutdown") - procclosesocket = modws2_32.NewProc("closesocket") - procAcceptEx = modmswsock.NewProc("AcceptEx") - procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") procWSARecv = modws2_32.NewProc("WSARecv") - procWSASend = modws2_32.NewProc("WSASend") procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") + procWSASend = modws2_32.NewProc("WSASend") procWSASendTo = modws2_32.NewProc("WSASendTo") + procWSAStartup = modws2_32.NewProc("WSAStartup") + procbind = modws2_32.NewProc("bind") + procclosesocket = modws2_32.NewProc("closesocket") + procconnect = modws2_32.NewProc("connect") procgethostbyname = modws2_32.NewProc("gethostbyname") + procgetpeername = modws2_32.NewProc("getpeername") + procgetprotobyname = modws2_32.NewProc("getprotobyname") procgetservbyname = modws2_32.NewProc("getservbyname") + procgetsockname = modws2_32.NewProc("getsockname") + procgetsockopt = modws2_32.NewProc("getsockopt") + proclisten = modws2_32.NewProc("listen") procntohs = modws2_32.NewProc("ntohs") - procgetprotobyname = modws2_32.NewProc("getprotobyname") - procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") - procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") - procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") - procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") - procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") - procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") - procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") - procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") - procGetACP = modkernel32.NewProc("GetACP") - procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") - procTranslateNameW = modsecur32.NewProc("TranslateNameW") - procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") - procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") - procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") - procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") - procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") - procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") - procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") - procGetLengthSid = modadvapi32.NewProc("GetLengthSid") - procCopySid = modadvapi32.NewProc("CopySid") - procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") - procCreateWellKnownSid = modadvapi32.NewProc("CreateWellKnownSid") - procIsWellKnownSid = modadvapi32.NewProc("IsWellKnownSid") - procFreeSid = modadvapi32.NewProc("FreeSid") - procEqualSid = modadvapi32.NewProc("EqualSid") - procGetSidIdentifierAuthority = modadvapi32.NewProc("GetSidIdentifierAuthority") - procGetSidSubAuthorityCount = modadvapi32.NewProc("GetSidSubAuthorityCount") - procGetSidSubAuthority = modadvapi32.NewProc("GetSidSubAuthority") - procIsValidSid = modadvapi32.NewProc("IsValidSid") - procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") - procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procSetThreadToken = modadvapi32.NewProc("SetThreadToken") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procAdjustTokenGroups = modadvapi32.NewProc("AdjustTokenGroups") - procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") - procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") - procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") - procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") - procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW") - procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW") - procGetSystemWindowsDirectoryW = modkernel32.NewProc("GetSystemWindowsDirectoryW") - procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken") + procrecvfrom = modws2_32.NewProc("recvfrom") + procsendto = modws2_32.NewProc("sendto") + procsetsockopt = modws2_32.NewProc("setsockopt") + procshutdown = modws2_32.NewProc("shutdown") + procsocket = modws2_32.NewProc("socket") procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW") procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory") - procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo") - procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") - procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") - procSetNamedSecurityInfoW = modadvapi32.NewProc("SetNamedSecurityInfoW") - procBuildSecurityDescriptorW = modadvapi32.NewProc("BuildSecurityDescriptorW") - procInitializeSecurityDescriptor = modadvapi32.NewProc("InitializeSecurityDescriptor") - procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") - procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl") - procGetSecurityDescriptorSacl = modadvapi32.NewProc("GetSecurityDescriptorSacl") - procGetSecurityDescriptorOwner = modadvapi32.NewProc("GetSecurityDescriptorOwner") - procGetSecurityDescriptorGroup = modadvapi32.NewProc("GetSecurityDescriptorGroup") - procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") - procGetSecurityDescriptorRMControl = modadvapi32.NewProc("GetSecurityDescriptorRMControl") - procIsValidSecurityDescriptor = modadvapi32.NewProc("IsValidSecurityDescriptor") - procSetSecurityDescriptorControl = modadvapi32.NewProc("SetSecurityDescriptorControl") - procSetSecurityDescriptorDacl = modadvapi32.NewProc("SetSecurityDescriptorDacl") - procSetSecurityDescriptorSacl = modadvapi32.NewProc("SetSecurityDescriptorSacl") - procSetSecurityDescriptorOwner = modadvapi32.NewProc("SetSecurityDescriptorOwner") - procSetSecurityDescriptorGroup = modadvapi32.NewProc("SetSecurityDescriptorGroup") - procSetSecurityDescriptorRMControl = modadvapi32.NewProc("SetSecurityDescriptorRMControl") - procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") - procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") - procMakeAbsoluteSD = modadvapi32.NewProc("MakeAbsoluteSD") - procMakeSelfRelativeSD = modadvapi32.NewProc("MakeSelfRelativeSD") - procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") + procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken") ) -func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) { + var _p0 uint32 + if resetToDefault { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procAdjustTokenGroups.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + if r1 == 0 { + err = errnoErr(e1) } return } -func DeregisterEventSource(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) +func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) { + var _p0 uint32 + if disableAllPrivileges { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) +func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.Syscall9(procBuildSecurityDescriptorW.Addr(), 9, uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func CloseServiceHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) +func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { + r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + if r1 == 0 { + err = errnoErr(e1) } return } -func DeleteService(service Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) +func CloseServiceHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) +func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) +func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceLockStatusW.Addr(), 4, uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) +func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(str) + if err != nil { + return } - return + return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) } -func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) +func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) +func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) +func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) +func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCreateWellKnownSid.Addr(), 4, uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) +func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) +func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { + r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) +func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) { - r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) - if r0 != 0 { - ret = syscall.Errno(r0) +func DeleteService(service Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetLastError() (lasterr error) { - r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) - if r0 != 0 { - lasterr = syscall.Errno(r0) +func DeregisterEventSource(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func LoadLibrary(libname string) (handle Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(libname) - if err != nil { - return +func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) { + r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) + if r1 == 0 { + err = errnoErr(e1) } - return _LoadLibrary(_p0) + return } -func _LoadLibrary(libname *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(libname) - if err != nil { - return - } - return _LoadLibraryEx(_p0, zero, flags) +func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { + r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) + isEqual = r0 != 0 + return } -func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func FreeSid(sid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + if r1 != 0 { + err = errnoErr(e1) } return } -func FreeLibrary(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func GetLengthSid(sid *SID) (len uint32) { + r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + len = uint32(r0) return } -func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(procname) - if err != nil { +func getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + var _p0 *uint16 + _p0, ret = syscall.UTF16PtrFromString(objectName) + if ret != nil { return } - return _GetProcAddress(module, _p0) + return _getNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl, sd) } -func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) - proc = uintptr(r0) - if proc == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.Syscall9(procGetNamedSecurityInfoW.Addr(), 8, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) { - r1, _, e1 := syscall.Syscall(procGetModuleHandleExW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) +func getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) { + var _p0 uint32 + if *daclPresent { + _p0 = 1 + } + var _p1 uint32 + if *daclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + *daclPresent = _p0 != 0 + *daclDefaulted = _p1 != 0 if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetVersion() (ver uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) - ver = uint32(r0) - if ver == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) { + var _p0 uint32 + if *groupDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) + *groupDefaulted = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) } return } -func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { - var _p0 *uint16 - if len(buf) > 0 { - _p0 = &buf[0] +func getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) { + r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + len = uint32(r0) + return +} + +func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) { + var _p0 uint32 + if *ownerDefaulted { + _p0 = 1 } - r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) + *ownerDefaulted = _p0 != 0 + if r1 == 0 { + err = errnoErr(e1) } return } -func ExitProcess(exitcode uint32) { - syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) +func getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) { + r0, _, _ := syscall.Syscall(procGetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } return } -func IsWow64Process(handle Handle, isWow64 *bool) (err error) { +func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) { var _p0 uint32 - if *isWow64 { + if *saclPresent { _p0 = 1 - } else { - _p0 = 0 } - r1, _, e1 := syscall.Syscall(procIsWow64Process.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(&_p0)), 0) - *isWow64 = _p0 != 0 + var _p1 uint32 + if *saclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + *saclPresent = _p0 != 0 + *saclDefaulted = _p1 != 0 if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { + r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] - } - r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) +func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) { + r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0)) + return +} + +func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) { + r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(index), 0) + subAuthority = (*uint32)(unsafe.Pointer(r0)) + return +} + +func getSidSubAuthorityCount(sid *SID) (count *uint8) { + r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + count = (*uint8)(unsafe.Pointer(r0)) + return +} + +func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] +func ImpersonateSelf(impersonationlevel uint32) (err error) { + r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } - r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + return +} + +func initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) { + r1, _, e1 := syscall.Syscall(procInitializeSecurityDescriptor.Addr(), 2, uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { +func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) { var _p0 uint32 - if wait { + if forceAppsClosed { _p0 = 1 - } else { - _p0 = 0 } - r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0), 0, 0) + var _p1 uint32 + if rebootAfterShutdown { + _p1 = 1 + } + r1, _, e1 := syscall.Syscall6(procInitiateSystemShutdownExW.Addr(), 6, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { - r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) - newlowoffset = uint32(r0) - if newlowoffset == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func isTokenRestricted(tokenHandle Token) (ret bool, err error) { + r0, _, e1 := syscall.Syscall(procIsTokenRestricted.Addr(), 1, uintptr(tokenHandle), 0, 0) + ret = r0 != 0 + if !ret { + err = errnoErr(e1) } return } -func CloseHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) { + r0, _, _ := syscall.Syscall(procIsValidSecurityDescriptor.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + isValid = r0 != 0 return } -func GetStdHandle(stdhandle uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func isValidSid(sid *SID) (isValid bool) { + r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + isValid = r0 != 0 return } -func SetStdHandle(stdhandle uint32, handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) { + r0, _, _ := syscall.Syscall(procIsWellKnownSid.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(sidType), 0) + isWellKnown = r0 != 0 return } -func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func findNextFile1(handle Handle, data *win32finddata1) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) +func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func FindClose(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) +func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { + r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) +func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall12(procMakeAbsoluteSD.Addr(), 11, uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), 0, 0) +func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procMakeSelfRelativeSD.Addr(), 3, uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) { + r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func SetCurrentDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) +func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { + r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { - r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func RemoveDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func DeleteFile(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) +func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) { + var _p0 uint32 + if openAsSelf { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func MoveFile(from *uint16, to *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) +func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) +func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) +func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceLockStatusW.Addr(), 4, uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) +func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetComputerName(buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) +func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func RegCloseKey(key Handle) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) } return } -func SetEndOfFile(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) } return } -func GetSystemTimeAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) +func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } return } -func GetSystemTimePreciseAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) +func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } return } -func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) - rc = uint32(r0) - if rc == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + if r0 != 0 { + regerrno = syscall.Errno(r0) } return } -func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) +func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) handle = Handle(r0) if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) +func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) +func RevertToSelf() (err error) { + r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CancelIo(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) { + r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func CancelIoEx(s Handle, o *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) +func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { + r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { - var _p0 uint32 - if inheritHandles { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + var _p0 *uint16 + _p0, ret = syscall.UTF16PtrFromString(objectName) + if ret != nil { + return } - return + return _SetNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl) } -func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfoW.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { - r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) - if r1 <= 32 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) { + r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) + if r1 == 0 { + err = errnoErr(e1) } return } -func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) { - r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) { + var _p0 uint32 + if daclPresent { + _p0 = 1 } - return -} - -func TerminateProcess(handle Handle, exitcode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + var _p1 uint32 + if daclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) +func setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) { + var _p0 uint32 + if groupDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetStartupInfo(startupInfo *StartupInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) +func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) { + var _p0 uint32 + if ownerDefaulted { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) { + syscall.Syscall(procSetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) return } -func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { +func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) { var _p0 uint32 - if bInheritHandle { + if saclPresent { _p0 = 1 - } else { - _p0 = 0 } - r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + var _p1 uint32 + if saclDefaulted { + _p1 = 1 + } + r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { - r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) - event = uint32(r0) - if event == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { + r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { - var _p0 uint32 - if waitAll { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procWaitForMultipleObjects.Addr(), 4, uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds), 0, 0) - event = uint32(r0) - if event == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetThreadToken(thread *Handle, token Token) (err error) { + r1, _, e1 := syscall.Syscall(procSetThreadToken.Addr(), 2, uintptr(unsafe.Pointer(thread)), uintptr(token), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) +func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFileType(filehandle Handle) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) +func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) +func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { + r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { - r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) +func CertCloseStore(store Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetEnvironmentStrings() (envs *uint16, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) - envs = (*uint16)(unsafe.Pointer(r0)) - if envs == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + err = errnoErr(e1) } return } -func FreeEnvironmentStrings(envs *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) +func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { + r1, _, e1 := syscall.Syscall(procCertDeleteCertificateFromStore.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + err = errnoErr(e1) } return } -func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) +func CertFreeCertificateChain(ctx *CertChainContext) { + syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + return +} + +func CertFreeCertificateContext(ctx *CertContext) (err error) { + r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) { - var _p0 uint32 - if inheritExisting { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) +func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { + r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DestroyEnvironmentBlock(block *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func getTickCount64() (ms uint64) { - r0, _, _ := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) - ms = uint64(r0) +func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { + r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) + store = Handle(r0) + if store == 0 { + err = errnoErr(e1) + } return } -func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) +func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { + r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFileAttributes(name *uint16) (attrs uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - attrs = uint32(r0) - if attrs == INVALID_FILE_ATTRIBUTES { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { + r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) + same = r0 != 0 return } -func SetFileAttributes(name *uint16, attrs uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + var _p0 *uint16 + _p0, status = syscall.UTF16PtrFromString(name) + if status != nil { + return } - return + return _DnsQuery(_p0, qtype, options, extra, qrs, pr) } -func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + if r0 != 0 { + status = syscall.Errno(r0) } return } -func GetCommandLine() (cmd *uint16) { - r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) - cmd = (*uint16)(unsafe.Pointer(r0)) +func DnsRecordListFree(rl *DNSRecord, freetype uint32) { + syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) return } -func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { - r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) - argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) - if argv == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { + r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) } return } -func LocalFree(hmem Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) - handle = Handle(r0) - if handle != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { + r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) } return } -func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) +func GetIfEntry(pIfRow *MibIfRow) (errcode error) { + r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func AssignProcessToJobObject(job Handle, process Handle) (err error) { + r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func FlushFileBuffers(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) +func CancelIo(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CancelIoEx(s Handle, o *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CloseHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { + r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) +func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) handle = Handle(r0) if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) - addr = uintptr(r0) - if addr == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func UnmapViewOfFile(addr uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func FlushViewOfFile(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) } return } -func VirtualLock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + if r1&0xff == 0 { + err = errnoErr(e1) } return } -func VirtualUnlock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) - value = uintptr(r0) - if value == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateJobObjectW.Addr(), 2, uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name)), 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateMutexExW.Addr(), 4, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if initialOwner { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procCreateMutexW.Addr(), 3, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) +func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { +func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { var _p0 uint32 - if watchSubTree { + if inheritHandles { _p0 = 1 - } else { - _p0 = 0 } - r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) - store = Handle(r0) - if store == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + if r1&0xff == 0 { + err = errnoErr(e1) } return } -func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) +func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) handle = Handle(r0) if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) - context = (*CertContext)(unsafe.Pointer(r0)) - if context == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + if r1 == 0 { + err = errnoErr(e1) } return } -func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { - r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) +func DeleteFile(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertCloseStore(store Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) +func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { - r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) +func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertFreeCertificateChain(ctx *CertChainContext) { - syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) +func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { + var _p0 uint32 + if bInheritHandle { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) - context = (*CertContext)(unsafe.Pointer(r0)) - if context == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func ExitProcess(exitcode uint32) { + syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) return } -func CertFreeCertificateContext(ctx *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) +func FindClose(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { - r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) } return } -func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) +func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) } return } -func RegCloseKey(key Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) +func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) } return } -func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) - if r0 != 0 { - regerrno = syscall.Errno(r0) +func findNextFile1(handle Handle, data *win32finddata1) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) +func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + if r1 == 0 { + err = errnoErr(e1) } return } -func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) - if r0 != 0 { - regerrno = syscall.Errno(r0) +func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetCurrentProcessId() (pid uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) - pid = uint32(r0) +func FindVolumeClose(findVolume Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func GetConsoleMode(console Handle, mode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) +func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func SetConsoleMode(console Handle, mode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) +func FlushFileBuffers(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) +func FlushViewOfFile(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { + var _p0 *uint16 + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) +func FreeEnvironmentStrings(envs *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func FreeLibrary(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) +func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGenerateConsoleCtrlEvent.Addr(), 2, uintptr(ctrlEvent), uintptr(processGroupID), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) +func GetACP() (acp uint32) { + r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + acp = uint32(r0) + return +} + +func GetCommandLine() (cmd *uint16) { + r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) + cmd = (*uint16)(unsafe.Pointer(r0)) + return +} + +func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32First.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) +func GetComputerName(buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32Next.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) +func GetConsoleMode(console Handle, mode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) +func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func GetCurrentProcessId() (pid uint32) { + r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + pid = uint32(r0) return } @@ -2102,226 +1674,166 @@ func GetCurrentThreadId() (id uint32) { return } -func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { + r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func GetDriveType(rootPathName *uint16) (driveType uint32) { + r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + driveType = uint32(r0) return } -func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetEnvironmentStrings() (envs *uint16, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) + envs = (*uint16)(unsafe.Pointer(r0)) + if envs == nil { + err = errnoErr(e1) } return } -func SetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func ResetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) +func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func PulseEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) +func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) { - var _p0 uint32 - if initialOwner { - _p0 = 1 - } else { - _p0 = 0 +func GetFileAttributes(name *uint16) (attrs uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + attrs = uint32(r0) + if attrs == INVALID_FILE_ATTRIBUTES { + err = errnoErr(e1) } - r0, _, e1 := syscall.Syscall(procCreateMutexW.Addr(), 3, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + return +} + +func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateMutexExW.Addr(), 4, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 +func GetFileType(filehandle Handle) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } - r0, _, e1 := syscall.Syscall(procOpenMutexW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + return +} + +func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func ReleaseMutex(mutex Handle) (err error) { - r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func SleepEx(milliseconds uint32, alertable bool) (ret uint32) { - var _p0 uint32 - if alertable { - _p0 = 1 - } else { - _p0 = 0 +func GetLastError() (lasterr error) { + r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) + if r0 != 0 { + lasterr = syscall.Errno(r0) } - r0, _, _ := syscall.Syscall(procSleepEx.Addr(), 2, uintptr(milliseconds), uintptr(_p0), 0) - ret = uint32(r0) return } -func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateJobObjectW.Addr(), 2, uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name)), 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func AssignProcessToJobObject(job Handle, process Handle) (err error) { - r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetLogicalDrives() (drivesBitMask uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) + drivesBitMask = uint32(r0) + if drivesBitMask == 0 { + err = errnoErr(e1) } return } -func TerminateJobObject(job Handle, exitCode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateJobObject.Addr(), 2, uintptr(job), uintptr(exitCode), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func SetErrorMode(mode uint32) (ret uint32) { - r0, _, _ := syscall.Syscall(procSetErrorMode.Addr(), 1, uintptr(mode), 0, 0) - ret = uint32(r0) +func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) + } return } -func ResumeThread(thread Handle) (ret uint32, err error) { - r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0) - ret = uint32(r0) - if ret == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) { + r1, _, e1 := syscall.Syscall(procGetModuleHandleExW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) + if r1 == 0 { + err = errnoErr(e1) } return } -func SetPriorityClass(process Handle, priorityClass uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetPriorityClass.Addr(), 2, uintptr(process), uintptr(priorityClass), 0) +func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -2330,36 +1842,25 @@ func GetPriorityClass(process Handle) (ret uint32, err error) { r0, _, e1 := syscall.Syscall(procGetPriorityClass.Addr(), 1, uintptr(process), 0, 0) ret = uint32(r0) if ret == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { - r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0) - ret = int(r0) - if ret == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(procname) + if err != nil { + return } - return + return _GetProcAddress(module, _p0) } -func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGenerateConsoleCtrlEvent.Addr(), 2, uintptr(ctrlEvent), uintptr(processGroupID), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) + proc = uintptr(r0) + if proc == 0 { + err = errnoErr(e1) } return } @@ -2368,202 +1869,155 @@ func GetProcessId(process Handle) (id uint32, err error) { r0, _, e1 := syscall.Syscall(procGetProcessId.Addr(), 1, uintptr(process), 0, 0) id = uint32(r0) if id == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall(procOpenThread.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetProcessPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func SetProcessPriorityBoost(process Handle, disable bool) (err error) { - var _p0 uint32 - if disable { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall(procSetProcessPriorityBoost.Addr(), 2, uintptr(process), uintptr(_p0), 0) +func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessShutdownParameters.Addr(), 2, uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) +func GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) { + syscall.Syscall6(procGetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags)), 0, 0) + return +} + +func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) +func GetStartupInfo(startupInfo *StartupInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetStdHandle(stdhandle uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) handle = Handle(r0) if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) } return } -func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) +func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetSystemPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func FindVolumeClose(findVolume Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetSystemTimeAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func GetSystemTimePreciseAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetSystemWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) } return } -func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { - r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) +func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetThreadPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetDriveType(rootPathName *uint16) (driveType uint32) { - r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) - driveType = uint32(r0) +func getTickCount64() (ms uint64) { + r0, _, _ := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + ms = uint64(r0) return } -func GetLogicalDrives() (drivesBitMask uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) - drivesBitMask = uint32(r0) - if drivesBitMask == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) + rc = uint32(r0) + if rc == 0xffffffff { + err = errnoErr(e1) } return } -func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetUserPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetVersion() (ver uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) + ver = uint32(r0) + if ver == 0 { + err = errnoErr(e1) } return } @@ -2571,11 +2025,15 @@ func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volume func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + if r1 == 0 { + err = errnoErr(e1) } return } @@ -2583,11 +2041,7 @@ func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeN func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -2595,11 +2049,7 @@ func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -2607,1010 +2057,836 @@ func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength ui func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + len = uint32(r0) + if len == 0 { + err = errnoErr(e1) } return } -func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) +func IsWow64Process(handle Handle, isWow64 *bool) (err error) { + var _p0 uint32 + if *isWow64 { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procIsWow64Process.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(&_p0)), 0) + *isWow64 = _p0 != 0 if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) +func IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) { + err = procIsWow64Process2.Find() + if err != nil { + return + } + r1, _, e1 := syscall.Syscall(procIsWow64Process2.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { - r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) - ret = int32(r0) - if ret == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return } - return + return _LoadLibraryEx(_p0, zero, flags) } -func ExitWindowsEx(flags uint32, reason uint32) (err error) { - r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) { - var _p0 uint32 - if forceAppsClosed { - _p0 = 1 - } else { - _p0 = 0 +func LoadLibrary(libname string) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return } - var _p1 uint32 - if rebootAfterShutdown { - _p1 = 1 - } else { - _p1 = 0 + return _LoadLibrary(_p0) +} + +func _LoadLibrary(libname *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } - r1, _, e1 := syscall.Syscall6(procInitiateSystemShutdownExW.Addr(), 6, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + return +} + +func LocalFree(hmem Handle) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) + handle = Handle(r0) + if handle != 0 { + err = errnoErr(e1) } return } -func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetProcessShutdownParameters.Addr(), 2, uintptr(level), uintptr(flags), 0) +func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessShutdownParameters.Addr(), 2, uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) + addr = uintptr(r0) + if addr == 0 { + err = errnoErr(e1) } return } -func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) } return } -func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) { - r0, _, _ := syscall.Syscall(procStringFromGUID2.Addr(), 3, uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) - chars = int32(r0) +func MoveFile(from *uint16, to *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func coCreateGuid(pguid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCoCreateGuid.Addr(), 1, uintptr(unsafe.Pointer(pguid)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { + r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + nwrite = int32(r0) + if nwrite == 0 { + err = errnoErr(e1) } return } -func CoTaskMemFree(address unsafe.Pointer) { - syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(address), 0, 0) +func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } return } -func rtlGetVersion(info *OsVersionInfoEx) (ret error) { - r0, _, _ := syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procOpenMutexW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { - syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) +func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } return } -func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procOpenThread.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetThreadPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) +func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetUserPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) +func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetSystemPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) +func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) { - var _p0 *uint32 - if len(processIds) > 0 { - _p0 = &processIds[0] - } - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(processIds)), uintptr(unsafe.Pointer(bytesReturned))) +func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procProcessIdToSessionId.Addr(), 2, uintptr(pid), uintptr(unsafe.Pointer(sessionid)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { - r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) - if r0 != 0 { - sockerr = syscall.Errno(r0) +func PulseEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func WSACleanup() (err error) { - r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] +func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + var _p0 uint32 + if watchSubTree { + _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) { +func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { var _p0 *byte if len(buf) > 0 { _p0 = &buf[0] } - r0, _, e1 := syscall.Syscall6(procrecvfrom.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) - n = int32(r0) - if n == -1 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { - r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ReleaseMutex(mutex Handle) (err error) { + r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { - r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func RemoveDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ResetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ResumeThread(thread Handle) (ret uint32, err error) { + r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0) + ret = uint32(r0) + if ret == 0xffffffff { + err = errnoErr(e1) } return } -func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func setConsoleCursorPosition(console Handle, position uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetConsoleMode(console Handle, mode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func listen(s Handle, backlog int32) (err error) { - r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetCurrentDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func shutdown(s Handle, how int32) (err error) { - r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetDefaultDllDirectories(directoryFlags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetDefaultDllDirectories.Addr(), 1, uintptr(directoryFlags), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func Closesocket(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetDllDirectory(path string) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(path) + if err != nil { + return } - return + return _SetDllDirectory(_p0) } -func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) +func _SetDllDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetDllDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { - syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) +func SetEndOfFile(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func SetErrorMode(mode uint32) (ret uint32) { + r0, _, _ := syscall.Syscall(procSetErrorMode.Addr(), 1, uintptr(mode), 0, 0) + ret = uint32(r0) return } -func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetFileAttributes(name *uint16, attrs uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetHostByName(name string) (h *Hostent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return +func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) + if r1 == 0 { + err = errnoErr(e1) } - return _GetHostByName(_p0) + return } -func _GetHostByName(name *byte) (h *Hostent, err error) { - r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - h = (*Hostent)(unsafe.Pointer(r0)) - if h == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetServByName(name string, proto string) (s *Servent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return +func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { + r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) + newlowoffset = uint32(r0) + if newlowoffset == 0xffffffff { + err = errnoErr(e1) } - var _p1 *byte - _p1, err = syscall.BytePtrFromString(proto) - if err != nil { - return + return +} + +func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } - return _GetServByName(_p0, _p1) + return } -func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { - r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) - s = (*Servent)(unsafe.Pointer(r0)) - if s == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) } return } -func Ntohs(netshort uint16) (u uint16) { - r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) - u = uint16(r0) +func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { + r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0) + ret = int(r0) + if ret == 0 { + err = errnoErr(e1) + } return } -func GetProtoByName(name string) (p *Protoent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return +func SetPriorityClass(process Handle, priorityClass uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetPriorityClass.Addr(), 2, uintptr(process), uintptr(priorityClass), 0) + if r1 == 0 { + err = errnoErr(e1) } - return _GetProtoByName(_p0) + return } -func _GetProtoByName(name *byte) (p *Protoent, err error) { - r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - p = (*Protoent)(unsafe.Pointer(r0)) - if p == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SetProcessPriorityBoost(process Handle, disable bool) (err error) { + var _p0 uint32 + if disable { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procSetProcessPriorityBoost.Addr(), 2, uintptr(process), uintptr(_p0), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - var _p0 *uint16 - _p0, status = syscall.UTF16PtrFromString(name) - if status != nil { - return +func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetProcessShutdownParameters.Addr(), 2, uintptr(level), uintptr(flags), 0) + if r1 == 0 { + err = errnoErr(e1) } - return _DnsQuery(_p0, qtype, options, extra, qrs, pr) + return } -func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) - if r0 != 0 { - status = syscall.Errno(r0) +func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func DnsRecordListFree(rl *DNSRecord, freetype uint32) { - syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) +func SetStdHandle(stdhandle uint32, handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { - r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) - same = r0 != 0 +func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { - r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) - if r0 != 0 { - sockerr = syscall.Errno(r0) +func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func FreeAddrInfoW(addrinfo *AddrinfoW) { - syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) +func SleepEx(milliseconds uint32, alertable bool) (ret uint32) { + var _p0 uint32 + if alertable { + _p0 = 1 + } + r0, _, _ := syscall.Syscall(procSleepEx.Addr(), 2, uintptr(milliseconds), uintptr(_p0), 0) + ret = uint32(r0) return } -func GetIfEntry(pIfRow *MibIfRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) - if r0 != 0 { - errcode = syscall.Errno(r0) +func TerminateJobObject(job Handle, exitCode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procTerminateJobObject.Addr(), 2, uintptr(job), uintptr(exitCode), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) - if r0 != 0 { - errcode = syscall.Errno(r0) +func TerminateProcess(handle Handle, exitcode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) +func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procThread32First.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { - r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) - n = int32(r0) - if n == -1 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procThread32Next.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { - r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) - if r0 != 0 { - errcode = syscall.Errno(r0) +func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetACP() (acp uint32) { - r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) - acp = uint32(r0) +func UnmapViewOfFile(addr uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } return } -func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { - r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) - nwrite = int32(r0) - if nwrite == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) + value = uintptr(r0) + if value == 0 { + err = errnoErr(e1) } return } -func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func VirtualLock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { - r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) - if r0 != 0 { - neterr = syscall.Errno(r0) +func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { - r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) - if r0 != 0 { - neterr = syscall.Errno(r0) +func VirtualUnlock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func NetApiBufferFree(buf *byte) (neterr error) { - r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) - if r0 != 0 { - neterr = syscall.Errno(r0) +func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { + var _p0 uint32 + if waitAll { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall6(procWaitForMultipleObjects.Addr(), 4, uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds), 0, 0) + event = uint32(r0) + if event == 0xffffffff { + err = errnoErr(e1) } return } -func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { + r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) + event = uint32(r0) + if event == 0xffffffff { + err = errnoErr(e1) } return } -func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) +func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) +func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) +func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetLengthSid(sid *SID) (len uint32) { - r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - len = uint32(r0) +func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { + syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) return } -func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) +func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NetApiBufferFree(buf *byte) (neterr error) { + r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) } return } -func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreateWellKnownSid.Addr(), 4, uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { + r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + if r0 != 0 { + neterr = syscall.Errno(r0) } return } -func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) { - r0, _, _ := syscall.Syscall(procIsWellKnownSid.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(sidType), 0) - isWellKnown = r0 != 0 +func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { + r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } return } -func FreeSid(sid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { + syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) return } -func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { - r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) - isEqual = r0 != 0 +func rtlGetVersion(info *OsVersionInfoEx) (ret error) { + r0, _, _ := syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } return } -func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) { - r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0)) +func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { + r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } return } -func getSidSubAuthorityCount(sid *SID) (count *uint8) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - count = (*uint8)(unsafe.Pointer(r0)) +func coCreateGuid(pguid *GUID) (ret error) { + r0, _, _ := syscall.Syscall(procCoCreateGuid.Addr(), 1, uintptr(unsafe.Pointer(pguid)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) + } return } -func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(index), 0) - subAuthority = (*uint32)(unsafe.Pointer(r0)) +func CoTaskMemFree(address unsafe.Pointer) { + syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(address), 0, 0) return } -func isValidSid(sid *SID) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - isValid = r0 != 0 +func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) { + r0, _, _ := syscall.Syscall(procStringFromGUID2.Addr(), 3, uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) + chars = int32(r0) return } -func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { - r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) +func EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) { + var _p0 *uint32 + if len(processIds) > 0 { + _p0 = &processIds[0] + } + r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(processIds)), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) { + ret = procSubscribeServiceChangeNotifications.Find() + if ret != nil { + return + } + r0, _, _ := syscall.Syscall6(procSubscribeServiceChangeNotifications.Addr(), 5, uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription)), 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) { - var _p0 uint32 - if openAsSelf { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func UnsubscribeServiceChangeNotifications(subscription uintptr) (err error) { + err = procUnsubscribeServiceChangeNotifications.Find() + if err != nil { + return } + syscall.Syscall(procUnsubscribeServiceChangeNotifications.Addr(), 1, uintptr(subscription), 0, 0) return } -func ImpersonateSelf(impersonationlevel uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + if r1&0xff == 0 { + err = errnoErr(e1) } return } -func RevertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) + if r1&0xff == 0 { + err = errnoErr(e1) } return } -func SetThreadToken(thread *Handle, token Token) (err error) { - r1, _, e1 := syscall.Syscall(procSetThreadToken.Addr(), 2, uintptr(unsafe.Pointer(thread)), uintptr(token), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { + r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) + argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) + if argv == nil { + err = errnoErr(e1) } return } -func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) { + r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path)), 0, 0) + if r0 != 0 { + ret = syscall.Errno(r0) } return } -func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) { - var _p0 uint32 - if disableAllPrivileges { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { + r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) + if r1 <= 32 { + err = errnoErr(e1) } return } -func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) { - var _p0 uint32 - if resetToDefault { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall6(procAdjustTokenGroups.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) +func ExitWindowsEx(flags uint32, reason uint32) (err error) { + r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func MessageBox(hwnd Handle, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { + r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) + ret = int32(r0) + if ret == 0 { + err = errnoErr(e1) } return } -func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), 0, 0) +func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) { + var _p0 uint32 + if inheritExisting { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) { - r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) +func DestroyEnvironmentBlock(block *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -3618,434 +2894,277 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) - len = uint32(r0) - if len == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func FreeAddrInfoW(addrinfo *AddrinfoW) { + syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) return } -func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) - len = uint32(r0) - if len == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { + r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) + if r0 != 0 { + sockerr = syscall.Errno(r0) } return } -func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) - len = uint32(r0) - if len == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func WSACleanup() (err error) { + r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) + if r1 == socket_error { + err = errnoErr(e1) } return } -func WTSQueryUserToken(session uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procWTSQueryUserToken.Addr(), 2, uintptr(session), uintptr(unsafe.Pointer(token)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { + r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + n = int32(r0) + if n == -1 { + err = errnoErr(e1) } return } -func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procWTSEnumerateSessionsW.Addr(), 5, uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + if r1 == socket_error { + err = errnoErr(e1) } return } -func WTSFreeMemory(ptr uintptr) { - syscall.Syscall(procWTSFreeMemory.Addr(), 1, uintptr(ptr), 0, 0) +func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + err = errnoErr(e1) + } return } -func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) } return } -func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) { - syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) +func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + err = errnoErr(e1) + } return } -func getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - var _p0 *uint16 - _p0, ret = syscall.UTF16PtrFromString(objectName) - if ret != nil { - return +func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + err = errnoErr(e1) } - return _getNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl, sd) + return } -func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetNamedSecurityInfoW.Addr(), 8, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) +func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { + r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) if r0 != 0 { - ret = syscall.Errno(r0) + sockerr = syscall.Errno(r0) } return } -func SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - var _p0 *uint16 - _p0, ret = syscall.UTF16PtrFromString(objectName) - if ret != nil { - return +func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + err = errnoErr(e1) } - return _SetNamedSecurityInfo(_p0, objectType, securityInformation, owner, group, dacl, sacl) + return } -func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfoW.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func Closesocket(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) + if r1 == socket_error { + err = errnoErr(e1) } return } -func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procBuildSecurityDescriptorW.Addr(), 9, uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) - if r0 != 0 { - ret = syscall.Errno(r0) +func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + err = errnoErr(e1) } return } -func initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) { - r1, _, e1 := syscall.Syscall(procInitializeSecurityDescriptor.Addr(), 2, uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetHostByName(name string) (h *Hostent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return } - return + return _GetHostByName(_p0) } -func getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetHostByName(name *byte) (h *Hostent, err error) { + r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + h = (*Hostent)(unsafe.Pointer(r0)) + if h == nil { + err = errnoErr(e1) } return } -func getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) { - var _p0 uint32 - if *daclPresent { - _p0 = 1 - } else { - _p0 = 0 - } - var _p1 uint32 - if *daclDefaulted { - _p1 = 1 - } else { - _p1 = 0 - } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) - *daclPresent = _p0 != 0 - *daclDefaulted = _p1 != 0 - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + err = errnoErr(e1) } return } -func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) { - var _p0 uint32 - if *saclPresent { - _p0 = 1 - } else { - _p0 = 0 - } - var _p1 uint32 - if *saclDefaulted { - _p1 = 1 - } else { - _p1 = 0 - } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) - *saclPresent = _p0 != 0 - *saclDefaulted = _p1 != 0 - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetProtoByName(name string) (p *Protoent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return } - return + return _GetProtoByName(_p0) } -func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) { - var _p0 uint32 - if *ownerDefaulted { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) - *ownerDefaulted = _p0 != 0 - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetProtoByName(name *byte) (p *Protoent, err error) { + r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + p = (*Protoent)(unsafe.Pointer(r0)) + if p == nil { + err = errnoErr(e1) } return } -func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) { - var _p0 uint32 - if *groupDefaulted { - _p0 = 1 - } else { - _p0 = 0 +func GetServByName(name string, proto string) (s *Servent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) - *groupDefaulted = _p0 != 0 - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(proto) + if err != nil { + return } - return -} - -func getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) - len = uint32(r0) - return + return _GetServByName(_p0, _p1) } -func getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { + r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) + s = (*Servent)(unsafe.Pointer(r0)) + if s == nil { + err = errnoErr(e1) } return } -func isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSecurityDescriptor.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) - isValid = r0 != 0 +func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + err = errnoErr(e1) + } return } -func setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) { - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + if r1 == socket_error { + err = errnoErr(e1) } return } -func setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) { - var _p0 uint32 - if daclPresent { - _p0 = 1 - } else { - _p0 = 0 - } - var _p1 uint32 - if daclDefaulted { - _p1 = 1 - } else { - _p1 = 0 - } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func listen(s Handle, backlog int32) (err error) { + r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) + if r1 == socket_error { + err = errnoErr(e1) } return } -func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) { - var _p0 uint32 - if saclPresent { - _p0 = 1 - } else { - _p0 = 0 - } - var _p1 uint32 - if saclDefaulted { - _p1 = 1 - } else { - _p1 = 0 - } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func Ntohs(netshort uint16) (u uint16) { + r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) + u = uint16(r0) return } -func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) { - var _p0 uint32 - if ownerDefaulted { - _p0 = 1 - } else { - _p0 = 0 +func recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + r0, _, e1 := syscall.Syscall6(procrecvfrom.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int32(r0) + if n == -1 { + err = errnoErr(e1) } return } -func setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) { - var _p0 uint32 - if groupDefaulted { - _p0 = 1 - } else { - _p0 = 0 +func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + r1, _, e1 := syscall.Syscall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) + if r1 == socket_error { + err = errnoErr(e1) } return } -func setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) { - syscall.Syscall(procSetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) - return -} - -func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(str) - if err != nil { - return +func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { + r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) + if r1 == socket_error { + err = errnoErr(e1) } - return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) + return } -func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func shutdown(s Handle, how int32) (err error) { + r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) + if r1 == socket_error { + err = errnoErr(e1) } return } -func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) + handle = Handle(r0) + if handle == InvalidHandle { + err = errnoErr(e1) } return } -func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall12(procMakeAbsoluteSD.Addr(), 11, uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize)), 0) +func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procWTSEnumerateSessionsW.Addr(), 5, uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMakeSelfRelativeSD.Addr(), 3, uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func WTSFreeMemory(ptr uintptr) { + syscall.Syscall(procWTSFreeMemory.Addr(), 1, uintptr(ptr), 0, 0) return } -func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) { - r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) +func WTSQueryUserToken(session uint32, token *Token) (err error) { + r1, _, e1 := syscall.Syscall(procWTSQueryUserToken.Addr(), 2, uintptr(session), uintptr(unsafe.Pointer(token)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go index 8c9977355c..8c3c2e7ab9 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go @@ -95,12 +95,13 @@ type Pass struct { Analyzer *Analyzer // the identity of the current analyzer // syntax and type information - Fset *token.FileSet // file position information - Files []*ast.File // the abstract syntax tree of each file - OtherFiles []string // names of non-Go files of this package - Pkg *types.Package // type information about the package - TypesInfo *types.Info // type information about the syntax trees - TypesSizes types.Sizes // function for computing sizes of types + Fset *token.FileSet // file position information + Files []*ast.File // the abstract syntax tree of each file + OtherFiles []string // names of non-Go files of this package + IgnoredFiles []string // names of ignored source files in this package + Pkg *types.Package // type information about the package + TypesInfo *types.Info // type information about the syntax trees + TypesSizes types.Sizes // function for computing sizes of types // Report reports a Diagnostic, a finding about a specific location // in the analyzed source code such as a potential mistake. diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go index fb17a0e415..9fa3302dfb 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go @@ -121,13 +121,14 @@ package being analyzed, and provides operations to the Run function for reporting diagnostics and other information back to the driver. type Pass struct { - Fset *token.FileSet - Files []*ast.File - OtherFiles []string - Pkg *types.Package - TypesInfo *types.Info - ResultOf map[*Analyzer]interface{} - Report func(Diagnostic) + Fset *token.FileSet + Files []*ast.File + OtherFiles []string + IgnoredFiles []string + Pkg *types.Package + TypesInfo *types.Info + ResultOf map[*Analyzer]interface{} + Report func(Diagnostic) ... } @@ -139,6 +140,12 @@ files such as assembly that are part of this package. See the "asmdecl" or "buildtags" analyzers for examples of loading non-Go files and reporting diagnostics against them. +The IgnoredFiles field provides the names, but not the contents, +of ignored Go and non-Go source files that are not part of this package +with the current build configuration but may be part of other build +configurations. See the "buildtags" analyzer for an example of loading +and checking IgnoredFiles. + The ResultOf field provides the results computed by the analyzers required by this one, as expressed in its Analyzer.Requires field. The driver runs the required analyzers first and makes their results diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go index e6bfe71539..eb0016b18f 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go @@ -137,6 +137,7 @@ var ( asmSP = re(`[^+\-0-9](([0-9]+)\(([A-Z0-9]+)\))`) asmOpcode = re(`^\s*(?:[A-Z0-9a-z_]+:)?\s*([A-Z]+)\s*([^,]*)(?:,\s*(.*))?`) ppc64Suff = re(`([BHWD])(ZU|Z|U|BR)?$`) + abiSuff = re(`^(.+)<ABI.+>$`) ) func run(pass *analysis.Pass) (interface{}, error) { @@ -200,6 +201,13 @@ Files: } retLine = nil } + trimABI := func(fnName string) string { + m := abiSuff.FindStringSubmatch(fnName) + if m != nil { + return m[1] + } + return fnName + } for lineno, line := range lines { lineno++ @@ -268,6 +276,8 @@ Files: continue } } + // Trim off optional ABI selector. + fnName := trimABI(fnName) flag := m[3] fn = knownFunc[fnName][arch] if fn != nil { @@ -298,7 +308,8 @@ Files: continue } - if strings.Contains(line, "RET") { + if strings.Contains(line, "RET") && !strings.Contains(line, "(SB)") { + // RET f(SB) is a tail call. It is okay to not write the results. retLine = append(retLine, lineno) } diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go index 78176f1011..841b928578 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go @@ -9,6 +9,7 @@ import ( "bytes" "fmt" "go/ast" + "go/parser" "strings" "unicode" @@ -33,6 +34,20 @@ func runBuildTag(pass *analysis.Pass) (interface{}, error) { return nil, err } } + for _, name := range pass.IgnoredFiles { + if strings.HasSuffix(name, ".go") { + f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments) + if err != nil { + // Not valid Go source code - not our job to diagnose, so ignore. + return nil, nil + } + checkGoFile(pass, f) + } else { + if err := checkOtherFile(pass, name); err != nil { + return nil, err + } + } + } return nil, nil } @@ -132,13 +147,6 @@ func checkLine(line string, pastCutoff bool) error { } func checkArguments(fields []string) error { - // The original version of this checker in vet could examine - // files with malformed build tags that would cause the file to - // be always ignored by "go build". However, drivers for the new - // analysis API will analyze only the files selected to form a - // package, so these checks will never fire. - // TODO(adonovan): rethink this. - for _, arg := range fields[1:] { for _, elem := range strings.Split(arg, ",") { if strings.HasPrefix(elem, "!!") { diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go new file mode 100644 index 0000000000..741492e477 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go @@ -0,0 +1,91 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package framepointer defines an Analyzer that reports assembly code +// that clobbers the frame pointer before saving it. +package framepointer + +import ( + "go/build" + "regexp" + "strings" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" +) + +const Doc = "report assembly that clobbers the frame pointer before saving it" + +var Analyzer = &analysis.Analyzer{ + Name: "framepointer", + Doc: Doc, + Run: run, +} + +var ( + re = regexp.MustCompile + asmWriteBP = re(`,\s*BP$`) // TODO: can have false positive, e.g. for TESTQ BP,BP. Seems unlikely. + asmMentionBP = re(`\bBP\b`) + asmControlFlow = re(`^(J|RET)`) +) + +func run(pass *analysis.Pass) (interface{}, error) { + if build.Default.GOARCH != "amd64" { // TODO: arm64 also? + return nil, nil + } + if build.Default.GOOS != "linux" && build.Default.GOOS != "darwin" { + return nil, nil + } + + // Find assembly files to work on. + var sfiles []string + for _, fname := range pass.OtherFiles { + if strings.HasSuffix(fname, ".s") && pass.Pkg.Path() != "runtime" { + sfiles = append(sfiles, fname) + } + } + + for _, fname := range sfiles { + content, tf, err := analysisutil.ReadFile(pass.Fset, fname) + if err != nil { + return nil, err + } + + lines := strings.SplitAfter(string(content), "\n") + active := false + for lineno, line := range lines { + lineno++ + + // Ignore comments and commented-out code. + if i := strings.Index(line, "//"); i >= 0 { + line = line[:i] + } + line = strings.TrimSpace(line) + + // We start checking code at a TEXT line for a frameless function. + if strings.HasPrefix(line, "TEXT") && strings.Contains(line, "(SB)") && strings.Contains(line, "$0") { + active = true + continue + } + if !active { + continue + } + + if asmWriteBP.MatchString(line) { // clobber of BP, function is not OK + pass.Reportf(analysisutil.LineStart(tf, lineno), "frame pointer is clobbered before saving") + active = false + continue + } + if asmMentionBP.MatchString(line) { // any other use of BP might be a read, so function is OK + active = false + continue + } + if asmControlFlow.MatchString(line) { // give up after any branch instruction + active = false + continue + } + } + } + return nil, nil +} diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go index c5a71a7c57..fd2285332c 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go @@ -41,6 +41,10 @@ var Analyzer = &analysis.Analyzer{ // assertableTo checks whether interface v can be asserted into t. It returns // nil on success, or the first conflicting method on failure. func assertableTo(v, t types.Type) *types.Func { + if t == nil || v == nil { + // not assertable to, but there is no missing method + return nil + } // ensure that v and t are interfaces V, _ := v.Underlying().(*types.Interface) T, _ := t.Underlying().(*types.Interface) diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go index e09160379f..02555648a0 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go @@ -116,7 +116,11 @@ func checkCanonicalFieldTag(pass *analysis.Pass, field *types.Var, tag string, s } for _, enc := range [...]string{"json", "xml"} { - if reflect.StructTag(tag).Get(enc) != "" { + switch reflect.StructTag(tag).Get(enc) { + // Ignore warning if the field not exported and the tag is marked as + // ignored. + case "", "-": + default: pass.Reportf(field.Pos(), "struct field %s has %s tag but is not exported", field.Name(), enc) return } @@ -203,12 +207,12 @@ var ( ) // validateStructTag parses the struct tag and returns an error if it is not -// in the canonical format, which is a space-separated list of key:"value" -// settings. The value may contain spaces. +// in the canonical format, as defined by reflect.StructTag. func validateStructTag(tag string) error { // This code is based on the StructTag.Get code in package reflect. n := 0 + var keys []string for ; tag != ""; n++ { if n > 0 && tag != "" && tag[0] != ' ' { // More restrictive than reflect, but catches likely mistakes @@ -236,14 +240,27 @@ func validateStructTag(tag string) error { if i == 0 { return errTagKeySyntax } - if i+1 >= len(tag) || tag[i] != ':' { + if i+1 >= len(tag) || tag[i] < ' ' || tag[i] == 0x7f { return errTagSyntax } - if tag[i+1] != '"' { + key := tag[:i] + keys = append(keys, key) + tag = tag[i:] + + // If we found a space char here - assume that we have a tag with + // multiple keys. + if tag[0] == ' ' { + continue + } + + // Spaces were filtered above so we assume that here we have + // only valid tag value started with `:"`. + if tag[0] != ':' || tag[1] != '"' { return errTagValueSyntax } - key := tag[:i] - tag = tag[i+1:] + + // Remove the colon leaving tag at the start of the quoted string. + tag = tag[1:] // Scan quoted string to find value. i = 1 @@ -259,51 +276,56 @@ func validateStructTag(tag string) error { qvalue := tag[:i+1] tag = tag[i+1:] - value, err := strconv.Unquote(qvalue) + wholeValue, err := strconv.Unquote(qvalue) if err != nil { return errTagValueSyntax } - if !checkTagSpaces[key] { - continue - } - - switch key { - case "xml": - // If the first or last character in the XML tag is a space, it is - // suspicious. - if strings.Trim(value, " ") != value { - return errTagValueSpace + for _, key := range keys { + if !checkTagSpaces[key] { + continue } - // If there are multiple spaces, they are suspicious. - if strings.Count(value, " ") > 1 { - return errTagValueSpace - } + value := wholeValue + switch key { + case "xml": + // If the first or last character in the XML tag is a space, it is + // suspicious. + if strings.Trim(value, " ") != value { + return errTagValueSpace + } - // If there is no comma, skip the rest of the checks. - comma := strings.IndexRune(value, ',') - if comma < 0 { - continue + // If there are multiple spaces, they are suspicious. + if strings.Count(value, " ") > 1 { + return errTagValueSpace + } + + // If there is no comma, skip the rest of the checks. + comma := strings.IndexRune(value, ',') + if comma < 0 { + continue + } + + // If the character before a comma is a space, this is suspicious. + if comma > 0 && value[comma-1] == ' ' { + return errTagValueSpace + } + value = value[comma+1:] + case "json": + // JSON allows using spaces in the name, so skip it. + comma := strings.IndexRune(value, ',') + if comma < 0 { + continue + } + value = value[comma+1:] } - // If the character before a comma is a space, this is suspicious. - if comma > 0 && value[comma-1] == ' ' { + if strings.IndexByte(value, ' ') >= 0 { return errTagValueSpace } - value = value[comma+1:] - case "json": - // JSON allows using spaces in the name, so skip it. - comma := strings.IndexRune(value, ',') - if comma < 0 { - continue - } - value = value[comma+1:] } - if strings.IndexByte(value, ' ') >= 0 { - return errTagValueSpace - } + keys = keys[:0] } return nil } diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go new file mode 100644 index 0000000000..d2b9a5640d --- /dev/null +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go @@ -0,0 +1,154 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testinggoroutine + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = `report calls to (*testing.T).Fatal from goroutines started by a test. + +Functions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and +Skip{,f,Now} methods of *testing.T, must be called from the test goroutine itself. +This checker detects calls to these functions that occur within a goroutine +started by the test. For example: + +func TestFoo(t *testing.T) { + go func() { + t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine + }() +} +` + +var Analyzer = &analysis.Analyzer{ + Name: "testinggoroutine", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +var forbidden = map[string]bool{ + "FailNow": true, + "Fatal": true, + "Fatalf": true, + "Skip": true, + "Skipf": true, + "SkipNow": true, +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + if !analysisutil.Imports(pass.Pkg, "testing") { + return nil, nil + } + + // Filter out anything that isn't a function declaration. + onlyFuncs := []ast.Node{ + (*ast.FuncDecl)(nil), + } + + inspect.Nodes(onlyFuncs, func(node ast.Node, push bool) bool { + fnDecl, ok := node.(*ast.FuncDecl) + if !ok { + return false + } + + if !hasBenchmarkOrTestParams(fnDecl) { + return false + } + + // Now traverse the benchmark/test's body and check that none of the + // forbidden methods are invoked in the goroutines within the body. + ast.Inspect(fnDecl, func(n ast.Node) bool { + goStmt, ok := n.(*ast.GoStmt) + if !ok { + return true + } + + checkGoStmt(pass, goStmt) + + // No need to further traverse the GoStmt since right + // above we manually traversed it in the ast.Inspect(goStmt, ...) + return false + }) + + return false + }) + + return nil, nil +} + +func hasBenchmarkOrTestParams(fnDecl *ast.FuncDecl) bool { + // Check that the function's arguments include "*testing.T" or "*testing.B". + params := fnDecl.Type.Params.List + + for _, param := range params { + if _, ok := typeIsTestingDotTOrB(param.Type); ok { + return true + } + } + + return false +} + +func typeIsTestingDotTOrB(expr ast.Expr) (string, bool) { + starExpr, ok := expr.(*ast.StarExpr) + if !ok { + return "", false + } + selExpr, ok := starExpr.X.(*ast.SelectorExpr) + if !ok { + return "", false + } + + varPkg := selExpr.X.(*ast.Ident) + if varPkg.Name != "testing" { + return "", false + } + + varTypeName := selExpr.Sel.Name + ok = varTypeName == "B" || varTypeName == "T" + return varTypeName, ok +} + +// checkGoStmt traverses the goroutine and checks for the +// use of the forbidden *testing.(B, T) methods. +func checkGoStmt(pass *analysis.Pass, goStmt *ast.GoStmt) { + // Otherwise examine the goroutine to check for the forbidden methods. + ast.Inspect(goStmt, func(n ast.Node) bool { + selExpr, ok := n.(*ast.SelectorExpr) + if !ok { + return true + } + + _, bad := forbidden[selExpr.Sel.Name] + if !bad { + return true + } + + // Now filter out false positives by the import-path/type. + ident, ok := selExpr.X.(*ast.Ident) + if !ok { + return true + } + if ident.Obj == nil || ident.Obj.Decl == nil { + return true + } + field, ok := ident.Obj.Decl.(*ast.Field) + if !ok { + return true + } + if typeName, ok := typeIsTestingDotTOrB(field.Type); ok { + pass.ReportRangef(selExpr, "call to (*%s).%s from a non-test goroutine", typeName, selExpr.Sel) + } + return true + }) +} diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go index f9cc993cbb..92b37caff9 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go @@ -30,7 +30,7 @@ var Analyzer = &analysis.Analyzer{ func run(pass *analysis.Pass) (interface{}, error) { switch pass.Pkg.Path() { - case "encoding/gob", "encoding/json", "encoding/xml": + case "encoding/gob", "encoding/json", "encoding/xml", "encoding/asn1": // These packages know how to use their own APIs. // Sometimes they are testing what happens to incorrect programs. return nil, nil @@ -53,9 +53,10 @@ func run(pass *analysis.Pass) (interface{}, error) { recv := fn.Type().(*types.Signature).Recv() if fn.Name() == "Unmarshal" && recv == nil { // "encoding/json".Unmarshal - // "encoding/xml".Unmarshal + // "encoding/xml".Unmarshal + // "encoding/asn1".Unmarshal switch fn.Pkg().Path() { - case "encoding/json", "encoding/xml": + case "encoding/json", "encoding/xml", "encoding/asn1": argidx = 1 // func([]byte, interface{}) } } else if fn.Name() == "Decode" && recv != nil { diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go index d5bafb859d..ed86e5ebf0 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go @@ -13,6 +13,7 @@ import ( "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" "golang.org/x/tools/go/ast/inspector" ) @@ -36,32 +37,44 @@ func run(pass *analysis.Pass) (interface{}, error) { nodeFilter := []ast.Node{ (*ast.CallExpr)(nil), + (*ast.StarExpr)(nil), + (*ast.UnaryExpr)(nil), } inspect.Preorder(nodeFilter, func(n ast.Node) { - x := n.(*ast.CallExpr) - if len(x.Args) != 1 { - return - } - if hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) && - hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) && - !isSafeUintptr(pass.TypesInfo, x.Args[0]) { - pass.ReportRangef(x, "possible misuse of unsafe.Pointer") + switch x := n.(type) { + case *ast.CallExpr: + if len(x.Args) == 1 && + hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) && + hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) && + !isSafeUintptr(pass.TypesInfo, x.Args[0]) { + pass.ReportRangef(x, "possible misuse of unsafe.Pointer") + } + case *ast.StarExpr: + if t := pass.TypesInfo.Types[x].Type; isReflectHeader(t) { + pass.ReportRangef(x, "possible misuse of %s", t) + } + case *ast.UnaryExpr: + if x.Op != token.AND { + return + } + if t := pass.TypesInfo.Types[x.X].Type; isReflectHeader(t) { + pass.ReportRangef(x, "possible misuse of %s", t) + } } }) return nil, nil } // isSafeUintptr reports whether x - already known to be a uintptr - -// is safe to convert to unsafe.Pointer. It is safe if x is itself derived -// directly from an unsafe.Pointer via conversion and pointer arithmetic -// or if x is the result of reflect.Value.Pointer or reflect.Value.UnsafeAddr -// or obtained from the Data field of a *reflect.SliceHeader or *reflect.StringHeader. +// is safe to convert to unsafe.Pointer. func isSafeUintptr(info *types.Info, x ast.Expr) bool { - switch x := x.(type) { - case *ast.ParenExpr: - return isSafeUintptr(info, x.X) + // Check unsafe.Pointer safety rules according to + // https://golang.org/pkg/unsafe/#Pointer. + switch x := analysisutil.Unparen(x).(type) { case *ast.SelectorExpr: + // "(6) Conversion of a reflect.SliceHeader or + // reflect.StringHeader Data field to or from Pointer." if x.Sel.Name != "Data" { break } @@ -78,44 +91,56 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool { // For now approximate by saying that *Header is okay // but Header is not. pt, ok := info.Types[x.X].Type.(*types.Pointer) - if ok { - t, ok := pt.Elem().(*types.Named) - if ok && t.Obj().Pkg().Path() == "reflect" { - switch t.Obj().Name() { - case "StringHeader", "SliceHeader": - return true - } - } + if ok && isReflectHeader(pt.Elem()) { + return true } case *ast.CallExpr: - switch len(x.Args) { - case 0: - // maybe call to reflect.Value.Pointer or reflect.Value.UnsafeAddr. - sel, ok := x.Fun.(*ast.SelectorExpr) - if !ok { - break - } - switch sel.Sel.Name { - case "Pointer", "UnsafeAddr": - t, ok := info.Types[sel.X].Type.(*types.Named) - if ok && t.Obj().Pkg().Path() == "reflect" && t.Obj().Name() == "Value" { - return true - } + // "(5) Conversion of the result of reflect.Value.Pointer or + // reflect.Value.UnsafeAddr from uintptr to Pointer." + if len(x.Args) != 0 { + break + } + sel, ok := x.Fun.(*ast.SelectorExpr) + if !ok { + break + } + switch sel.Sel.Name { + case "Pointer", "UnsafeAddr": + t, ok := info.Types[sel.X].Type.(*types.Named) + if ok && t.Obj().Pkg().Path() == "reflect" && t.Obj().Name() == "Value" { + return true } - - case 1: - // maybe conversion of uintptr to unsafe.Pointer - return hasBasicType(info, x.Fun, types.Uintptr) && - hasBasicType(info, x.Args[0], types.UnsafePointer) } + } + + // "(3) Conversion of a Pointer to a uintptr and back, with arithmetic." + return isSafeArith(info, x) +} + +// isSafeArith reports whether x is a pointer arithmetic expression that is safe +// to convert to unsafe.Pointer. +func isSafeArith(info *types.Info, x ast.Expr) bool { + switch x := analysisutil.Unparen(x).(type) { + case *ast.CallExpr: + // Base case: initial conversion from unsafe.Pointer to uintptr. + return len(x.Args) == 1 && + hasBasicType(info, x.Fun, types.Uintptr) && + hasBasicType(info, x.Args[0], types.UnsafePointer) case *ast.BinaryExpr: + // "It is valid both to add and to subtract offsets from a + // pointer in this way. It is also valid to use &^ to round + // pointers, usually for alignment." switch x.Op { case token.ADD, token.SUB, token.AND_NOT: - return isSafeUintptr(info, x.X) && !isSafeUintptr(info, x.Y) + // TODO(mdempsky): Match compiler + // semantics. ADD allows a pointer on either + // side; SUB and AND_NOT don't care about RHS. + return isSafeArith(info, x.X) && !isSafeArith(info, x.Y) } } + return false } @@ -128,3 +153,16 @@ func hasBasicType(info *types.Info, x ast.Expr, kind types.BasicKind) bool { b, ok := t.(*types.Basic) return ok && b.Kind() == kind } + +// isReflectHeader reports whether t is reflect.SliceHeader or reflect.StringHeader. +func isReflectHeader(t types.Type) bool { + if named, ok := t.(*types.Named); ok { + if obj := named.Obj(); obj.Pkg() != nil && obj.Pkg().Path() == "reflect" { + switch obj.Name() { + case "SliceHeader", "StringHeader": + return true + } + } + } + return false +} diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go index 76d4ab2382..bececee7e9 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go @@ -44,7 +44,7 @@ var funcs, stringMethods stringSetFlag func init() { // TODO(adonovan): provide a comment syntax to allow users to // add their functions to this set using facts. - funcs.Set("errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse") + funcs.Set("errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse,context.WithValue,context.WithCancel,context.WithDeadline,context.WithTimeout") Analyzer.Flags.Var(&funcs, "funcs", "comma-separated list of functions whose results must be used") diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go index 2ed274949b..713e1380ef 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go @@ -63,6 +63,7 @@ type Config struct { ImportPath string GoFiles []string NonGoFiles []string + IgnoredFiles []string ImportMap map[string]string PackageFile map[string]string Standard map[string]bool @@ -333,6 +334,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re Fset: fset, Files: files, OtherFiles: cfg.NonGoFiles, + IgnoredFiles: cfg.IgnoredFiles, Pkg: pkg, TypesInfo: info, TypesSizes: tc.Sizes, diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/validate.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/validate.go index be98143461..ad0e7276c9 100644 --- a/src/cmd/vendor/golang.org/x/tools/go/analysis/validate.go +++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/validate.go @@ -3,6 +3,7 @@ package analysis import ( "fmt" "reflect" + "strings" "unicode" ) @@ -58,14 +59,28 @@ func Validate(analyzers []*Analyzer) error { } // recursion - for i, req := range a.Requires { + for _, req := range a.Requires { if err := visit(req); err != nil { - return fmt.Errorf("%s.Requires[%d]: %v", a.Name, i, err) + return err } } color[a] = black } + if color[a] == grey { + stack := []*Analyzer{a} + inCycle := map[string]bool{} + for len(stack) > 0 { + current := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if color[current] == grey && !inCycle[current.Name] { + inCycle[current.Name] = true + stack = append(stack, current.Requires...) + } + } + return &CycleInRequiresGraphError{AnalyzerNames: inCycle} + } + return nil } for _, a := range analyzers { @@ -95,3 +110,17 @@ func validIdent(name string) bool { } return name != "" } + +type CycleInRequiresGraphError struct { + AnalyzerNames map[string]bool +} + +func (e *CycleInRequiresGraphError) Error() string { + var b strings.Builder + b.WriteString("cycle detected involving the following analyzers:") + for n := range e.AnalyzerNames { + b.WriteByte(' ') + b.WriteString(n) + } + return b.String() +} diff --git a/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go b/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go index 26586810c7..01f6e829f7 100644 --- a/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go +++ b/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go @@ -14,6 +14,12 @@ import ( "strings" "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/internal/lsp/fuzzy" +) + +var ( + GetTypeErrors func(p interface{}) []types.Error + SetTypeErrors func(p interface{}, errors []types.Error) ) func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos { @@ -45,32 +51,34 @@ func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.T default: panic("unknown basic type") } - case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice: + case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice, *types.Array: return ast.NewIdent("nil") case *types.Struct: - texpr := typeExpr(fset, f, pkg, typ) // typ because we want the name here. + texpr := TypeExpr(fset, f, pkg, typ) // typ because we want the name here. if texpr == nil { return nil } return &ast.CompositeLit{ Type: texpr, } - case *types.Array: - texpr := typeExpr(fset, f, pkg, u.Elem()) - if texpr == nil { - return nil - } - return &ast.CompositeLit{ - Type: &ast.ArrayType{ - Elt: texpr, - Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%v", u.Len())}, - }, - } } return nil } -func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { +// IsZeroValue checks whether the given expression is a 'zero value' (as determined by output of +// analysisinternal.ZeroValue) +func IsZeroValue(expr ast.Expr) bool { + switch e := expr.(type) { + case *ast.BasicLit: + return e.Value == "0" || e.Value == `""` + case *ast.Ident: + return e.Name == "nil" || e.Name == "false" + default: + return false + } +} + +func TypeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { switch t := typ.(type) { case *types.Basic: switch t.Kind() { @@ -79,7 +87,96 @@ func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Ty default: return ast.NewIdent(t.Name()) } + case *types.Pointer: + x := TypeExpr(fset, f, pkg, t.Elem()) + if x == nil { + return nil + } + return &ast.UnaryExpr{ + Op: token.MUL, + X: x, + } + case *types.Array: + elt := TypeExpr(fset, f, pkg, t.Elem()) + if elt == nil { + return nil + } + return &ast.ArrayType{ + Len: &ast.BasicLit{ + Kind: token.INT, + Value: fmt.Sprintf("%d", t.Len()), + }, + Elt: elt, + } + case *types.Slice: + elt := TypeExpr(fset, f, pkg, t.Elem()) + if elt == nil { + return nil + } + return &ast.ArrayType{ + Elt: elt, + } + case *types.Map: + key := TypeExpr(fset, f, pkg, t.Key()) + value := TypeExpr(fset, f, pkg, t.Elem()) + if key == nil || value == nil { + return nil + } + return &ast.MapType{ + Key: key, + Value: value, + } + case *types.Chan: + dir := ast.ChanDir(t.Dir()) + if t.Dir() == types.SendRecv { + dir = ast.SEND | ast.RECV + } + value := TypeExpr(fset, f, pkg, t.Elem()) + if value == nil { + return nil + } + return &ast.ChanType{ + Dir: dir, + Value: value, + } + case *types.Signature: + var params []*ast.Field + for i := 0; i < t.Params().Len(); i++ { + p := TypeExpr(fset, f, pkg, t.Params().At(i).Type()) + if p == nil { + return nil + } + params = append(params, &ast.Field{ + Type: p, + Names: []*ast.Ident{ + { + Name: t.Params().At(i).Name(), + }, + }, + }) + } + var returns []*ast.Field + for i := 0; i < t.Results().Len(); i++ { + r := TypeExpr(fset, f, pkg, t.Results().At(i).Type()) + if r == nil { + return nil + } + returns = append(returns, &ast.Field{ + Type: r, + }) + } + return &ast.FuncType{ + Params: &ast.FieldList{ + List: params, + }, + Results: &ast.FieldList{ + List: returns, + }, + } case *types.Named: + if t.Obj().Pkg() == nil { + return ast.NewIdent(t.Obj().Name()) + } if t.Obj().Pkg() == pkg { return ast.NewIdent(t.Obj().Name()) } @@ -101,14 +198,15 @@ func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Ty X: ast.NewIdent(pkgName), Sel: ast.NewIdent(t.Obj().Name()), } + case *types.Struct: + return ast.NewIdent(t.String()) + case *types.Interface: + return ast.NewIdent(t.String()) default: - return nil // TODO: anonymous structs, but who does that + return nil } } -var GetTypeErrors = func(p interface{}) []types.Error { return nil } -var SetTypeErrors = func(p interface{}, errors []types.Error) {} - type TypeErrorPass string const ( @@ -116,3 +214,212 @@ const ( NoResultValues TypeErrorPass = "noresultvalues" UndeclaredName TypeErrorPass = "undeclaredname" ) + +// StmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable. +// Some examples: +// +// Basic Example: +// z := 1 +// y := z + x +// If x is undeclared, then this function would return `y := z + x`, so that we +// can insert `x := ` on the line before `y := z + x`. +// +// If stmt example: +// if z == 1 { +// } else if z == y {} +// If y is undeclared, then this function would return `if z == 1 {`, because we cannot +// insert a statement between an if and an else if statement. As a result, we need to find +// the top of the if chain to insert `y := ` before. +func StmtToInsertVarBefore(path []ast.Node) ast.Stmt { + enclosingIndex := -1 + for i, p := range path { + if _, ok := p.(ast.Stmt); ok { + enclosingIndex = i + break + } + } + if enclosingIndex == -1 { + return nil + } + enclosingStmt := path[enclosingIndex] + switch enclosingStmt.(type) { + case *ast.IfStmt: + // The enclosingStmt is inside of the if declaration, + // We need to check if we are in an else-if stmt and + // get the base if statement. + return baseIfStmt(path, enclosingIndex) + case *ast.CaseClause: + // Get the enclosing switch stmt if the enclosingStmt is + // inside of the case statement. + for i := enclosingIndex + 1; i < len(path); i++ { + if node, ok := path[i].(*ast.SwitchStmt); ok { + return node + } else if node, ok := path[i].(*ast.TypeSwitchStmt); ok { + return node + } + } + } + if len(path) <= enclosingIndex+1 { + return enclosingStmt.(ast.Stmt) + } + // Check if the enclosing statement is inside another node. + switch expr := path[enclosingIndex+1].(type) { + case *ast.IfStmt: + // Get the base if statement. + return baseIfStmt(path, enclosingIndex+1) + case *ast.ForStmt: + if expr.Init == enclosingStmt || expr.Post == enclosingStmt { + return expr + } + } + return enclosingStmt.(ast.Stmt) +} + +// baseIfStmt walks up the if/else-if chain until we get to +// the top of the current if chain. +func baseIfStmt(path []ast.Node, index int) ast.Stmt { + stmt := path[index] + for i := index + 1; i < len(path); i++ { + if node, ok := path[i].(*ast.IfStmt); ok && node.Else == stmt { + stmt = node + continue + } + break + } + return stmt.(ast.Stmt) +} + +// WalkASTWithParent walks the AST rooted at n. The semantics are +// similar to ast.Inspect except it does not call f(nil). +func WalkASTWithParent(n ast.Node, f func(n ast.Node, parent ast.Node) bool) { + var ancestors []ast.Node + ast.Inspect(n, func(n ast.Node) (recurse bool) { + if n == nil { + ancestors = ancestors[:len(ancestors)-1] + return false + } + + var parent ast.Node + if len(ancestors) > 0 { + parent = ancestors[len(ancestors)-1] + } + ancestors = append(ancestors, n) + return f(n, parent) + }) +} + +// FindMatchingIdents finds all identifiers in 'node' that match any of the given types. +// 'pos' represents the position at which the identifiers may be inserted. 'pos' must be within +// the scope of each of identifier we select. Otherwise, we will insert a variable at 'pos' that +// is unrecognized. +func FindMatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]*ast.Ident { + matches := map[types.Type][]*ast.Ident{} + // Initialize matches to contain the variable types we are searching for. + for _, typ := range typs { + if typ == nil { + continue + } + matches[typ] = []*ast.Ident{} + } + seen := map[types.Object]struct{}{} + ast.Inspect(node, func(n ast.Node) bool { + if n == nil { + return false + } + // Prevent circular definitions. If 'pos' is within an assignment statement, do not + // allow any identifiers in that assignment statement to be selected. Otherwise, + // we could do the following, where 'x' satisfies the type of 'f0': + // + // x := fakeStruct{f0: x} + // + assignment, ok := n.(*ast.AssignStmt) + if ok && pos > assignment.Pos() && pos <= assignment.End() { + return false + } + if n.End() > pos { + return n.Pos() <= pos + } + ident, ok := n.(*ast.Ident) + if !ok || ident.Name == "_" { + return true + } + obj := info.Defs[ident] + if obj == nil || obj.Type() == nil { + return true + } + if _, ok := obj.(*types.TypeName); ok { + return true + } + // Prevent duplicates in matches' values. + if _, ok = seen[obj]; ok { + return true + } + seen[obj] = struct{}{} + // Find the scope for the given position. Then, check whether the object + // exists within the scope. + innerScope := pkg.Scope().Innermost(pos) + if innerScope == nil { + return true + } + _, foundObj := innerScope.LookupParent(ident.Name, pos) + if foundObj != obj { + return true + } + // The object must match one of the types that we are searching for. + if idents, ok := matches[obj.Type()]; ok { + matches[obj.Type()] = append(idents, ast.NewIdent(ident.Name)) + } + // If the object type does not exactly match any of the target types, greedily + // find the first target type that the object type can satisfy. + for typ := range matches { + if obj.Type() == typ { + continue + } + if equivalentTypes(obj.Type(), typ) { + matches[typ] = append(matches[typ], ast.NewIdent(ident.Name)) + } + } + return true + }) + return matches +} + +func equivalentTypes(want, got types.Type) bool { + if want == got || types.Identical(want, got) { + return true + } + // Code segment to help check for untyped equality from (golang/go#32146). + if rhs, ok := want.(*types.Basic); ok && rhs.Info()&types.IsUntyped > 0 { + if lhs, ok := got.Underlying().(*types.Basic); ok { + return rhs.Info()&types.IsConstType == lhs.Info()&types.IsConstType + } + } + return types.AssignableTo(want, got) +} + +// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the +// given pattern. We return the identifier whose name is most similar to the pattern. +func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr { + fuzz := fuzzy.NewMatcher(pattern) + var bestFuzz ast.Expr + highScore := float32(0) // minimum score is 0 (no match) + for _, ident := range idents { + // TODO: Improve scoring algorithm. + score := fuzz.Score(ident.Name) + if score > highScore { + highScore = score + bestFuzz = ident + } else if score == 0 { + // Order matters in the fuzzy matching algorithm. If we find no match + // when matching the target to the identifier, try matching the identifier + // to the target. + revFuzz := fuzzy.NewMatcher(ident.Name) + revScore := revFuzz.Score(pattern) + if revScore > highScore { + highScore = revScore + bestFuzz = ident + } + } + } + return bestFuzz +} diff --git a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go new file mode 100644 index 0000000000..ac377035ec --- /dev/null +++ b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go @@ -0,0 +1,168 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fuzzy + +import ( + "unicode" +) + +// RuneRole specifies the role of a rune in the context of an input. +type RuneRole byte + +const ( + // RNone specifies a rune without any role in the input (i.e., whitespace/non-ASCII). + RNone RuneRole = iota + // RSep specifies a rune with the role of segment separator. + RSep + // RTail specifies a rune which is a lower-case tail in a word in the input. + RTail + // RUCTail specifies a rune which is an upper-case tail in a word in the input. + RUCTail + // RHead specifies a rune which is the first character in a word in the input. + RHead +) + +// RuneRoles detects the roles of each byte rune in an input string and stores it in the output +// slice. The rune role depends on the input type. Stops when it parsed all the runes in the string +// or when it filled the output. If output is nil, then it gets created. +func RuneRoles(str string, reuse []RuneRole) []RuneRole { + var output []RuneRole + if cap(reuse) < len(str) { + output = make([]RuneRole, 0, len(str)) + } else { + output = reuse[:0] + } + + prev, prev2 := rtNone, rtNone + for i := 0; i < len(str); i++ { + r := rune(str[i]) + + role := RNone + + curr := rtLower + if str[i] <= unicode.MaxASCII { + curr = runeType(rt[str[i]] - '0') + } + + if curr == rtLower { + if prev == rtNone || prev == rtPunct { + role = RHead + } else { + role = RTail + } + } else if curr == rtUpper { + role = RHead + + if prev == rtUpper { + // This and previous characters are both upper case. + + if i+1 == len(str) { + // This is last character, previous was also uppercase -> this is UCTail + // i.e., (current char is C): aBC / BC / ABC + role = RUCTail + } + } + } else if curr == rtPunct { + switch r { + case '.', ':': + role = RSep + } + } + if curr != rtLower { + if i > 1 && output[i-1] == RHead && prev2 == rtUpper && (output[i-2] == RHead || output[i-2] == RUCTail) { + // The previous two characters were uppercase. The current one is not a lower case, so the + // previous one can't be a HEAD. Make it a UCTail. + // i.e., (last char is current char - B must be a UCTail): ABC / ZABC / AB. + output[i-1] = RUCTail + } + } + + output = append(output, role) + prev2 = prev + prev = curr + } + return output +} + +type runeType byte + +const ( + rtNone runeType = iota + rtPunct + rtLower + rtUpper +) + +const rt = "00000000000000000000000000000000000000000000001122222222221000000333333333333333333333333330000002222222222222222222222222200000" + +// LastSegment returns the substring representing the last segment from the input, where each +// byte has an associated RuneRole in the roles slice. This makes sense only for inputs of Symbol +// or Filename type. +func LastSegment(input string, roles []RuneRole) string { + // Exclude ending separators. + end := len(input) - 1 + for end >= 0 && roles[end] == RSep { + end-- + } + if end < 0 { + return "" + } + + start := end - 1 + for start >= 0 && roles[start] != RSep { + start-- + } + + return input[start+1 : end+1] +} + +// ToLower transforms the input string to lower case, which is stored in the output byte slice. +// The lower casing considers only ASCII values - non ASCII values are left unmodified. +// Stops when parsed all input or when it filled the output slice. If output is nil, then it gets +// created. +func ToLower(input string, reuse []byte) []byte { + output := reuse + if cap(reuse) < len(input) { + output = make([]byte, len(input)) + } + + for i := 0; i < len(input); i++ { + r := rune(input[i]) + if r <= unicode.MaxASCII { + if 'A' <= r && r <= 'Z' { + r += 'a' - 'A' + } + } + output[i] = byte(r) + } + return output[:len(input)] +} + +// WordConsumer defines a consumer for a word delimited by the [start,end) byte offsets in an input +// (start is inclusive, end is exclusive). +type WordConsumer func(start, end int) + +// Words find word delimiters in an input based on its bytes' mappings to rune roles. The offset +// delimiters for each word are fed to the provided consumer function. +func Words(roles []RuneRole, consume WordConsumer) { + var wordStart int + for i, r := range roles { + switch r { + case RUCTail, RTail: + case RHead, RNone, RSep: + if i != wordStart { + consume(wordStart, i) + } + wordStart = i + if r != RHead { + // Skip this character. + wordStart = i + 1 + } + } + } + if wordStart != len(roles) { + consume(wordStart, len(roles)) + } +} diff --git a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go new file mode 100644 index 0000000000..16a643097d --- /dev/null +++ b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go @@ -0,0 +1,398 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package fuzzy implements a fuzzy matching algorithm. +package fuzzy + +import ( + "bytes" + "fmt" +) + +const ( + // MaxInputSize is the maximum size of the input scored against the fuzzy matcher. Longer inputs + // will be truncated to this size. + MaxInputSize = 127 + // MaxPatternSize is the maximum size of the pattern used to construct the fuzzy matcher. Longer + // inputs are truncated to this size. + MaxPatternSize = 63 +) + +type scoreVal int + +func (s scoreVal) val() int { + return int(s) >> 1 +} + +func (s scoreVal) prevK() int { + return int(s) & 1 +} + +func score(val int, prevK int /*0 or 1*/) scoreVal { + return scoreVal(val<<1 + prevK) +} + +// Matcher implements a fuzzy matching algorithm for scoring candidates against a pattern. +// The matcher does not support parallel usage. +type Matcher struct { + pattern string + patternLower []byte // lower-case version of the pattern + patternShort []byte // first characters of the pattern + caseSensitive bool // set if the pattern is mix-cased + + patternRoles []RuneRole // the role of each character in the pattern + roles []RuneRole // the role of each character in the tested string + + scores [MaxInputSize + 1][MaxPatternSize + 1][2]scoreVal + + scoreScale float32 + + lastCandidateLen int // in bytes + lastCandidateMatched bool + + // Here we save the last candidate in lower-case. This is basically a byte slice we reuse for + // performance reasons, so the slice is not reallocated for every candidate. + lowerBuf [MaxInputSize]byte + rolesBuf [MaxInputSize]RuneRole +} + +func (m *Matcher) bestK(i, j int) int { + if m.scores[i][j][0].val() < m.scores[i][j][1].val() { + return 1 + } + return 0 +} + +// NewMatcher returns a new fuzzy matcher for scoring candidates against the provided pattern. +func NewMatcher(pattern string) *Matcher { + if len(pattern) > MaxPatternSize { + pattern = pattern[:MaxPatternSize] + } + + m := &Matcher{ + pattern: pattern, + patternLower: ToLower(pattern, nil), + } + + for i, c := range m.patternLower { + if pattern[i] != c { + m.caseSensitive = true + break + } + } + + if len(pattern) > 3 { + m.patternShort = m.patternLower[:3] + } else { + m.patternShort = m.patternLower + } + + m.patternRoles = RuneRoles(pattern, nil) + + if len(pattern) > 0 { + maxCharScore := 4 + m.scoreScale = 1 / float32(maxCharScore*len(pattern)) + } + + return m +} + +// Score returns the score returned by matching the candidate to the pattern. +// This is not designed for parallel use. Multiple candidates must be scored sequentially. +// Returns a score between 0 and 1 (0 - no match, 1 - perfect match). +func (m *Matcher) Score(candidate string) float32 { + if len(candidate) > MaxInputSize { + candidate = candidate[:MaxInputSize] + } + lower := ToLower(candidate, m.lowerBuf[:]) + m.lastCandidateLen = len(candidate) + + if len(m.pattern) == 0 { + // Empty patterns perfectly match candidates. + return 1 + } + + if m.match(candidate, lower) { + sc := m.computeScore(candidate, lower) + if sc > minScore/2 && !m.poorMatch() { + m.lastCandidateMatched = true + if len(m.pattern) == len(candidate) { + // Perfect match. + return 1 + } + + if sc < 0 { + sc = 0 + } + normalizedScore := float32(sc) * m.scoreScale + if normalizedScore > 1 { + normalizedScore = 1 + } + + return normalizedScore + } + } + + m.lastCandidateMatched = false + return 0 +} + +const minScore = -10000 + +// MatchedRanges returns matches ranges for the last scored string as a flattened array of +// [begin, end) byte offset pairs. +func (m *Matcher) MatchedRanges() []int { + if len(m.pattern) == 0 || !m.lastCandidateMatched { + return nil + } + i, j := m.lastCandidateLen, len(m.pattern) + if m.scores[i][j][0].val() < minScore/2 && m.scores[i][j][1].val() < minScore/2 { + return nil + } + + var ret []int + k := m.bestK(i, j) + for i > 0 { + take := (k == 1) + k = m.scores[i][j][k].prevK() + if take { + if len(ret) == 0 || ret[len(ret)-1] != i { + ret = append(ret, i) + ret = append(ret, i-1) + } else { + ret[len(ret)-1] = i - 1 + } + j-- + } + i-- + } + // Reverse slice. + for i := 0; i < len(ret)/2; i++ { + ret[i], ret[len(ret)-1-i] = ret[len(ret)-1-i], ret[i] + } + return ret +} + +func (m *Matcher) match(candidate string, candidateLower []byte) bool { + i, j := 0, 0 + for ; i < len(candidateLower) && j < len(m.patternLower); i++ { + if candidateLower[i] == m.patternLower[j] { + j++ + } + } + if j != len(m.patternLower) { + return false + } + + // The input passes the simple test against pattern, so it is time to classify its characters. + // Character roles are used below to find the last segment. + m.roles = RuneRoles(candidate, m.rolesBuf[:]) + + return true +} + +func (m *Matcher) computeScore(candidate string, candidateLower []byte) int { + pattLen, candLen := len(m.pattern), len(candidate) + + for j := 0; j <= len(m.pattern); j++ { + m.scores[0][j][0] = minScore << 1 + m.scores[0][j][1] = minScore << 1 + } + m.scores[0][0][0] = score(0, 0) // Start with 0. + + segmentsLeft, lastSegStart := 1, 0 + for i := 0; i < candLen; i++ { + if m.roles[i] == RSep { + segmentsLeft++ + lastSegStart = i + 1 + } + } + + // A per-character bonus for a consecutive match. + consecutiveBonus := 2 + wordIdx := 0 // Word count within segment. + for i := 1; i <= candLen; i++ { + + role := m.roles[i-1] + isHead := role == RHead + + if isHead { + wordIdx++ + } else if role == RSep && segmentsLeft > 1 { + wordIdx = 0 + segmentsLeft-- + } + + var skipPenalty int + if i == 1 || (i-1) == lastSegStart { + // Skipping the start of first or last segment. + skipPenalty++ + } + + for j := 0; j <= pattLen; j++ { + // By default, we don't have a match. Fill in the skip data. + m.scores[i][j][1] = minScore << 1 + + // Compute the skip score. + k := 0 + if m.scores[i-1][j][0].val() < m.scores[i-1][j][1].val() { + k = 1 + } + + skipScore := m.scores[i-1][j][k].val() + // Do not penalize missing characters after the last matched segment. + if j != pattLen { + skipScore -= skipPenalty + } + m.scores[i][j][0] = score(skipScore, k) + + if j == 0 || candidateLower[i-1] != m.patternLower[j-1] { + // Not a match. + continue + } + pRole := m.patternRoles[j-1] + + if role == RTail && pRole == RHead { + if j > 1 { + // Not a match: a head in the pattern matches a tail character in the candidate. + continue + } + // Special treatment for the first character of the pattern. We allow + // matches in the middle of a word if they are long enough, at least + // min(3, pattern.length) characters. + if !bytes.HasPrefix(candidateLower[i-1:], m.patternShort) { + continue + } + } + + // Compute the char score. + var charScore int + // Bonus 1: the char is in the candidate's last segment. + if segmentsLeft <= 1 { + charScore++ + } + // Bonus 2: Case match or a Head in the pattern aligns with one in the word. + // Single-case patterns lack segmentation signals and we assume any character + // can be a head of a segment. + if candidate[i-1] == m.pattern[j-1] || role == RHead && (!m.caseSensitive || pRole == RHead) { + charScore++ + } + + // Penalty 1: pattern char is Head, candidate char is Tail. + if role == RTail && pRole == RHead { + charScore-- + } + // Penalty 2: first pattern character matched in the middle of a word. + if j == 1 && role == RTail { + charScore -= 4 + } + + // Third dimension encodes whether there is a gap between the previous match and the current + // one. + for k := 0; k < 2; k++ { + sc := m.scores[i-1][j-1][k].val() + charScore + + isConsecutive := k == 1 || i-1 == 0 || i-1 == lastSegStart + if isConsecutive { + // Bonus 3: a consecutive match. First character match also gets a bonus to + // ensure prefix final match score normalizes to 1.0. + // Logically, this is a part of charScore, but we have to compute it here because it + // only applies for consecutive matches (k == 1). + sc += consecutiveBonus + } + if k == 0 { + // Penalty 3: Matching inside a segment (and previous char wasn't matched). Penalize for the lack + // of alignment. + if role == RTail || role == RUCTail { + sc -= 3 + } + } + + if sc > m.scores[i][j][1].val() { + m.scores[i][j][1] = score(sc, k) + } + } + } + } + + result := m.scores[len(candidate)][len(m.pattern)][m.bestK(len(candidate), len(m.pattern))].val() + + return result +} + +// ScoreTable returns the score table computed for the provided candidate. Used only for debugging. +func (m *Matcher) ScoreTable(candidate string) string { + var buf bytes.Buffer + + var line1, line2, separator bytes.Buffer + line1.WriteString("\t") + line2.WriteString("\t") + for j := 0; j < len(m.pattern); j++ { + line1.WriteString(fmt.Sprintf("%c\t\t", m.pattern[j])) + separator.WriteString("----------------") + } + + buf.WriteString(line1.String()) + buf.WriteString("\n") + buf.WriteString(separator.String()) + buf.WriteString("\n") + + for i := 1; i <= len(candidate); i++ { + line1.Reset() + line2.Reset() + + line1.WriteString(fmt.Sprintf("%c\t", candidate[i-1])) + line2.WriteString("\t") + + for j := 1; j <= len(m.pattern); j++ { + line1.WriteString(fmt.Sprintf("M%6d(%c)\t", m.scores[i][j][0].val(), dir(m.scores[i][j][0].prevK()))) + line2.WriteString(fmt.Sprintf("H%6d(%c)\t", m.scores[i][j][1].val(), dir(m.scores[i][j][1].prevK()))) + } + buf.WriteString(line1.String()) + buf.WriteString("\n") + buf.WriteString(line2.String()) + buf.WriteString("\n") + buf.WriteString(separator.String()) + buf.WriteString("\n") + } + + return buf.String() +} + +func dir(prevK int) rune { + if prevK == 0 { + return 'M' + } + return 'H' +} + +func (m *Matcher) poorMatch() bool { + if len(m.pattern) < 2 { + return false + } + + i, j := m.lastCandidateLen, len(m.pattern) + k := m.bestK(i, j) + + var counter, len int + for i > 0 { + take := (k == 1) + k = m.scores[i][j][k].prevK() + if take { + len++ + if k == 0 && len < 3 && m.roles[i-1] == RTail { + // Short match in the middle of a word + counter++ + if counter > 1 { + return true + } + } + j-- + } else { + len = 0 + } + i-- + } + return false +} diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt index c0c008e038..4e47f41855 100644 --- a/src/cmd/vendor/modules.txt +++ b/src/cmd/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 +# github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 ## explicit github.com/google/pprof/driver github.com/google/pprof/internal/binutils @@ -15,21 +15,20 @@ github.com/google/pprof/profile github.com/google/pprof/third_party/d3 github.com/google/pprof/third_party/d3flamegraph github.com/google/pprof/third_party/svgpan -# github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 -## explicit +# github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 github.com/ianlancetaylor/demangle -# golang.org/x/arch v0.0.0-20200511175325-f7c78586839d +# golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff ## explicit golang.org/x/arch/arm/armasm golang.org/x/arch/arm64/arm64asm golang.org/x/arch/ppc64/ppc64asm golang.org/x/arch/x86/x86asm -# golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 +# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 ## explicit golang.org/x/crypto/ed25519 golang.org/x/crypto/ed25519/internal/edwards25519 golang.org/x/crypto/ssh/terminal -# golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 +# golang.org/x/mod v0.4.0 ## explicit golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile @@ -40,12 +39,12 @@ golang.org/x/mod/sumdb/dirhash golang.org/x/mod/sumdb/note golang.org/x/mod/sumdb/tlog golang.org/x/mod/zip -# golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 +# golang.org/x/sys v0.0.0-20201204225414-ed752295db88 ## explicit golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 +# golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 ## explicit golang.org/x/tools/go/analysis golang.org/x/tools/go/analysis/internal/analysisflags @@ -60,6 +59,7 @@ golang.org/x/tools/go/analysis/passes/composite golang.org/x/tools/go/analysis/passes/copylock golang.org/x/tools/go/analysis/passes/ctrlflow golang.org/x/tools/go/analysis/passes/errorsas +golang.org/x/tools/go/analysis/passes/framepointer golang.org/x/tools/go/analysis/passes/httpresponse golang.org/x/tools/go/analysis/passes/ifaceassert golang.org/x/tools/go/analysis/passes/inspect @@ -72,6 +72,7 @@ golang.org/x/tools/go/analysis/passes/shift golang.org/x/tools/go/analysis/passes/stdmethods golang.org/x/tools/go/analysis/passes/stringintconv golang.org/x/tools/go/analysis/passes/structtag +golang.org/x/tools/go/analysis/passes/testinggoroutine golang.org/x/tools/go/analysis/passes/tests golang.org/x/tools/go/analysis/passes/unmarshal golang.org/x/tools/go/analysis/passes/unreachable @@ -84,7 +85,7 @@ golang.org/x/tools/go/cfg golang.org/x/tools/go/types/objectpath golang.org/x/tools/go/types/typeutil golang.org/x/tools/internal/analysisinternal -# golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 -## explicit +golang.org/x/tools/internal/lsp/fuzzy +# golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 golang.org/x/xerrors golang.org/x/xerrors/internal diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go index 6381de840c..d50c45d691 100644 --- a/src/cmd/vet/main.go +++ b/src/cmd/vet/main.go @@ -14,6 +14,7 @@ import ( "golang.org/x/tools/go/analysis/passes/composite" "golang.org/x/tools/go/analysis/passes/copylock" "golang.org/x/tools/go/analysis/passes/errorsas" + "golang.org/x/tools/go/analysis/passes/framepointer" "golang.org/x/tools/go/analysis/passes/httpresponse" "golang.org/x/tools/go/analysis/passes/ifaceassert" "golang.org/x/tools/go/analysis/passes/loopclosure" @@ -24,6 +25,7 @@ import ( "golang.org/x/tools/go/analysis/passes/stdmethods" "golang.org/x/tools/go/analysis/passes/stringintconv" "golang.org/x/tools/go/analysis/passes/structtag" + "golang.org/x/tools/go/analysis/passes/testinggoroutine" "golang.org/x/tools/go/analysis/passes/tests" "golang.org/x/tools/go/analysis/passes/unmarshal" "golang.org/x/tools/go/analysis/passes/unreachable" @@ -44,6 +46,7 @@ func main() { composite.Analyzer, copylock.Analyzer, errorsas.Analyzer, + framepointer.Analyzer, httpresponse.Analyzer, ifaceassert.Analyzer, loopclosure.Analyzer, @@ -55,6 +58,7 @@ func main() { stringintconv.Analyzer, structtag.Analyzer, tests.Analyzer, + testinggoroutine.Analyzer, unmarshal.Analyzer, unreachable.Analyzer, unsafeptr.Analyzer, diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go index 5d8139d977..d15d1ce377 100644 --- a/src/cmd/vet/vet_test.go +++ b/src/cmd/vet/vet_test.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "internal/testenv" - "io/ioutil" "log" "os" "os/exec" @@ -32,7 +31,7 @@ func TestMain(m *testing.M) { } func testMain(m *testing.M) int { - dir, err := ioutil.TempDir("", "vet_test") + dir, err := os.MkdirTemp("", "vet_test") if err != nil { fmt.Fprintln(os.Stderr, err) return 1 @@ -345,7 +344,7 @@ var ( func wantedErrors(file, short string) (errs []wantedError) { cache := make(map[string]*regexp.Regexp) - src, err := ioutil.ReadFile(file) + src, err := os.ReadFile(file) if err != nil { log.Fatal(err) } |
