aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/addr2line/addr2line_test.go27
-rw-r--r--src/cmd/api/goapi.go40
-rw-r--r--src/cmd/api/goapi_test.go16
-rw-r--r--src/cmd/asm/internal/arch/arch.go5
-rw-r--r--src/cmd/asm/internal/arch/arm64.go31
-rw-r--r--src/cmd/asm/internal/asm/asm.go41
-rw-r--r--src/cmd/asm/internal/asm/endtoend_test.go33
-rw-r--r--src/cmd/asm/internal/asm/expr_test.go4
-rw-r--r--src/cmd/asm/internal/asm/line_test.go2
-rw-r--r--src/cmd/asm/internal/asm/operand_test.go24
-rw-r--r--src/cmd/asm/internal/asm/parse.go177
-rw-r--r--src/cmd/asm/internal/asm/pseudo_test.go1
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64.s809
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64error.s81
-rw-r--r--src/cmd/asm/internal/asm/testdata/buildtagerror.s8
-rw-r--r--src/cmd/asm/internal/asm/testdata/ppc64.s1936
-rw-r--r--src/cmd/asm/internal/asm/testdata/ppc64enc.s633
-rw-r--r--src/cmd/asm/internal/asm/testdata/riscvenc.s29
-rw-r--r--src/cmd/asm/internal/asm/testdata/s390x.s2
-rw-r--r--src/cmd/asm/internal/flags/flags.go27
-rw-r--r--src/cmd/asm/internal/lex/input.go3
-rw-r--r--src/cmd/asm/internal/lex/lex.go12
-rw-r--r--src/cmd/asm/internal/lex/lex_test.go3
-rw-r--r--src/cmd/asm/internal/lex/tokenizer.go11
-rw-r--r--src/cmd/asm/main.go8
-rw-r--r--src/cmd/buildid/buildid.go21
-rw-r--r--src/cmd/cgo/ast.go16
-rw-r--r--src/cmd/cgo/doc.go2
-rw-r--r--src/cmd/cgo/gcc.go39
-rw-r--r--src/cmd/cgo/godefs.go2
-rw-r--r--src/cmd/cgo/main.go37
-rw-r--r--src/cmd/cgo/out.go339
-rw-r--r--src/cmd/compile/fmt_test.go3
-rw-r--r--src/cmd/compile/fmtmap_test.go2
-rw-r--r--src/cmd/compile/internal/amd64/ssa.go15
-rw-r--r--src/cmd/compile/internal/arm64/ggen.go2
-rw-r--r--src/cmd/compile/internal/arm64/ssa.go143
-rw-r--r--src/cmd/compile/internal/gc/alg.go156
-rw-r--r--src/cmd/compile/internal/gc/align.go108
-rw-r--r--src/cmd/compile/internal/gc/bench_test.go24
-rw-r--r--src/cmd/compile/internal/gc/bexport.go43
-rw-r--r--src/cmd/compile/internal/gc/builtin.go97
-rw-r--r--src/cmd/compile/internal/gc/builtin/runtime.go5
-rw-r--r--src/cmd/compile/internal/gc/closure.go12
-rw-r--r--src/cmd/compile/internal/gc/const.go191
-rw-r--r--src/cmd/compile/internal/gc/dcl.go32
-rw-r--r--src/cmd/compile/internal/gc/dwinl.go96
-rw-r--r--src/cmd/compile/internal/gc/embed.go273
-rw-r--r--src/cmd/compile/internal/gc/esc.go53
-rw-r--r--src/cmd/compile/internal/gc/escape.go55
-rw-r--r--src/cmd/compile/internal/gc/export.go12
-rw-r--r--src/cmd/compile/internal/gc/float_test.go19
-rw-r--r--src/cmd/compile/internal/gc/fmt.go80
-rw-r--r--src/cmd/compile/internal/gc/go.go22
-rw-r--r--src/cmd/compile/internal/gc/gsubr.go50
-rw-r--r--src/cmd/compile/internal/gc/iexport.go61
-rw-r--r--src/cmd/compile/internal/gc/iimport.go51
-rw-r--r--src/cmd/compile/internal/gc/init.go8
-rw-r--r--src/cmd/compile/internal/gc/inl.go482
-rw-r--r--src/cmd/compile/internal/gc/inl_test.go4
-rw-r--r--src/cmd/compile/internal/gc/lex.go7
-rw-r--r--src/cmd/compile/internal/gc/main.go140
-rw-r--r--src/cmd/compile/internal/gc/noder.go157
-rw-r--r--src/cmd/compile/internal/gc/obj.go169
-rw-r--r--src/cmd/compile/internal/gc/order.go29
-rw-r--r--src/cmd/compile/internal/gc/pgen.go26
-rw-r--r--src/cmd/compile/internal/gc/plive.go430
-rw-r--r--src/cmd/compile/internal/gc/range.go17
-rw-r--r--src/cmd/compile/internal/gc/reflect.go27
-rw-r--r--src/cmd/compile/internal/gc/scc.go15
-rw-r--r--src/cmd/compile/internal/gc/scope.go4
-rw-r--r--src/cmd/compile/internal/gc/sinit.go29
-rw-r--r--src/cmd/compile/internal/gc/ssa.go877
-rw-r--r--src/cmd/compile/internal/gc/subr.go213
-rw-r--r--src/cmd/compile/internal/gc/swt.go29
-rw-r--r--src/cmd/compile/internal/gc/syntax.go197
-rw-r--r--src/cmd/compile/internal/gc/typecheck.go195
-rw-r--r--src/cmd/compile/internal/gc/universe.go10
-rw-r--r--src/cmd/compile/internal/gc/walk.go351
-rw-r--r--src/cmd/compile/internal/logopt/log_opts.go89
-rw-r--r--src/cmd/compile/internal/logopt/logopt_test.go41
-rw-r--r--src/cmd/compile/internal/ppc64/ssa.go82
-rw-r--r--src/cmd/compile/internal/riscv64/ggen.go10
-rw-r--r--src/cmd/compile/internal/riscv64/ssa.go52
-rw-r--r--src/cmd/compile/internal/s390x/ssa.go34
-rw-r--r--src/cmd/compile/internal/ssa/addressingmodes.go8
-rw-r--r--src/cmd/compile/internal/ssa/branchelim.go2
-rw-r--r--src/cmd/compile/internal/ssa/check.go44
-rw-r--r--src/cmd/compile/internal/ssa/compile.go53
-rw-r--r--src/cmd/compile/internal/ssa/config.go17
-rw-r--r--src/cmd/compile/internal/ssa/decompose.go87
-rw-r--r--src/cmd/compile/internal/ssa/expand_calls.go974
-rw-r--r--src/cmd/compile/internal/ssa/export_test.go4
-rw-r--r--src/cmd/compile/internal/ssa/flagalloc.go5
-rw-r--r--src/cmd/compile/internal/ssa/func.go24
-rw-r--r--src/cmd/compile/internal/ssa/func_test.go7
-rw-r--r--src/cmd/compile/internal/ssa/fuse_test.go4
-rw-r--r--src/cmd/compile/internal/ssa/gen/386.rules67
-rw-r--r--src/cmd/compile/internal/ssa/gen/386Ops.go20
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64.rules912
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64Ops.go8
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM.rules2232
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64.rules535
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64Ops.go47
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARMOps.go6
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS.rules74
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS64.rules52
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS64Ops.go6
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPSOps.go12
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64.rules138
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64Ops.go35
-rw-r--r--src/cmd/compile/internal/ssa/gen/RISCV64.rules290
-rw-r--r--src/cmd/compile/internal/ssa/gen/RISCV64Ops.go62
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390X.rules231
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390XOps.go26
-rw-r--r--src/cmd/compile/internal/ssa/gen/Wasm.rules1
-rw-r--r--src/cmd/compile/internal/ssa/gen/WasmOps.go8
-rw-r--r--src/cmd/compile/internal/ssa/gen/dec64.rules146
-rw-r--r--src/cmd/compile/internal/ssa/gen/generic.rules112
-rw-r--r--src/cmd/compile/internal/ssa/gen/genericOps.go42
-rw-r--r--src/cmd/compile/internal/ssa/gen/rulegen.go119
-rw-r--r--src/cmd/compile/internal/ssa/html.go64
-rw-r--r--src/cmd/compile/internal/ssa/lca.go2
-rw-r--r--src/cmd/compile/internal/ssa/loopreschedchecks.go2
-rw-r--r--src/cmd/compile/internal/ssa/op.go171
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go1234
-rw-r--r--src/cmd/compile/internal/ssa/prove.go2
-rw-r--r--src/cmd/compile/internal/ssa/regalloc.go69
-rw-r--r--src/cmd/compile/internal/ssa/regalloc_test.go12
-rw-r--r--src/cmd/compile/internal/ssa/rewrite.go272
-rw-r--r--src/cmd/compile/internal/ssa/rewrite386.go329
-rw-r--r--src/cmd/compile/internal/ssa/rewriteAMD64.go6157
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM.go5383
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM64.go1690
-rw-r--r--src/cmd/compile/internal/ssa/rewriteMIPS.go163
-rw-r--r--src/cmd/compile/internal/ssa/rewriteMIPS64.go112
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go1353
-rw-r--r--src/cmd/compile/internal/ssa/rewriteRISCV64.go1865
-rw-r--r--src/cmd/compile/internal/ssa/rewriteS390X.go982
-rw-r--r--src/cmd/compile/internal/ssa/rewriteWasm.go14
-rw-r--r--src/cmd/compile/internal/ssa/rewrite_test.go181
-rw-r--r--src/cmd/compile/internal/ssa/rewritedec64.go812
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go401
-rw-r--r--src/cmd/compile/internal/ssa/shortcircuit.go5
-rw-r--r--src/cmd/compile/internal/ssa/stackalloc.go3
-rw-r--r--src/cmd/compile/internal/ssa/value.go7
-rw-r--r--src/cmd/compile/internal/ssa/writebarrier.go32
-rw-r--r--src/cmd/compile/internal/syntax/parser.go10
-rw-r--r--src/cmd/compile/internal/test/divconst_test.go81
-rw-r--r--src/cmd/compile/internal/types/etype_string.go7
-rw-r--r--src/cmd/compile/internal/types/type.go85
-rw-r--r--src/cmd/compile/internal/wasm/ssa.go11
-rw-r--r--src/cmd/compile/internal/x86/387.go375
-rw-r--r--src/cmd/compile/internal/x86/galign.go16
-rw-r--r--src/cmd/compile/internal/x86/ssa.go9
-rw-r--r--src/cmd/cover/cover.go3
-rw-r--r--src/cmd/cover/cover_test.go31
-rw-r--r--src/cmd/cover/html.go5
-rw-r--r--src/cmd/dist/build.go60
-rw-r--r--src/cmd/dist/buildtool.go2
-rw-r--r--src/cmd/dist/cpuid_386.s16
-rw-r--r--src/cmd/dist/cpuid_amd64.s16
-rw-r--r--src/cmd/dist/cpuid_default.s10
-rw-r--r--src/cmd/dist/main.go9
-rw-r--r--src/cmd/dist/test.go70
-rw-r--r--src/cmd/dist/util_gc.go12
-rw-r--r--src/cmd/dist/util_gccgo.go13
-rw-r--r--src/cmd/doc/doc_test.go4
-rw-r--r--src/cmd/doc/pkg.go10
-rw-r--r--src/cmd/fix/gotypes.go6
-rw-r--r--src/cmd/fix/main.go30
-rw-r--r--src/cmd/fix/typecheck.go9
-rw-r--r--src/cmd/go.mod16
-rw-r--r--src/cmd/go.sum44
-rw-r--r--src/cmd/go/alldocs.go418
-rw-r--r--src/cmd/go/go_test.go196
-rw-r--r--src/cmd/go/go_windows_test.go14
-rw-r--r--src/cmd/go/help_test.go4
-rw-r--r--src/cmd/go/init_test.go26
-rw-r--r--src/cmd/go/internal/auth/netrc.go3
-rw-r--r--src/cmd/go/internal/base/base.go14
-rw-r--r--src/cmd/go/internal/base/flag.go37
-rw-r--r--src/cmd/go/internal/base/goflags.go60
-rw-r--r--src/cmd/go/internal/base/signal.go2
-rw-r--r--src/cmd/go/internal/bug/bug.go7
-rw-r--r--src/cmd/go/internal/cache/cache.go8
-rw-r--r--src/cmd/go/internal/cache/cache_test.go13
-rw-r--r--src/cmd/go/internal/cache/default.go3
-rw-r--r--src/cmd/go/internal/cache/hash_test.go3
-rw-r--r--src/cmd/go/internal/cfg/cfg.go21
-rw-r--r--src/cmd/go/internal/clean/clean.go24
-rw-r--r--src/cmd/go/internal/envcmd/env.go52
-rw-r--r--src/cmd/go/internal/fmtcmd/fmt.go3
-rw-r--r--src/cmd/go/internal/fsys/fsys.go689
-rw-r--r--src/cmd/go/internal/fsys/fsys_test.go1094
-rw-r--r--src/cmd/go/internal/generate/generate.go3
-rw-r--r--src/cmd/go/internal/get/get.go53
-rw-r--r--src/cmd/go/internal/help/helpdoc.go11
-rw-r--r--src/cmd/go/internal/imports/build.go5
-rw-r--r--src/cmd/go/internal/imports/read.go4
-rw-r--r--src/cmd/go/internal/imports/scan.go15
-rw-r--r--src/cmd/go/internal/imports/scan_test.go8
-rw-r--r--src/cmd/go/internal/imports/tags.go23
-rw-r--r--src/cmd/go/internal/imports/testdata/android/.h.go3
-rw-r--r--src/cmd/go/internal/imports/testdata/illumos/.h.go3
-rw-r--r--src/cmd/go/internal/list/list.go61
-rw-r--r--src/cmd/go/internal/load/pkg.go401
-rw-r--r--src/cmd/go/internal/load/test.go27
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock.go5
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go11
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go6
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go8
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go7
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go6
-rw-r--r--src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go6
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile.go14
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile_filelock.go6
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile_plan9.go13
-rw-r--r--src/cmd/go/internal/lockedfile/lockedfile_test.go9
-rw-r--r--src/cmd/go/internal/modcmd/download.go19
-rw-r--r--src/cmd/go/internal/modcmd/edit.go5
-rw-r--r--src/cmd/go/internal/modcmd/graph.go16
-rw-r--r--src/cmd/go/internal/modcmd/init.go43
-rw-r--r--src/cmd/go/internal/modcmd/tidy.go35
-rw-r--r--src/cmd/go/internal/modcmd/vendor.go87
-rw-r--r--src/cmd/go/internal/modcmd/verify.go28
-rw-r--r--src/cmd/go/internal/modcmd/why.go26
-rw-r--r--src/cmd/go/internal/modconv/convert_test.go5
-rw-r--r--src/cmd/go/internal/modconv/modconv_test.go6
-rw-r--r--src/cmd/go/internal/modfetch/cache.go82
-rw-r--r--src/cmd/go/internal/modfetch/cache_test.go3
-rw-r--r--src/cmd/go/internal/modfetch/codehost/codehost.go22
-rw-r--r--src/cmd/go/internal/modfetch/codehost/git.go27
-rw-r--r--src/cmd/go/internal/modfetch/codehost/git_test.go9
-rw-r--r--src/cmd/go/internal/modfetch/codehost/shell.go6
-rw-r--r--src/cmd/go/internal/modfetch/codehost/vcs.go10
-rw-r--r--src/cmd/go/internal/modfetch/coderepo.go90
-rw-r--r--src/cmd/go/internal/modfetch/coderepo_test.go46
-rw-r--r--src/cmd/go/internal/modfetch/fetch.go183
-rw-r--r--src/cmd/go/internal/modfetch/insecure.go3
-rw-r--r--src/cmd/go/internal/modfetch/proxy.go11
-rw-r--r--src/cmd/go/internal/modfetch/pseudo.go12
-rw-r--r--src/cmd/go/internal/modfetch/repo.go64
-rw-r--r--src/cmd/go/internal/modfetch/sumdb.go14
-rw-r--r--src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go3
-rw-r--r--src/cmd/go/internal/modget/get.go2077
-rw-r--r--src/cmd/go/internal/modget/query.go357
-rw-r--r--src/cmd/go/internal/modload/build.go28
-rw-r--r--src/cmd/go/internal/modload/buildlist.go267
-rw-r--r--src/cmd/go/internal/modload/help.go81
-rw-r--r--src/cmd/go/internal/modload/import.go379
-rw-r--r--src/cmd/go/internal/modload/import_test.go44
-rw-r--r--src/cmd/go/internal/modload/init.go422
-rw-r--r--src/cmd/go/internal/modload/list.go2
-rw-r--r--src/cmd/go/internal/modload/load.go1028
-rw-r--r--src/cmd/go/internal/modload/modfile.go367
-rw-r--r--src/cmd/go/internal/modload/mvs.go67
-rw-r--r--src/cmd/go/internal/modload/mvs_test.go31
-rw-r--r--src/cmd/go/internal/modload/query.go766
-rw-r--r--src/cmd/go/internal/modload/query_test.go25
-rw-r--r--src/cmd/go/internal/modload/search.go54
-rw-r--r--src/cmd/go/internal/modload/stat_openfile.go5
-rw-r--r--src/cmd/go/internal/modload/stat_unix.go5
-rw-r--r--src/cmd/go/internal/modload/stat_windows.go6
-rw-r--r--src/cmd/go/internal/modload/testgo.go11
-rw-r--r--src/cmd/go/internal/modload/vendor.go6
-rw-r--r--src/cmd/go/internal/mvs/mvs.go59
-rw-r--r--src/cmd/go/internal/mvs/mvs_test.go47
-rw-r--r--src/cmd/go/internal/renameio/renameio.go11
-rw-r--r--src/cmd/go/internal/renameio/renameio_test.go13
-rw-r--r--src/cmd/go/internal/renameio/umask_test.go8
-rw-r--r--src/cmd/go/internal/robustio/robustio.go2
-rw-r--r--src/cmd/go/internal/robustio/robustio_flaky.go5
-rw-r--r--src/cmd/go/internal/robustio/robustio_other.go3
-rw-r--r--src/cmd/go/internal/search/search.go14
-rw-r--r--src/cmd/go/internal/str/str_test.go27
-rw-r--r--src/cmd/go/internal/test/test.go24
-rw-r--r--src/cmd/go/internal/test/testflag.go16
-rw-r--r--src/cmd/go/internal/txtar/archive.go4
-rw-r--r--src/cmd/go/internal/vcs/discovery.go (renamed from src/cmd/go/internal/get/discovery.go)2
-rw-r--r--src/cmd/go/internal/vcs/discovery_test.go (renamed from src/cmd/go/internal/get/pkg_test.go)23
-rw-r--r--src/cmd/go/internal/vcs/vcs.go (renamed from src/cmd/go/internal/get/vcs.go)561
-rw-r--r--src/cmd/go/internal/vcs/vcs_test.go (renamed from src/cmd/go/internal/get/vcs_test.go)153
-rw-r--r--src/cmd/go/internal/version/version.go28
-rw-r--r--src/cmd/go/internal/vet/vet.go3
-rw-r--r--src/cmd/go/internal/web/api.go11
-rw-r--r--src/cmd/go/internal/web/file_test.go8
-rw-r--r--src/cmd/go/internal/web/http.go7
-rw-r--r--src/cmd/go/internal/work/action.go14
-rw-r--r--src/cmd/go/internal/work/build.go263
-rw-r--r--src/cmd/go/internal/work/build_test.go18
-rw-r--r--src/cmd/go/internal/work/buildid.go45
-rw-r--r--src/cmd/go/internal/work/exec.go312
-rw-r--r--src/cmd/go/internal/work/exec_test.go86
-rw-r--r--src/cmd/go/internal/work/gc.go131
-rw-r--r--src/cmd/go/internal/work/gccgo.go69
-rw-r--r--src/cmd/go/internal/work/init.go49
-rw-r--r--src/cmd/go/internal/work/security.go11
-rw-r--r--src/cmd/go/internal/work/security_test.go8
-rw-r--r--src/cmd/go/main.go3
-rw-r--r--src/cmd/go/proxy_test.go16
-rw-r--r--src/cmd/go/script_test.go45
-rw-r--r--src/cmd/go/testdata/addmod.go18
-rw-r--r--src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt12
-rw-r--r--src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt18
-rw-r--r--src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt28
-rw-r--r--src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt28
-rw-r--r--src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt28
-rw-r--r--src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt27
-rw-r--r--src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt30
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt12
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt9
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt19
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt9
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt2
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt16
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt22
-rw-r--r--src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt14
-rw-r--r--src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt19
-rw-r--r--src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt19
-rw-r--r--src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt18
-rw-r--r--src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt17
-rw-r--r--src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt19
-rw-r--r--src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt20
-rw-r--r--src/cmd/go/testdata/savedir.go8
-rw-r--r--src/cmd/go/testdata/script/build_cache_arch_mode.txt20
-rw-r--r--src/cmd/go/testdata/script/build_cache_disabled.txt8
-rw-r--r--src/cmd/go/testdata/script/build_cd_gopath_different.txt1
-rw-r--r--src/cmd/go/testdata/script/build_cgo_consistent_results.txt6
-rw-r--r--src/cmd/go/testdata/script/build_dash_x.txt2
-rw-r--r--src/cmd/go/testdata/script/build_exe.txt12
-rw-r--r--src/cmd/go/testdata/script/build_gopath_order.txt3
-rw-r--r--src/cmd/go/testdata/script/build_i_deprecate.txt24
-rw-r--r--src/cmd/go/testdata/script/build_import_comment.txt57
-rw-r--r--src/cmd/go/testdata/script/build_import_cycle.txt3
-rw-r--r--src/cmd/go/testdata/script/build_internal.txt45
-rw-r--r--src/cmd/go/testdata/script/build_issue6480.txt13
-rw-r--r--src/cmd/go/testdata/script/build_link_x_import_path_escape.txt8
-rw-r--r--src/cmd/go/testdata/script/build_n_cgo.txt4
-rw-r--r--src/cmd/go/testdata/script/build_no_go.txt4
-rw-r--r--src/cmd/go/testdata/script/build_output.txt34
-rw-r--r--src/cmd/go/testdata/script/build_overlay.txt308
-rw-r--r--src/cmd/go/testdata/script/build_patterns_outside_gopath.txt9
-rw-r--r--src/cmd/go/testdata/script/build_plugin_non_main.txt22
-rw-r--r--src/cmd/go/testdata/script/build_test_only.txt8
-rw-r--r--src/cmd/go/testdata/script/build_trimpath.txt31
-rw-r--r--src/cmd/go/testdata/script/build_trimpath_cgo.txt28
-rw-r--r--src/cmd/go/testdata/script/build_vendor.txt1
-rw-r--r--src/cmd/go/testdata/script/cgo_asm_error.txt8
-rw-r--r--src/cmd/go/testdata/script/cgo_bad_directives.txt43
-rw-r--r--src/cmd/go/testdata/script/cgo_depends_on_syscall.txt6
-rw-r--r--src/cmd/go/testdata/script/clean_binary.txt78
-rw-r--r--src/cmd/go/testdata/script/cover_asm.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_blank_func_decl.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_cgo.txt8
-rw-r--r--src/cmd/go/testdata/script/cover_cgo_extra_file.txt12
-rw-r--r--src/cmd/go/testdata/script/cover_cgo_extra_test.txt12
-rw-r--r--src/cmd/go/testdata/script/cover_cgo_xtest.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_dash_c.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_dep_loop.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_dot_import.txt20
-rw-r--r--src/cmd/go/testdata/script/cover_error.txt23
-rw-r--r--src/cmd/go/testdata/script/cover_import_main_loop.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_pattern.txt10
-rw-r--r--src/cmd/go/testdata/script/cover_statements.txt4
-rw-r--r--src/cmd/go/testdata/script/cover_sync_atomic_import.txt12
-rw-r--r--src/cmd/go/testdata/script/embed.txt72
-rw-r--r--src/cmd/go/testdata/script/env_write.txt56
-rw-r--r--src/cmd/go/testdata/script/gcflags_patterns.txt4
-rw-r--r--src/cmd/go/testdata/script/generate_bad_imports.txt6
-rw-r--r--src/cmd/go/testdata/script/generate_invalid.txt6
-rw-r--r--src/cmd/go/testdata/script/get_custom_domain_wildcard.txt3
-rw-r--r--src/cmd/go/testdata/script/get_dash_t.txt3
-rw-r--r--src/cmd/go/testdata/script/get_domain_root.txt3
-rw-r--r--src/cmd/go/testdata/script/get_dot_slash_download.txt3
-rw-r--r--src/cmd/go/testdata/script/get_go_file.txt18
-rw-r--r--src/cmd/go/testdata/script/get_goroot.txt3
-rw-r--r--src/cmd/go/testdata/script/get_insecure_custom_domain.txt3
-rw-r--r--src/cmd/go/testdata/script/get_insecure_deprecated.txt21
-rw-r--r--src/cmd/go/testdata/script/get_insecure_update.txt3
-rw-r--r--src/cmd/go/testdata/script/get_internal_wildcard.txt3
-rw-r--r--src/cmd/go/testdata/script/get_issue11307.txt3
-rw-r--r--src/cmd/go/testdata/script/get_legacy.txt (renamed from src/cmd/go/testdata/script/mod_get_legacy.txt)3
-rw-r--r--src/cmd/go/testdata/script/get_race.txt3
-rw-r--r--src/cmd/go/testdata/script/get_test_only.txt3
-rw-r--r--src/cmd/go/testdata/script/get_update.txt3
-rw-r--r--src/cmd/go/testdata/script/get_update_all.txt2
-rw-r--r--src/cmd/go/testdata/script/get_update_unknown_protocol.txt3
-rw-r--r--src/cmd/go/testdata/script/get_update_wildcard.txt3
-rw-r--r--src/cmd/go/testdata/script/get_vcs_error_message.txt1
-rw-r--r--src/cmd/go/testdata/script/get_vendor.txt3
-rw-r--r--src/cmd/go/testdata/script/gopath_moved_repo.txt5
-rw-r--r--src/cmd/go/testdata/script/gopath_vendor_dup_err.txt1
-rw-r--r--src/cmd/go/testdata/script/govcs.txt174
-rw-r--r--src/cmd/go/testdata/script/import_ignore.txt11
-rw-r--r--src/cmd/go/testdata/script/install_cgo_excluded.txt6
-rw-r--r--src/cmd/go/testdata/script/install_relative_gobin_fail.txt6
-rw-r--r--src/cmd/go/testdata/script/install_shadow_gopath.txt3
-rw-r--r--src/cmd/go/testdata/script/ldflag.txt44
-rw-r--r--src/cmd/go/testdata/script/link_matching_actionid.txt38
-rw-r--r--src/cmd/go/testdata/script/link_syso_issue33139.txt10
-rw-r--r--src/cmd/go/testdata/script/list_bad_import.txt18
-rw-r--r--src/cmd/go/testdata/script/list_case_collision.txt22
-rw-r--r--src/cmd/go/testdata/script/list_dedup_packages.txt1
-rw-r--r--src/cmd/go/testdata/script/list_overlay.txt63
-rw-r--r--src/cmd/go/testdata/script/list_symlink.txt1
-rw-r--r--src/cmd/go/testdata/script/list_symlink_internal.txt3
-rw-r--r--src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt3
-rw-r--r--src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt3
-rw-r--r--src/cmd/go/testdata/script/list_test_err.txt3
-rw-r--r--src/cmd/go/testdata/script/list_test_simple.txt20
-rw-r--r--src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt16
-rw-r--r--src/cmd/go/testdata/script/load_test_pkg_err.txt12
-rw-r--r--src/cmd/go/testdata/script/mod_all.txt100
-rw-r--r--src/cmd/go/testdata/script/mod_auth.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_bad_domain.txt18
-rw-r--r--src/cmd/go/testdata/script/mod_build_info_err.txt15
-rw-r--r--src/cmd/go/testdata/script/mod_case.txt9
-rw-r--r--src/cmd/go/testdata/script/mod_case_cgo.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_concurrent.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_concurrent_unzipinplace.txt17
-rw-r--r--src/cmd/go/testdata/script/mod_doc.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_domain_root.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_dot.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_download.txt32
-rw-r--r--src/cmd/go/testdata/script/mod_download_concurrent_read.txt26
-rw-r--r--src/cmd/go/testdata/script/mod_download_partial.txt10
-rw-r--r--src/cmd/go/testdata/script/mod_e.txt89
-rw-r--r--src/cmd/go/testdata/script/mod_enabled.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt107
-rw-r--r--src/cmd/go/testdata/script/mod_get_ambiguous_import.txt60
-rw-r--r--src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt87
-rw-r--r--src/cmd/go/testdata/script/mod_get_changes.txt70
-rw-r--r--src/cmd/go/testdata/script/mod_get_commit.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_get_downgrade.txt17
-rw-r--r--src/cmd/go/testdata/script/mod_get_downgrade_missing.txt43
-rw-r--r--src/cmd/go/testdata/script/mod_get_errors.txt69
-rw-r--r--src/cmd/go/testdata/script/mod_get_extra.txt69
-rw-r--r--src/cmd/go/testdata/script/mod_get_fossil.txt29
-rw-r--r--src/cmd/go/testdata/script/mod_get_incompatible.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_get_indirect.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_issue37438.txt37
-rw-r--r--src/cmd/go/testdata/script/mod_get_latest_pseudo.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_main.txt30
-rw-r--r--src/cmd/go/testdata/script/mod_get_moved.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_get_newcycle.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_get_none.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_get_nopkgs.txt40
-rw-r--r--src/cmd/go/testdata/script/mod_get_patch.txt130
-rw-r--r--src/cmd/go/testdata/script/mod_get_patchbound.txt84
-rw-r--r--src/cmd/go/testdata/script/mod_get_patchcycle.txt64
-rw-r--r--src/cmd/go/testdata/script/mod_get_patchmod.txt82
-rw-r--r--src/cmd/go/testdata/script/mod_get_patterns.txt12
-rw-r--r--src/cmd/go/testdata/script/mod_get_replaced.txt111
-rw-r--r--src/cmd/go/testdata/script/mod_get_retract.txt20
-rw-r--r--src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt10
-rw-r--r--src/cmd/go/testdata/script/mod_get_split.txt157
-rw-r--r--src/cmd/go/testdata/script/mod_get_sum_noroot.txt11
-rw-r--r--src/cmd/go/testdata/script/mod_get_test.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_trailing_slash.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_get_upgrade.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_wild.txt95
-rw-r--r--src/cmd/go/testdata/script/mod_go_version.txt41
-rw-r--r--src/cmd/go/testdata/script/mod_gobuild_import.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_gonoproxy.txt20
-rw-r--r--src/cmd/go/testdata/script/mod_gopkg_unstable.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_import.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_import_issue41113.txt28
-rw-r--r--src/cmd/go/testdata/script/mod_import_issue42891.txt14
-rw-r--r--src/cmd/go/testdata/script/mod_import_meta.txt45
-rw-r--r--src/cmd/go/testdata/script/mod_in_testdata_dir.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_indirect.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_init_dep.txt21
-rw-r--r--src/cmd/go/testdata/script/mod_init_path.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_init_tidy.txt30
-rw-r--r--src/cmd/go/testdata/script/mod_install_pkg_version.txt198
-rw-r--r--src/cmd/go/testdata/script/mod_install_versioned.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_internal.txt14
-rw-r--r--src/cmd/go/testdata/script/mod_invalid_version.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_issue35317.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_lazy_downgrade.txt145
-rw-r--r--src/cmd/go/testdata/script/mod_list.txt8
-rw-r--r--src/cmd/go/testdata/script/mod_list_bad_import.txt20
-rw-r--r--src/cmd/go/testdata/script/mod_list_dir.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_list_direct.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_list_replace_dir.txt12
-rw-r--r--src/cmd/go/testdata/script/mod_list_retract.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_list_std.txt64
-rw-r--r--src/cmd/go/testdata/script/mod_list_upgrade.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_load_badchain.txt22
-rw-r--r--src/cmd/go/testdata/script/mod_load_badmod.txt7
-rw-r--r--src/cmd/go/testdata/script/mod_load_badzip.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_load_replace_mismatch.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_modinfo.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_multirepo.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_notall.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_off.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_off_init.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_outside.txt38
-rw-r--r--src/cmd/go/testdata/script/mod_overlay.txt254
-rw-r--r--src/cmd/go/testdata/script/mod_permissions.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_proxy_list.txt14
-rw-r--r--src/cmd/go/testdata/script/mod_query.txt10
-rw-r--r--src/cmd/go/testdata/script/mod_query_empty.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_query_exclude.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_query_main.txt43
-rw-r--r--src/cmd/go/testdata/script/mod_readonly.txt45
-rw-r--r--src/cmd/go/testdata/script/mod_replace.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_replace_gopkgin.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_replace_import.txt13
-rw-r--r--src/cmd/go/testdata/script/mod_replace_readonly.txt62
-rw-r--r--src/cmd/go/testdata/script/mod_require_exclude.txt8
-rw-r--r--src/cmd/go/testdata/script/mod_retention.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_retract.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_retract_incompatible.txt15
-rw-r--r--src/cmd/go/testdata/script/mod_retract_pseudo_base.txt62
-rw-r--r--src/cmd/go/testdata/script/mod_retract_rationale.txt14
-rw-r--r--src/cmd/go/testdata/script/mod_retract_rename.txt28
-rw-r--r--src/cmd/go/testdata/script/mod_retract_replace.txt16
-rw-r--r--src/cmd/go/testdata/script/mod_std_vendor.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_sum_ambiguous.txt48
-rw-r--r--src/cmd/go/testdata/script/mod_sum_lookup.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_sum_readonly.txt87
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb_file_path.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb_golang.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb_proxy.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_symlink.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_test.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_test_cached.txt7
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_replace.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_upgrade_patch.txt22
-rw-r--r--src/cmd/go/testdata/script/mod_vcs_missing.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_vendor_auto.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_vendor_build.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_verify.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_why.txt17
-rw-r--r--src/cmd/go/testdata/script/modfile_flag.txt6
-rw-r--r--src/cmd/go/testdata/script/run_hello_pkg.txt9
-rw-r--r--src/cmd/go/testdata/script/run_vendor.txt1
-rw-r--r--src/cmd/go/testdata/script/sum_readonly.txt29
-rw-r--r--src/cmd/go/testdata/script/test_benchmark_fatal.txt6
-rw-r--r--src/cmd/go/testdata/script/test_benchmark_labels.txt6
-rw-r--r--src/cmd/go/testdata/script/test_build_failure.txt10
-rw-r--r--src/cmd/go/testdata/script/test_cache_inputs.txt4
-rw-r--r--src/cmd/go/testdata/script/test_cleanup_failnow.txt47
-rw-r--r--src/cmd/go/testdata/script/test_compile_tempfile.txt2
-rw-r--r--src/cmd/go/testdata/script/test_deadline.txt4
-rw-r--r--src/cmd/go/testdata/script/test_empty.txt4
-rw-r--r--src/cmd/go/testdata/script/test_example_goexit.txt6
-rw-r--r--src/cmd/go/testdata/script/test_flag.txt18
-rw-r--r--src/cmd/go/testdata/script/test_generated_main.txt3
-rw-r--r--src/cmd/go/testdata/script/test_import_error_stack.txt11
-rw-r--r--src/cmd/go/testdata/script/test_json.txt18
-rw-r--r--src/cmd/go/testdata/script/test_main_twice.txt6
-rw-r--r--src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt8
-rw-r--r--src/cmd/go/testdata/script/test_no_run_example.txt8
-rw-r--r--src/cmd/go/testdata/script/test_no_tests.txt6
-rw-r--r--src/cmd/go/testdata/script/test_race.txt6
-rw-r--r--src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt6
-rw-r--r--src/cmd/go/testdata/script/test_race_install.txt11
-rw-r--r--src/cmd/go/testdata/script/test_race_install_cgo.txt14
-rw-r--r--src/cmd/go/testdata/script/test_regexps.txt8
-rw-r--r--src/cmd/go/testdata/script/test_relative_import.txt3
-rw-r--r--src/cmd/go/testdata/script/test_relative_import_dash_i.txt3
-rw-r--r--src/cmd/go/testdata/script/test_syntax_error_says_fail.txt11
-rw-r--r--src/cmd/go/testdata/script/test_vendor.txt12
-rw-r--r--src/cmd/go/testdata/script/test_vet.txt16
-rw-r--r--src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt9
-rw-r--r--src/cmd/go/testdata/script/test_xtestonly_works.txt8
-rw-r--r--src/cmd/go/testdata/script/testing_issue40908.txt6
-rw-r--r--src/cmd/go/testdata/script/toolexec.txt85
-rw-r--r--src/cmd/go/testdata/script/vendor_gopath_issue11409.txt1
-rw-r--r--src/cmd/go/testdata/script/vendor_import.txt1
-rw-r--r--src/cmd/go/testdata/script/vendor_import_wrong.txt11
-rw-r--r--src/cmd/go/testdata/script/vendor_issue12156.txt1
-rw-r--r--src/cmd/go/testdata/script/vendor_list_issue11977.txt5
-rw-r--r--src/cmd/go/testdata/script/vendor_resolve.txt1
-rw-r--r--src/cmd/go/testdata/script/vendor_test_issue11864.txt3
-rw-r--r--src/cmd/go/testdata/script/vendor_test_issue14613.txt1
-rw-r--r--src/cmd/go/testdata/script/version.txt7
-rw-r--r--src/cmd/go/testdata/script/version_replace.txt2
-rw-r--r--src/cmd/go/testdata/script/vet.txt18
-rw-r--r--src/cmd/go/testdata/script/vet_flags.txt16
-rw-r--r--src/cmd/gofmt/gofmt.go18
-rw-r--r--src/cmd/gofmt/gofmt_test.go13
-rw-r--r--src/cmd/gofmt/long_test.go18
-rw-r--r--src/cmd/internal/archive/archive_test.go4
-rw-r--r--src/cmd/internal/buildid/buildid.go38
-rw-r--r--src/cmd/internal/buildid/buildid_test.go31
-rw-r--r--src/cmd/internal/buildid/note.go7
-rw-r--r--src/cmd/internal/buildid/rewrite.go71
-rw-r--r--src/cmd/internal/codesign/codesign.go268
-rw-r--r--src/cmd/internal/dwarf/dwarf.go33
-rw-r--r--src/cmd/internal/goobj/funcinfo.go82
-rw-r--r--src/cmd/internal/goobj/objfile.go12
-rw-r--r--src/cmd/internal/moddeps/moddeps_test.go3
-rw-r--r--src/cmd/internal/obj/arm/asm5.go8
-rw-r--r--src/cmd/internal/obj/arm/obj5.go36
-rw-r--r--src/cmd/internal/obj/arm64/a.out.go129
-rw-r--r--src/cmd/internal/obj/arm64/anames.go68
-rw-r--r--src/cmd/internal/obj/arm64/anames7.go11
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go891
-rw-r--r--src/cmd/internal/obj/arm64/doc.go10
-rw-r--r--src/cmd/internal/obj/arm64/obj7.go38
-rw-r--r--src/cmd/internal/obj/dwarf.go34
-rw-r--r--src/cmd/internal/obj/ld.go2
-rw-r--r--src/cmd/internal/obj/link.go164
-rw-r--r--src/cmd/internal/obj/mips/asm0.go10
-rw-r--r--src/cmd/internal/obj/mips/obj0.go42
-rw-r--r--src/cmd/internal/obj/objfile.go220
-rw-r--r--src/cmd/internal/obj/objfile_test.go36
-rw-r--r--src/cmd/internal/obj/pass.go6
-rw-r--r--src/cmd/internal/obj/pcln.go83
-rw-r--r--src/cmd/internal/obj/plist.go36
-rw-r--r--src/cmd/internal/obj/ppc64/a.out.go6
-rw-r--r--src/cmd/internal/obj/ppc64/anames.go6
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go189
-rw-r--r--src/cmd/internal/obj/ppc64/obj9.go36
-rw-r--r--src/cmd/internal/obj/riscv/cpu.go12
-rw-r--r--src/cmd/internal/obj/riscv/obj.go168
-rw-r--r--src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.go83
-rw-r--r--src/cmd/internal/obj/riscv/testdata/testbranch/branch_test.s44
-rw-r--r--src/cmd/internal/obj/s390x/asmz.go16
-rw-r--r--src/cmd/internal/obj/s390x/objz.go34
-rw-r--r--src/cmd/internal/obj/s390x/rotate.go82
-rw-r--r--src/cmd/internal/obj/s390x/rotate_test.go122
-rw-r--r--src/cmd/internal/obj/sizeof_test.go2
-rw-r--r--src/cmd/internal/obj/sym.go11
-rw-r--r--src/cmd/internal/obj/util.go54
-rw-r--r--src/cmd/internal/obj/wasm/wasmobj.go42
-rw-r--r--src/cmd/internal/obj/x86/asm6.go32
-rw-r--r--src/cmd/internal/obj/x86/obj6.go30
-rw-r--r--src/cmd/internal/objabi/flag.go39
-rw-r--r--src/cmd/internal/objabi/flag_test.go26
-rw-r--r--src/cmd/internal/objabi/funcdata.go15
-rw-r--r--src/cmd/internal/objabi/funcid.go6
-rw-r--r--src/cmd/internal/objabi/head.go2
-rw-r--r--src/cmd/internal/objabi/line.go33
-rw-r--r--src/cmd/internal/objabi/path.go22
-rw-r--r--src/cmd/internal/objabi/reloctype.go22
-rw-r--r--src/cmd/internal/objabi/reloctype_string.go70
-rw-r--r--src/cmd/internal/objabi/util.go18
-rw-r--r--src/cmd/internal/objfile/goobj.go20
-rw-r--r--src/cmd/internal/objfile/macho.go2
-rw-r--r--src/cmd/internal/pkgpath/pkgpath.go174
-rw-r--r--src/cmd/internal/pkgpath/pkgpath_test.go141
-rw-r--r--src/cmd/internal/sys/supported.go27
-rw-r--r--src/cmd/internal/sys/supported_test.go18
-rw-r--r--src/cmd/link/dwarf_test.go10
-rw-r--r--src/cmd/link/internal/amd64/asm.go75
-rw-r--r--src/cmd/link/internal/amd64/l.go2
-rw-r--r--src/cmd/link/internal/amd64/obj.go7
-rw-r--r--src/cmd/link/internal/arm/asm.go4
-rw-r--r--src/cmd/link/internal/arm64/asm.go188
-rw-r--r--src/cmd/link/internal/arm64/obj.go2
-rw-r--r--src/cmd/link/internal/ld/ar.go2
-rw-r--r--src/cmd/link/internal/ld/config.go26
-rw-r--r--src/cmd/link/internal/ld/data.go49
-rw-r--r--src/cmd/link/internal/ld/deadcode.go96
-rw-r--r--src/cmd/link/internal/ld/deadcode_test.go2
-rw-r--r--src/cmd/link/internal/ld/dwarf.go111
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go17
-rw-r--r--src/cmd/link/internal/ld/elf.go1144
-rw-r--r--src/cmd/link/internal/ld/elf_test.go3
-rw-r--r--src/cmd/link/internal/ld/go.go63
-rw-r--r--src/cmd/link/internal/ld/go_test.go121
-rw-r--r--src/cmd/link/internal/ld/ld_test.go77
-rw-r--r--src/cmd/link/internal/ld/lib.go80
-rw-r--r--src/cmd/link/internal/ld/link.go1
-rw-r--r--src/cmd/link/internal/ld/macho.go564
-rw-r--r--src/cmd/link/internal/ld/main.go18
-rw-r--r--src/cmd/link/internal/ld/outbuf.go23
-rw-r--r--src/cmd/link/internal/ld/outbuf_darwin.go9
-rw-r--r--src/cmd/link/internal/ld/outbuf_mmap.go2
-rw-r--r--src/cmd/link/internal/ld/outbuf_nofallocate.go4
-rw-r--r--src/cmd/link/internal/ld/outbuf_notdarwin.go9
-rw-r--r--src/cmd/link/internal/ld/outbuf_test.go2
-rw-r--r--src/cmd/link/internal/ld/outbuf_windows.go5
-rw-r--r--src/cmd/link/internal/ld/pcln.go939
-rw-r--r--src/cmd/link/internal/ld/symtab.go97
-rw-r--r--src/cmd/link/internal/ld/target.go6
-rw-r--r--src/cmd/link/internal/ld/testdata/deadcode/ifacemethod.go9
-rw-r--r--src/cmd/link/internal/ld/testdata/deadcode/ifacemethod3.go29
-rw-r--r--src/cmd/link/internal/ld/testdata/deadcode/ifacemethod4.go23
-rw-r--r--src/cmd/link/internal/ld/testdata/issue39256/x.go2
-rw-r--r--src/cmd/link/internal/loadelf/ldelf.go48
-rw-r--r--src/cmd/link/internal/loader/loader.go161
-rw-r--r--src/cmd/link/internal/loader/symbolbuilder.go27
-rw-r--r--src/cmd/link/internal/loadmacho/ldmacho.go69
-rw-r--r--src/cmd/link/internal/mips64/obj.go5
-rw-r--r--src/cmd/link/internal/ppc64/asm.go7
-rw-r--r--src/cmd/link/internal/riscv64/asm.go163
-rw-r--r--src/cmd/link/internal/riscv64/obj.go3
-rw-r--r--src/cmd/link/internal/s390x/asm.go2
-rw-r--r--src/cmd/link/internal/sym/symbol.go4
-rw-r--r--src/cmd/link/internal/wasm/asm.go3
-rw-r--r--src/cmd/link/internal/x86/asm.go4
-rw-r--r--src/cmd/link/link_test.go133
-rw-r--r--src/cmd/link/testdata/testRO/x.go22
-rw-r--r--src/cmd/nm/nm_cgo_test.go2
-rw-r--r--src/cmd/nm/nm_test.go14
-rw-r--r--src/cmd/objdump/objdump_test.go97
-rw-r--r--src/cmd/objdump/testdata/testfilenum/a.go7
-rw-r--r--src/cmd/objdump/testdata/testfilenum/b.go7
-rw-r--r--src/cmd/objdump/testdata/testfilenum/c.go7
-rw-r--r--src/cmd/objdump/testdata/testfilenum/go.mod3
-rw-r--r--src/cmd/pack/pack.go3
-rw-r--r--src/cmd/pack/pack_test.go24
-rw-r--r--src/cmd/pprof/pprof.go9
-rw-r--r--src/cmd/trace/annotations_test.go4
-rw-r--r--src/cmd/trace/pprof.go3
-rw-r--r--src/cmd/trace/trace_test.go10
-rw-r--r--src/cmd/trace/trace_unix_test.go4
-rw-r--r--src/cmd/vendor/github.com/google/pprof/driver/driver.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go132
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm.go14
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go129
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go281
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/config.go367
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go110
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go24
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go7
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go177
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go157
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/tempfile.go18
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go238
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go143
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go25
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go17
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/report/report.go11
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/report/source.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/profile.go10
-rw-r--r--src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go378
-rw-r--r--src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go501
-rw-r--r--src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go5
-rw-r--r--src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go38
-rw-r--r--src/cmd/vendor/golang.org/x/mod/semver/semver.go3
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_386.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_386.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_386.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_arm64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_linux_s390x.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_386.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_386.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s29
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/endian_big.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/endian_little.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/fcntl_darwin.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/gccgo.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/gccgo_c.c6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ioctl.go9
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/mkall.sh15
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh26
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall.go43
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go16
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go36
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go142
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go9
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go22
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go9
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go22
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go11
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go19
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go11
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go24
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_dragonfly.go32
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go19
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go41
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go233
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go3
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go5
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go13
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_netbsd.go19
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd.go19
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go35
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go7
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go138
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go306
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go5
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go4
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go6
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go7
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go7
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go7
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go7
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go1862
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go22
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go1811
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go299
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s18
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go1811
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go299
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s18
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go1784
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go270
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s14
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go284
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s16
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go42
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go29
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go77
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go (renamed from src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_11.go)514
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go3
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go279
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go1
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go255
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go2
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go220
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go33
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go44
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go40
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go44
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go46
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go12
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go1534
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go20
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go23
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go565
-rw-r--r--src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go31
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/dll_windows.go32
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/env_windows.go11
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/memory_windows.go25
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/security_windows.go34
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/service.go8
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/setupapierrors_windows.go100
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/syscall.go46
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go76
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/types_windows.go60
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/types_windows_386.go13
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/types_windows_amd64.go12
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/types_windows_arm.go13
-rw-r--r--src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go4397
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go13
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go21
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go13
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go22
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go91
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go4
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go100
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go154
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go7
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go122
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go2
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go2
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/validate.go33
-rw-r--r--src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go343
-rw-r--r--src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go168
-rw-r--r--src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go398
-rw-r--r--src/cmd/vendor/modules.txt21
-rw-r--r--src/cmd/vet/main.go4
-rw-r--r--src/cmd/vet/vet_test.go5
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(&regsSymTmp, 0, uint32(len(lv.regMaps))) // number of bitmaps
- roff = duint32(&regsSymTmp, 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(&regsSymTmp, 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(&regsSymTmp)
- }
- // 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 = &paramType{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 = &paramType{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&LTO != 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)
}