aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Findley <rfindley@google.com>2020-09-11 14:23:34 -0400
committerRob Findley <rfindley@google.com>2020-09-11 14:23:34 -0400
commitf8b1c17aced24a1618c6984794be9770c5d260be (patch)
tree45af8d39b5c3d9f43d439ebec0a2ba42b49efe70
parente5d91ab096a9ff9673311f1a7f3f860a7f9c2062 (diff)
parent07c1788357cfe6a4ee5f6f6a54d4fe9f579fa844 (diff)
downloadgo-dev.types.tar.gz
go-dev.types.zip
[dev.types] all: merge master into dev.typesdev.types
Change-Id: Ia6964cb4e09153c15cc9c5b441373d1b3cb8f757
-rw-r--r--api/next.txt14
-rw-r--r--doc/asm.html7
-rw-r--r--doc/go1.14.html6
-rw-r--r--doc/go1.16.html77
-rw-r--r--doc/install-source.html3
-rw-r--r--misc/cgo/test/test.go1
-rw-r--r--misc/wasm/wasm_exec.js4
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64.s63
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64enc.s4
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64error.s14
-rw-r--r--src/cmd/cgo/doc.go7
-rw-r--r--src/cmd/cgo/gcc.go28
-rw-r--r--src/cmd/compile/internal/amd64/ssa.go4
-rw-r--r--src/cmd/compile/internal/arm64/ssa.go2
-rw-r--r--src/cmd/compile/internal/gc/alg.go34
-rw-r--r--src/cmd/compile/internal/gc/closure.go14
-rw-r--r--src/cmd/compile/internal/gc/dcl.go26
-rw-r--r--src/cmd/compile/internal/gc/esc.go6
-rw-r--r--src/cmd/compile/internal/gc/escape.go9
-rw-r--r--src/cmd/compile/internal/gc/fmt.go3
-rw-r--r--src/cmd/compile/internal/gc/gsubr.go2
-rw-r--r--src/cmd/compile/internal/gc/init.go1
-rw-r--r--src/cmd/compile/internal/gc/noder.go15
-rw-r--r--src/cmd/compile/internal/gc/order.go1
-rw-r--r--src/cmd/compile/internal/gc/pgen.go4
-rw-r--r--src/cmd/compile/internal/gc/pgen_test.go10
-rw-r--r--src/cmd/compile/internal/gc/plive.go14
-rw-r--r--src/cmd/compile/internal/gc/range.go2
-rw-r--r--src/cmd/compile/internal/gc/select.go4
-rw-r--r--src/cmd/compile/internal/gc/ssa.go9
-rw-r--r--src/cmd/compile/internal/gc/subr.go15
-rw-r--r--src/cmd/compile/internal/gc/syntax.go41
-rw-r--r--src/cmd/compile/internal/gc/walk.go88
-rw-r--r--src/cmd/compile/internal/ppc64/ssa.go27
-rw-r--r--src/cmd/compile/internal/s390x/ssa.go4
-rw-r--r--src/cmd/compile/internal/ssa/addressingmodes.go65
-rw-r--r--src/cmd/compile/internal/ssa/check.go6
-rw-r--r--src/cmd/compile/internal/ssa/decompose.go10
-rw-r--r--src/cmd/compile/internal/ssa/func.go59
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64.rules835
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64.rules162
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64Ops.go4
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64.rules40
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64Ops.go13
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390X.rules885
-rw-r--r--src/cmd/compile/internal/ssa/gen/dec.rules4
-rw-r--r--src/cmd/compile/internal/ssa/gen/rulegen.go7
-rw-r--r--src/cmd/compile/internal/ssa/lower.go2
-rw-r--r--src/cmd/compile/internal/ssa/nilcheck.go2
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go51
-rw-r--r--src/cmd/compile/internal/ssa/opt.go2
-rw-r--r--src/cmd/compile/internal/ssa/regalloc.go2
-rw-r--r--src/cmd/compile/internal/ssa/rewrite.go37
-rw-r--r--src/cmd/compile/internal/ssa/rewriteAMD64.go4225
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM64.go332
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go603
-rw-r--r--src/cmd/compile/internal/ssa/rewriteS390X.go6164
-rw-r--r--src/cmd/compile/internal/ssa/rewritedec.go7
-rw-r--r--src/cmd/compile/internal/ssa/softfloat.go3
-rw-r--r--src/cmd/compile/internal/ssa/value.go31
-rw-r--r--src/cmd/compile/internal/ssa/writebarrier.go2
-rw-r--r--src/cmd/compile/internal/types/type.go29
-rw-r--r--src/cmd/compile/internal/x86/ssa.go4
-rw-r--r--src/cmd/dist/test.go5
-rw-r--r--src/cmd/fix/fix.go292
-rw-r--r--src/cmd/go.mod4
-rw-r--r--src/cmd/go.sum20
-rw-r--r--src/cmd/go/alldocs.go46
-rw-r--r--src/cmd/go/internal/base/flag.go35
-rw-r--r--src/cmd/go/internal/cfg/cfg.go5
-rw-r--r--src/cmd/go/internal/fmtcmd/fmt.go3
-rw-r--r--src/cmd/go/internal/get/get.go57
-rw-r--r--src/cmd/go/internal/get/path.go192
-rw-r--r--src/cmd/go/internal/list/list.go123
-rw-r--r--src/cmd/go/internal/load/test.go2
-rw-r--r--src/cmd/go/internal/modcmd/download.go11
-rw-r--r--src/cmd/go/internal/modcmd/edit.go104
-rw-r--r--src/cmd/go/internal/modcmd/graph.go5
-rw-r--r--src/cmd/go/internal/modcmd/init.go3
-rw-r--r--src/cmd/go/internal/modcmd/tidy.go15
-rw-r--r--src/cmd/go/internal/modcmd/vendor.go5
-rw-r--r--src/cmd/go/internal/modcmd/verify.go5
-rw-r--r--src/cmd/go/internal/modcmd/why.go8
-rw-r--r--src/cmd/go/internal/modfetch/fetch.go14
-rw-r--r--src/cmd/go/internal/modfetch/insecure.go3
-rw-r--r--src/cmd/go/internal/modfetch/repo.go12
-rw-r--r--src/cmd/go/internal/modfetch/sumdb.go3
-rw-r--r--src/cmd/go/internal/modget/get.go250
-rw-r--r--src/cmd/go/internal/modget/mvs.go202
-rw-r--r--src/cmd/go/internal/modinfo/info.go17
-rw-r--r--src/cmd/go/internal/modload/build.go78
-rw-r--r--src/cmd/go/internal/modload/buildlist.go122
-rw-r--r--src/cmd/go/internal/modload/help.go8
-rw-r--r--src/cmd/go/internal/modload/import.go134
-rw-r--r--src/cmd/go/internal/modload/import_test.go44
-rw-r--r--src/cmd/go/internal/modload/init.go161
-rw-r--r--src/cmd/go/internal/modload/list.go33
-rw-r--r--src/cmd/go/internal/modload/load.go881
-rw-r--r--src/cmd/go/internal/modload/modfile.go384
-rw-r--r--src/cmd/go/internal/modload/mvs.go142
-rw-r--r--src/cmd/go/internal/modload/query.go111
-rw-r--r--src/cmd/go/internal/modload/query_test.go8
-rw-r--r--src/cmd/go/internal/modload/vendor.go4
-rw-r--r--src/cmd/go/internal/mvs/errors.go101
-rw-r--r--src/cmd/go/internal/mvs/mvs.go82
-rw-r--r--src/cmd/go/internal/par/queue.go88
-rw-r--r--src/cmd/go/internal/par/queue_test.go79
-rw-r--r--src/cmd/go/internal/str/str_test.go27
-rw-r--r--src/cmd/go/internal/test/flagdefs_test.go11
-rw-r--r--src/cmd/go/internal/test/genflags.go7
-rw-r--r--src/cmd/go/internal/test/test.go3
-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)279
-rw-r--r--src/cmd/go/internal/vcs/vcs_test.go (renamed from src/cmd/go/internal/get/vcs_test.go)53
-rw-r--r--src/cmd/go/internal/work/build.go14
-rw-r--r--src/cmd/go/internal/work/gc.go9
-rw-r--r--src/cmd/go/internal/work/init.go2
-rw-r--r--src/cmd/go/internal/work/security.go1
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt4
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt6
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt6
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt8
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt8
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt8
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt8
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt6
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt8
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt6
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt48
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt14
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt16
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt19
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt16
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt14
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt14
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt18
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab20
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt14
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt16
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt10
-rw-r--r--src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt13
-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/script/get_insecure_env.txt29
-rw-r--r--src/cmd/go/testdata/script/get_unicode.txt40
-rw-r--r--src/cmd/go/testdata/script/list_bad_import.txt18
-rw-r--r--src/cmd/go/testdata/script/list_test_err.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_all.txt444
-rw-r--r--src/cmd/go/testdata/script/mod_auth.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_bad_filenames.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_build_info_err.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_case.txt7
-rw-r--r--src/cmd/go/testdata/script/mod_concurrent.txt1
-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_download.txt84
-rw-r--r--src/cmd/go/testdata/script/mod_download_json.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_download_partial.txt9
-rw-r--r--src/cmd/go/testdata/script/mod_edit.txt114
-rw-r--r--src/cmd/go/testdata/script/mod_find.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_get_incompatible.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_indirect.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_latest_pseudo.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_get_retract.txt49
-rw-r--r--src/cmd/go/testdata/script/mod_get_sum_noroot.txt11
-rw-r--r--src/cmd/go/testdata/script/mod_get_trailing_slash.txt3
-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_in_testdata_dir.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_init_dep.txt21
-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_path.txt40
-rw-r--r--src/cmd/go/testdata/script/mod_invalid_version.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_lazy_import_allmod.txt172
-rw-r--r--src/cmd/go/testdata/script/mod_lazy_new_import.txt107
-rw-r--r--src/cmd/go/testdata/script/mod_lazy_test_horizon.txt131
-rw-r--r--src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt145
-rw-r--r--src/cmd/go/testdata/script/mod_list.txt8
-rw-r--r--src/cmd/go/testdata/script/mod_list_bad_import.txt18
-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_pseudo.txt21
-rw-r--r--src/cmd/go/testdata/script/mod_list_replace_dir.txt12
-rw-r--r--src/cmd/go/testdata/script/mod_list_retract.txt108
-rw-r--r--src/cmd/go/testdata/script/mod_list_std.txt64
-rw-r--r--src/cmd/go/testdata/script/mod_list_test.txt14
-rw-r--r--src/cmd/go/testdata/script/mod_list_upgrade.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_load_badchain.txt4
-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.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_multirepo.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_notall.txt99
-rw-r--r--src/cmd/go/testdata/script/mod_permissions.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_query.txt10
-rw-r--r--src/cmd/go/testdata/script/mod_query_exclude.txt40
-rw-r--r--src/cmd/go/testdata/script/mod_replace.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_replace_gopkgin.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_replace_import.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_require_exclude.txt62
-rw-r--r--src/cmd/go/testdata/script/mod_retention.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_retract.txt43
-rw-r--r--src/cmd/go/testdata/script/mod_retract_rationale.txt79
-rw-r--r--src/cmd/go/testdata/script/mod_retract_replace.txt61
-rw-r--r--src/cmd/go/testdata/script/mod_std_vendor.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_sum_lookup.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb.txt6
-rw-r--r--src/cmd/go/testdata/script/mod_sumdb_golang.txt12
-rw-r--r--src/cmd/go/testdata/script/mod_symlink.txt5
-rw-r--r--src/cmd/go/testdata/script/mod_symlink_dotgo.txt17
-rw-r--r--src/cmd/go/testdata/script/mod_test.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_tidy_replace.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_upgrade_patch.txt1
-rw-r--r--src/cmd/go/testdata/script/mod_vcs_missing.txt4
-rw-r--r--src/cmd/go/testdata/script/mod_vendor_build.txt3
-rw-r--r--src/cmd/go/testdata/script/mod_verify.txt2
-rw-r--r--src/cmd/go/testdata/script/mod_why.txt3
-rw-r--r--src/cmd/go/testdata/script/modfile_flag.txt6
-rw-r--r--src/cmd/go/testdata/script/test_example_goexit.txt25
-rw-r--r--src/cmd/go/testdata/script/test_exit.txt114
-rw-r--r--src/cmd/go/testdata/script/testing_issue40908.txt21
-rw-r--r--src/cmd/go/testdata/script/version.txt1
-rw-r--r--src/cmd/go/testdata/script/version_replace.txt2
-rw-r--r--src/cmd/internal/goobj/objfile.go14
-rw-r--r--src/cmd/internal/obj/arm/asm5.go16
-rw-r--r--src/cmd/internal/obj/arm/obj5.go10
-rw-r--r--src/cmd/internal/obj/arm64/a.out.go11
-rw-r--r--src/cmd/internal/obj/arm64/anames.go11
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go179
-rw-r--r--src/cmd/internal/obj/arm64/obj7.go26
-rw-r--r--src/cmd/internal/obj/link.go24
-rw-r--r--src/cmd/internal/obj/mips/asm0.go24
-rw-r--r--src/cmd/internal/obj/mips/obj0.go14
-rw-r--r--src/cmd/internal/obj/pass.go17
-rw-r--r--src/cmd/internal/obj/ppc64/asm9.go18
-rw-r--r--src/cmd/internal/obj/ppc64/obj9.go12
-rw-r--r--src/cmd/internal/obj/riscv/obj.go29
-rw-r--r--src/cmd/internal/obj/s390x/asmz.go18
-rw-r--r--src/cmd/internal/obj/s390x/objz.go10
-rw-r--r--src/cmd/internal/obj/sym.go1
-rw-r--r--src/cmd/internal/obj/util.go6
-rw-r--r--src/cmd/internal/obj/x86/asm6.go18
-rw-r--r--src/cmd/internal/obj/x86/obj6.go14
-rw-r--r--src/cmd/internal/objabi/doc.go122
-rw-r--r--src/cmd/internal/objabi/funcdata.go2
-rw-r--r--src/cmd/internal/objabi/util.go14
-rw-r--r--src/cmd/internal/objfile/macho.go2
-rw-r--r--src/cmd/link/internal/arm64/obj.go2
-rw-r--r--src/cmd/link/internal/ld/data.go24
-rw-r--r--src/cmd/link/internal/ld/deadcode.go2
-rw-r--r--src/cmd/link/internal/ld/lib.go44
-rw-r--r--src/cmd/link/internal/ld/macho.go41
-rw-r--r--src/cmd/link/internal/ld/macho_combine_dwarf.go112
-rw-r--r--src/cmd/link/internal/ld/symtab.go4
-rw-r--r--src/cmd/link/internal/ld/target.go6
-rw-r--r--src/cmd/link/internal/loader/loader.go36
-rw-r--r--src/cmd/link/internal/sym/symkind.go2
-rw-r--r--src/cmd/link/internal/sym/symkind_string.go24
-rw-r--r--src/cmd/link/link_test.go22
-rw-r--r--src/cmd/link/testdata/testRO/x.go22
-rw-r--r--src/cmd/vendor/golang.org/x/mod/modfile/read.go8
-rw-r--r--src/cmd/vendor/golang.org/x/mod/modfile/rule.go243
-rw-r--r--src/cmd/vendor/golang.org/x/mod/module/module.go33
-rw-r--r--src/cmd/vendor/golang.org/x/mod/zip/zip.go621
-rw-r--r--src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go6
-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/unusedresult/unusedresult.go2
-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.txt5
-rw-r--r--src/crypto/x509/x509.go1
-rw-r--r--src/database/sql/sql.go7
-rw-r--r--src/debug/elf/file.go77
-rw-r--r--src/debug/elf/file_test.go623
-rw-r--r--src/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64bin0 -> 5696 bytes
-rw-r--r--src/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64bin0 -> 7680 bytes
-rw-r--r--src/debug/elf/testdata/multiple-code-sections.c28
-rw-r--r--src/encoding/binary/varint.go4
-rw-r--r--src/go.mod2
-rw-r--r--src/go.sum4
-rw-r--r--src/go/ast/ast.go6
-rw-r--r--src/go/build/build.go6
-rw-r--r--src/go/types/api_test.go9
-rw-r--r--src/go/types/assignments.go17
-rw-r--r--src/go/types/check_test.go32
-rw-r--r--src/go/types/errors.go39
-rw-r--r--src/go/types/expr.go153
-rw-r--r--src/go/types/fixedbugs/issue23203a.src (renamed from src/go/types/testdata/issue23203a.src)0
-rw-r--r--src/go/types/fixedbugs/issue23203b.src (renamed from src/go/types/testdata/issue23203b.src)0
-rw-r--r--src/go/types/fixedbugs/issue26390.src (renamed from src/go/types/testdata/issue26390.src)2
-rw-r--r--src/go/types/fixedbugs/issue28251.src (renamed from src/go/types/testdata/issue28251.src)0
-rw-r--r--src/go/types/fixedbugs/issue6977.src (renamed from src/go/types/testdata/issue6977.src)0
-rw-r--r--src/go/types/operand.go43
-rw-r--r--src/go/types/self_test.go25
-rw-r--r--src/go/types/stdlib_test.go51
-rw-r--r--src/go/types/testdata/shifts.src23
-rw-r--r--src/html/template/escape.go2
-rw-r--r--src/html/template/template_test.go16
-rw-r--r--src/image/gif/writer_test.go34
-rw-r--r--src/internal/testlog/exit.go33
-rwxr-xr-xsrc/make.bash10
-rw-r--r--src/math/big/arith_arm64.s113
-rw-r--r--src/math/big/arith_test.go106
-rw-r--r--src/math/big/example_test.go7
-rw-r--r--src/math/big/float.go7
-rw-r--r--src/mime/example_test.go26
-rw-r--r--src/net/error_test.go17
-rw-r--r--src/net/http/cgi/child.go3
-rw-r--r--src/net/http/cgi/integration_test.go21
-rw-r--r--src/net/http/export_test.go11
-rw-r--r--src/net/http/fcgi/child.go3
-rw-r--r--src/net/http/fs.go10
-rw-r--r--src/net/http/fs_test.go70
-rw-r--r--src/net/http/h2_bundle.go85
-rw-r--r--src/net/http/omithttp2.go4
-rw-r--r--src/net/http/serve_test.go70
-rw-r--r--src/net/http/server.go110
-rw-r--r--src/net/http/transport.go18
-rw-r--r--src/net/http/transport_test.go99
-rw-r--r--src/net/mail/message.go13
-rw-r--r--src/net/mail/message_test.go32
-rw-r--r--src/net/net.go12
-rw-r--r--src/net/smtp/smtp.go6
-rw-r--r--src/net/smtp/smtp_test.go213
-rw-r--r--src/os/dir_darwin.go10
-rw-r--r--src/os/dir_unix.go2
-rw-r--r--src/os/os_test.go4
-rw-r--r--src/os/proc.go8
-rw-r--r--src/runtime/cgocall.go9
-rw-r--r--src/runtime/debug.go5
-rw-r--r--src/runtime/debugcall.go2
-rw-r--r--src/runtime/defs_linux_arm.go4
-rw-r--r--src/runtime/defs_linux_mips64x.go4
-rw-r--r--src/runtime/defs_openbsd_arm64.go4
-rw-r--r--src/runtime/defs_plan9_386.go4
-rw-r--r--src/runtime/defs_plan9_amd64.go4
-rw-r--r--src/runtime/export_test.go24
-rw-r--r--src/runtime/lockrank.go2
-rw-r--r--src/runtime/lockrank_off.go10
-rw-r--r--src/runtime/map.go9
-rw-r--r--src/runtime/map_fast32.go5
-rw-r--r--src/runtime/map_fast64.go5
-rw-r--r--src/runtime/map_faststr.go5
-rw-r--r--src/runtime/mgcmark.go3
-rw-r--r--src/runtime/mgcstack.go2
-rw-r--r--src/runtime/mkduff.go1
-rw-r--r--src/runtime/mpagealloc.go13
-rw-r--r--src/runtime/os_linux.go15
-rw-r--r--src/runtime/preempt.go2
-rw-r--r--src/runtime/proc.go10
-rw-r--r--src/runtime/rt0_linux_ppc64.s4
-rw-r--r--src/runtime/rt0_linux_ppc64le.s4
-rw-r--r--src/runtime/runtime2.go13
-rw-r--r--src/runtime/select.go1
-rw-r--r--src/runtime/stack.go8
-rw-r--r--src/runtime/symtab.go3
-rw-r--r--src/runtime/trace/annotation.go4
-rw-r--r--src/runtime/trace/annotation_test.go4
-rw-r--r--src/runtime/traceback.go6
-rw-r--r--src/sync/map.go1
-rw-r--r--src/sync/map_test.go24
-rw-r--r--src/testing/benchmark.go18
-rw-r--r--src/testing/example.go11
-rw-r--r--src/testing/internal/testdeps/deps.go5
-rw-r--r--src/testing/run_example.go4
-rw-r--r--src/testing/run_example_js.go4
-rw-r--r--src/testing/sub_test.go46
-rw-r--r--src/testing/testing.go252
-rw-r--r--src/testing/testing_test.go32
-rw-r--r--src/text/template/exec.go1
-rw-r--r--src/text/template/parse/lex.go8
-rw-r--r--src/text/template/parse/lex_test.go7
-rw-r--r--src/text/template/parse/node.go33
-rw-r--r--src/text/template/parse/parse.go22
-rw-r--r--src/text/template/parse/parse_test.go25
-rw-r--r--src/unicode/utf8/utf8_test.go30
-rw-r--r--src/vendor/modules.txt2
-rw-r--r--test/README.md4
-rw-r--r--test/codegen/arithmetic.go42
-rw-r--r--test/codegen/mathbits.go14
-rw-r--r--test/codegen/select.go20
-rw-r--r--test/codegen/slices.go21
-rw-r--r--test/fixedbugs/bug229.go8
-rw-r--r--test/fixedbugs/issue22921.go18
-rw-r--r--test/fixedbugs/issue24491.go45
-rw-r--r--test/fixedbugs/issue38125.go22
-rw-r--r--test/fixedbugs/issue39505.go31
-rw-r--r--test/fixedbugs/issue39505b.go183
-rw-r--r--test/fixedbugs/issue41247.go11
-rw-r--r--test/fixedbugs/issue8606b.go63
-rw-r--r--test/notinheap2.go12
-rw-r--r--test/runtime.go2
401 files changed, 15484 insertions, 12121 deletions
diff --git a/api/next.txt b/api/next.txt
index fe7509bf82..076f39ec34 100644
--- a/api/next.txt
+++ b/api/next.txt
@@ -3,3 +3,17 @@ pkg unicode, var Chorasmian *RangeTable
pkg unicode, var Dives_Akuru *RangeTable
pkg unicode, var Khitan_Small_Script *RangeTable
pkg unicode, var Yezidi *RangeTable
+pkg text/template/parse, const NodeComment = 20
+pkg text/template/parse, const NodeComment NodeType
+pkg text/template/parse, const ParseComments = 1
+pkg text/template/parse, const ParseComments Mode
+pkg text/template/parse, method (*CommentNode) Copy() Node
+pkg text/template/parse, method (*CommentNode) String() string
+pkg text/template/parse, method (CommentNode) Position() Pos
+pkg text/template/parse, method (CommentNode) Type() NodeType
+pkg text/template/parse, type CommentNode struct
+pkg text/template/parse, type CommentNode struct, Text string
+pkg text/template/parse, type CommentNode struct, embedded NodeType
+pkg text/template/parse, type CommentNode struct, embedded Pos
+pkg text/template/parse, type Mode uint
+pkg text/template/parse, type Tree struct, Mode Mode
diff --git a/doc/asm.html b/doc/asm.html
index dbbe8f2cd1..cc8598aeff 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -687,6 +687,13 @@ MOVQ g(CX), AX // Move g into AX.
MOVQ g_m(AX), BX // Move g.m into BX.
</pre>
+<p>
+Register <code>BP</code> is callee-save.
+The assembler automatically inserts <code>BP</code> save/restore when frame size is larger than zero.
+Using <code>BP</code> as a general purpose register is allowed,
+however it can interfere with sampling-based profiling.
+</p>
+
<h3 id="arm">ARM</h3>
<p>
diff --git a/doc/go1.14.html b/doc/go1.14.html
index 35a9f3c2f3..410e0cbf7c 100644
--- a/doc/go1.14.html
+++ b/doc/go1.14.html
@@ -609,6 +609,12 @@ Do not send CLs removing the interior tags from such phrases.
If a program needs to accept invalid numbers like the empty string,
consider wrapping the type with <a href="/pkg/encoding/json/#Unmarshaler"><code>Unmarshaler</code></a>.
</p>
+
+ <p><!-- CL 200237 -->
+ <a href="/pkg/encoding/json/#Unmarshal"><code>Unmarshal</code></a>
+ can now support map keys with string underlying type which implement
+ <a href="/pkg/encoding/#TextUnmarshaler"><code>encoding.TextUnmarshaler</code></a>.
+ </p>
</dd>
</dl><!-- encoding/json -->
diff --git a/doc/go1.16.html b/doc/go1.16.html
index 4753cf914d..95e63d0d5a 100644
--- a/doc/go1.16.html
+++ b/doc/go1.16.html
@@ -43,6 +43,37 @@ Do not send CLs removing the interior tags from such phrases.
<h3 id="go-command">Go command</h3>
+<p><!-- golang.org/issue/24031 -->
+ <code>retract</code> directives may now be used in a <code>go.mod</code> file
+ to indicate that certain published versions of the module should not be used
+ by other modules. A module author may retract a version after a severe problem
+ is discovered or if the version was published unintentionally.<br>
+ TODO: write and link to section in golang.org/ref/mod<br>
+ TODO: write and link to tutorial or blog post
+</p>
+
+<p><!-- golang.org/issue/29062 -->
+ When using <code>go test</code>, a test that
+ calls <code>os.Exit(0)</code> during execution of a test function
+ will now be considered to fail.
+ This will help catch cases in which a test calls code that calls
+ os.Exit(0) and thereby stops running all future tests.
+ If a <code>TestMain</code> function calls <code>os.Exit(0)</code>
+ that is still considered to be a passing test.
+</p>
+
+<h4 id="all-pattern">The <code>all</code> pattern</h4>
+
+<p><!-- golang.org/cl/240623 -->
+ When the main module's <code>go.mod</code> file
+ declares <code>go</code> <code>1.16</code> or higher, the <code>all</code>
+ package pattern now matches only those packages that are transitively imported
+ by a package or test found in the main module. (Packages imported by <em>tests
+ of</em> packages imported by the main module are no longer included.) This is
+ the same set of packages retained
+ by <code>go</code> <code>mod</code> <code>vendor</code> since Go 1.11.
+</p>
+
<p>
TODO
</p>
@@ -90,6 +121,28 @@ Do not send CLs removing the interior tags from such phrases.
TODO
</p>
+<h3 id="net"><a href="/pkg/net/">net</a></h3>
+
+<p><!-- CL 250357 -->
+ The case of I/O on a closed network connection, or I/O on a network
+ connection that is closed before any of the I/O completes, can now
+ be detected using the new <a href="/pkg/net/#ErrClosed">ErrClosed</a> error.
+ A typical use would be <code>errors.Is(err, net.ErrClosed)</code>.
+ In earlier releases the only way to reliably detect this case was to
+ match the string returned by the <code>Error</code> method
+ with <code>"use of closed network connection"</code>.
+</p>
+
+
+<h3 id="text/template/parse"><a href="/pkg/text/template/parse/">text/template/parse</a></h3>
+
+<p><!-- CL 229398, golang.org/issue/34652 -->
+ A new <a href="/pkg/text/template/parse/#CommentNode"><code>CommentNode</code></a>
+ was added to the parse tree. The <a href="/pkg/text/template/parse/#Mode"><code>Mode</code></a>
+ field in the <code>parse.Tree</code> enables access to it.
+</p>
+<!-- text/template/parse -->
+
<h3 id="unicode"><a href="/pkg/unicode/">unicode</a></h3>
<p><!-- CL 248765 -->
@@ -112,3 +165,27 @@ Do not send CLs removing the interior tags from such phrases.
<p>
TODO
</p>
+
+<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
+ <dd>
+ <p><!-- CL 233637 -->
+ In the <a href="/pkg/net/http/"><code>net/http</code></a> package, the
+ behavior of <a href="/pkg/net/http/#StripPrefix"><code>StripPrefix</code></a>
+ has been changed to strip the prefix from the request URL's
+ <code>RawPath</code> field in addition to its <code>Path</code> field.
+ In past releases, only the <code>Path</code> field was trimmed, and so if the
+ request URL contained any escaped characters the URL would be modified to
+ have mismatched <code>Path</code> and <code>RawPath</code> fields.
+ In Go 1.16, <code>StripPrefix</code> trims both fields.
+ If there are escaped characters in the prefix part of the request URL the
+ handler serves a 404 instead of its previous behavior of invoking the
+ underlying handler with a mismatched <code>Path</code>/<code>RawPath</code> pair.
+ </p>
+
+ <p><!-- CL 252497 -->
+ The <a href="/pkg/net/http/"><code>net/http</code></a> package now rejects HTTP range requests
+ of the form <code>"Range": "bytes=--N"</code> where <code>"-N"</code> is a negative suffix length, for
+ example <code>"Range": "bytes=--2"</code>. It now replies with a <code>416 "Range Not Satisfiable"</code> response.
+ </p>
+ </dd>
+</dl><!-- net/http -->
diff --git a/doc/install-source.html b/doc/install-source.html
index f8cda1dc21..cbf4eac70b 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -600,6 +600,9 @@ The valid combinations of <code>$GOOS</code> and <code>$GOARCH</code> are:
<td></td><td><code>linux</code></td> <td><code>mips64le</code></td>
</tr>
<tr>
+<td></td><td><code>linux</code></td> <td><code>riscv64</code></td>
+</tr>
+<tr>
<td></td><td><code>linux</code></td> <td><code>s390x</code></td>
</tr>
<tr>
diff --git a/misc/cgo/test/test.go b/misc/cgo/test/test.go
index 35bc3a1447..05fa52b381 100644
--- a/misc/cgo/test/test.go
+++ b/misc/cgo/test/test.go
@@ -319,6 +319,7 @@ typedef enum {
// issue 4339
// We've historically permitted #include <>, so test it here. Issue 29333.
+// Also see issue 41059.
#include <issue4339.h>
// issue 4417
diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js
index 8501ae7cd8..ef97c4e311 100644
--- a/misc/wasm/wasm_exec.js
+++ b/misc/wasm/wasm_exec.js
@@ -11,6 +11,7 @@
// - Node.js
// - Electron
// - Parcel
+ // - Webpack
if (typeof global !== "undefined") {
// global already exists
@@ -28,7 +29,7 @@
if (!global.fs && global.require) {
const fs = require("fs");
- if (Object.keys(fs) !== 0) {
+ if (typeof fs === "object" && fs !== null && Object.keys(fs).length !== 0) {
global.fs = fs;
}
}
@@ -556,6 +557,7 @@
}
if (
+ typeof module !== "undefined" &&
global.require &&
global.require.main === module &&
global.process &&
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 5a6db05074..e106ff2ae1 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -145,6 +145,37 @@ 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
+ 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
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
@@ -186,6 +217,10 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
FMOVS $(0.96875), F3 // 03f02d1e
FMOVD $(28.0), F4 // 0490671e
+// move a large constant to a Vd.
+ FMOVD $0x8040201008040201, V20 // FMOVD $-9205322385119247871, V20
+ FMOVQ $0x8040201008040202, V29 // FMOVQ $-9205322385119247870, V29
+
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
@@ -359,18 +394,22 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
VLD4 (R15), [V10.H4, V11.H4, V12.H4, V13.H4] // ea05400c
VLD4.P 32(R24), [V31.B8, V0.B8, V1.B8, V2.B8] // 1f03df0c
VLD4.P (R13)(R9), [V14.S2, V15.S2, V16.S2, V17.S2] // VLD4.P (R13)(R9*1), [V14.S2,V15.S2,V16.S2,V17.S2] // ae09c90c
- VLD1R (R0), [V0.B16] // 00c0404d
- VLD1R.P 16(R0), [V0.B16] // 00c0df4d
- VLD1R.P (R15)(R1), [V15.H4] // VLD1R.P (R15)(R1*1), [V15.H4] // efc5c10d
- VLD2R (R15), [V15.H4, V16.H4] // efc5600d
- VLD2R.P 32(R0), [V0.D2, V1.D2] // 00ccff4d
- VLD2R.P (R0)(R5), [V31.D1, V0.D1] // VLD2R.P (R0)(R5*1), [V31.D1, V0.D1] // 1fcce50d
- VLD3R (RSP), [V31.S2, V0.S2, V1.S2] // ffeb400d
- VLD3R.P 24(R15), [V15.H4, V16.H4, V17.H4] // efe5df0d
- VLD3R.P (R15)(R6), [V15.H8, V16.H8, V17.H8] // VLD3R.P (R15)(R6*1), [V15.H8, V16.H8, V17.H8] // efe5c64d
- VLD4R (R0), [V0.B8, V1.B8, V2.B8, V3.B8] // 00e0600d
- VLD4R.P 64(RSP), [V31.S4, V0.S4, V1.S4, V2.S4] // ffebff4d
- VLD4R.P (R15)(R9), [V15.H4, V16.H4, V17.H4, V18.H4] // VLD4R.P (R15)(R9*1), [V15.H4, V16.H4, V17.H4, V18.H4] // efe5e90d
+ VLD1R (R1), [V9.B8] // 29c0400d
+ VLD1R.P (R1), [V9.B8] // 29c0df0d
+ VLD1R.P 1(R1), [V2.B8] // 22c0df0d
+ VLD1R.P 2(R1), [V2.H4] // 22c4df0d
+ VLD1R (R0), [V0.B16] // 00c0404d
+ VLD1R.P (R0), [V0.B16] // 00c0df4d
+ VLD1R.P (R15)(R1), [V15.H4] // VLD1R.P (R15)(R1*1), [V15.H4] // efc5c10d
+ VLD2R (R15), [V15.H4, V16.H4] // efc5600d
+ VLD2R.P 16(R0), [V0.D2, V1.D2] // 00ccff4d
+ VLD2R.P (R0)(R5), [V31.D1, V0.D1] // VLD2R.P (R0)(R5*1), [V31.D1, V0.D1] // 1fcce50d
+ VLD3R (RSP), [V31.S2, V0.S2, V1.S2] // ffeb400d
+ VLD3R.P 6(R15), [V15.H4, V16.H4, V17.H4] // efe5df0d
+ VLD3R.P (R15)(R6), [V15.H8, V16.H8, V17.H8] // VLD3R.P (R15)(R6*1), [V15.H8, V16.H8, V17.H8] // efe5c64d
+ VLD4R (R0), [V0.B8, V1.B8, V2.B8, V3.B8] // 00e0600d
+ VLD4R.P 16(RSP), [V31.S4, V0.S4, V1.S4, V2.S4] // ffebff4d
+ VLD4R.P (R15)(R9), [V15.H4, V16.H4, V17.H4, V18.H4] // VLD4R.P (R15)(R9*1), [V15.H4, V16.H4, V17.H4, V18.H4] // efe5e90d
VST1.P [V24.S2], 8(R2) // 58789f0c
VST1 [V29.S2, V30.S2], (R29) // bdab000c
VST1 [V14.H4, V15.H4, V16.H4], (R27) // 6e67000c
diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s
index 56cf51c303..e802ee76f5 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s
@@ -591,7 +591,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
FMOVS R8, F15 // 0f01271e
FMOVD F2, F9 // 4940601e
FMOVS F4, F27 // 9b40201e
- //TODO VFMOV $3.125, V8.2D // 28f5006f
+ //TODO VFMOV $3.125, V8.D2 // 28f5006f
FMSUBS F13, F21, F13, F19 // b3d50d1f
FMSUBD F11, F7, F15, F31 // ff9d4b1f
//TODO VFMUL V9.S[2], F21, F19 // b39a895f
@@ -648,7 +648,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
FSUBS F25, F23, F0 // e03a391e
FSUBD F11, F13, F24 // b8396b1e
//TODO SCVTFSS F30, F20 // d4db215e
- //TODO VSCVTF V7.2S, V17.2S // f1d8210e
+ //TODO VSCVTF V7.S2, V17.S2 // f1d8210e
SCVTFWS R3, F16 // 7000221e
SCVTFWD R20, F4 // 8402621e
SCVTFS R16, F12 // 0c02229e
diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s
index 0661a474b4..20b1f3e9f0 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64error.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64error.s
@@ -339,4 +339,18 @@ TEXT errors(SB),$0
MRS ICV_EOIR1_EL1, R3 // ERROR "system register is not readable"
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"
RET
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index ca18c45d9d..b3f371b08c 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -112,6 +112,13 @@ The default C and C++ compilers may be changed by the CC and CXX
environment variables, respectively; those environment variables
may include command line options.
+The cgo tool will always invoke the C compiler with the source file's
+directory in the include path; i.e. -I${SRCDIR} is always implied. This
+means that if a header file foo/bar.h exists both in the source
+directory and also in the system include directory (or some other place
+specified by a -I flag), then "#include <foo/bar.h>" will always find the
+local version in preference to any other version.
+
The cgo tool is enabled by default for native builds on systems where
it is expected to work. It is disabled by default when
cross-compiling. You can control this by setting the CGO_ENABLED
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index a59534ebd0..9179b5490e 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -369,7 +369,18 @@ func (p *Package) guessKinds(f *File) []*Name {
fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
"int __cgo__1 = __cgo__2;\n")
- stderr := p.gccErrors(b.Bytes())
+ // We need to parse the output from this gcc command, so ensure that it
+ // doesn't have any ANSI escape sequences in it. (TERM=dumb is
+ // insufficient; if the user specifies CGO_CFLAGS=-fdiagnostics-color,
+ // GCC will ignore TERM, and GCC can also be configured at compile-time
+ // to ignore TERM.)
+ stderr := p.gccErrors(b.Bytes(), "-fdiagnostics-color=never")
+ if strings.Contains(stderr, "unrecognized command line option") {
+ // We're using an old version of GCC that doesn't understand
+ // -fdiagnostics-color. Those versions can't print color anyway,
+ // so just rerun without that option.
+ stderr = p.gccErrors(b.Bytes())
+ }
if stderr == "" {
fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
}
@@ -1970,22 +1981,25 @@ func (p *Package) gccDefines(stdin []byte) string {
// gccErrors runs gcc over the C program stdin and returns
// the errors that gcc prints. That is, this function expects
// gcc to fail.
-func (p *Package) gccErrors(stdin []byte) string {
+func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
// TODO(rsc): require failure
args := p.gccCmd()
// Optimization options can confuse the error messages; remove them.
- nargs := make([]string, 0, len(args))
+ nargs := make([]string, 0, len(args)+len(extraArgs))
for _, arg := range args {
if !strings.HasPrefix(arg, "-O") {
nargs = append(nargs, arg)
}
}
- // Force -O0 optimization but keep the trailing "-" at the end.
- nargs = append(nargs, "-O0")
- nl := len(nargs)
- nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
+ // Force -O0 optimization and append extra arguments, but keep the
+ // trailing "-" at the end.
+ li := len(nargs) - 1
+ last := nargs[li]
+ nargs[li] = "-O0"
+ nargs = append(nargs, extraArgs...)
+ nargs = append(nargs, last)
if *debugGcc {
fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go
index 9d8a0920b3..4ac877986c 100644
--- a/src/cmd/compile/internal/amd64/ssa.go
+++ b/src/cmd/compile/internal/amd64/ssa.go
@@ -319,8 +319,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
// TODO(khr): issue only the -1 fixup code we need.
// For instance, if only the quotient is used, no point in zeroing the remainder.
- j1.To.Val = n1
- j2.To.Val = s.Pc()
+ j1.To.SetTarget(n1)
+ j2.To.SetTarget(s.Pc())
}
case ssa.OpAMD64HMULQ, ssa.OpAMD64HMULL, ssa.OpAMD64HMULQU, ssa.OpAMD64HMULLU:
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index b6bb81a847..1d6ea6b9d8 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -816,7 +816,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
}
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
- p.From.Reg = condBits[v.Aux.(ssa.Op)]
+ p.From.Reg = condBits[ssa.Op(v.AuxInt)]
p.Reg = v.Args[0].Reg()
p.SetFrom3(obj.Addr{Type: obj.TYPE_REG, Reg: r1})
p.To.Type = obj.TYPE_REG
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index e2e2374717..c9d71ea00b 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -429,8 +429,7 @@ func hashfor(t *types.Type) *Node {
}
n := newname(sym)
- n.SetClass(PFUNC)
- n.Sym.SetFunc(true)
+ setNodeNameFunc(n)
n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)),
anonfield(types.Types[TUINTPTR]),
@@ -646,17 +645,11 @@ func geneq(t *types.Type) *obj.LSym {
// Build a list of conditions to satisfy.
// The conditions are a list-of-lists. Conditions are reorderable
// within each inner list. The outer lists must be evaluated in order.
- // Even within each inner list, track their order so that we can preserve
- // aspects of that order. (TODO: latter part needed?)
- type nodeIdx struct {
- n *Node
- idx int
- }
- var conds [][]nodeIdx
- conds = append(conds, []nodeIdx{})
+ var conds [][]*Node
+ conds = append(conds, []*Node{})
and := func(n *Node) {
i := len(conds) - 1
- conds[i] = append(conds[i], nodeIdx{n: n, idx: len(conds[i])})
+ conds[i] = append(conds[i], n)
}
// Walk the struct using memequal for runs of AMEM
@@ -674,7 +667,7 @@ func geneq(t *types.Type) *obj.LSym {
if !IsRegularMemory(f.Type) {
if EqCanPanic(f.Type) {
// Enforce ordering by starting a new set of reorderable conditions.
- conds = append(conds, []nodeIdx{})
+ conds = append(conds, []*Node{})
}
p := nodSym(OXDOT, np, f.Sym)
q := nodSym(OXDOT, nq, f.Sym)
@@ -688,7 +681,7 @@ func geneq(t *types.Type) *obj.LSym {
}
if EqCanPanic(f.Type) {
// Also enforce ordering after something that can panic.
- conds = append(conds, []nodeIdx{})
+ conds = append(conds, []*Node{})
}
i++
continue
@@ -713,14 +706,13 @@ func geneq(t *types.Type) *obj.LSym {
// Sort conditions to put runtime calls last.
// Preserve the rest of the ordering.
- var flatConds []nodeIdx
+ var flatConds []*Node
for _, c := range conds {
+ isCall := func(n *Node) bool {
+ return n.Op == OCALL || n.Op == OCALLFUNC
+ }
sort.SliceStable(c, func(i, j int) bool {
- x, y := c[i], c[j]
- if (x.n.Op != OCALL) == (y.n.Op != OCALL) {
- return x.idx < y.idx
- }
- return x.n.Op != OCALL
+ return !isCall(c[i]) && isCall(c[j])
})
flatConds = append(flatConds, c...)
}
@@ -729,9 +721,9 @@ func geneq(t *types.Type) *obj.LSym {
if len(flatConds) == 0 {
cond = nodbool(true)
} else {
- cond = flatConds[0].n
+ cond = flatConds[0]
for _, c := range flatConds[1:] {
- cond = nod(OANDAND, cond, c.n)
+ cond = nod(OANDAND, cond, c)
}
}
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 23e48939b4..250be38e5b 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -107,18 +107,7 @@ func typecheckclosure(clo *Node, top int) {
}
xfunc.Func.Nname.Sym = closurename(Curfn)
- disableExport(xfunc.Func.Nname.Sym)
- if xfunc.Func.Nname.Sym.Def != nil {
- // The only case we can reach here is when the outer function was redeclared.
- // In that case, don't bother to redeclare the closure. Otherwise, we will get
- // a spurious error message, see #17758. While we are here, double check that
- // we already reported other error.
- if nsavederrors+nerrors == 0 {
- Fatalf("unexpected symbol collision %v", xfunc.Func.Nname.Sym)
- }
- } else {
- declare(xfunc.Func.Nname, PFUNC)
- }
+ setNodeNameFunc(xfunc.Func.Nname)
xfunc = typecheck(xfunc, ctxStmt)
// Type check the body now, but only if we're inside a function.
@@ -473,7 +462,6 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
tfn.List.Set(structargs(t0.Params(), true))
tfn.Rlist.Set(structargs(t0.Results(), false))
- disableExport(sym)
xfunc := dclfunc(sym, tfn)
xfunc.Func.SetDupok(true)
xfunc.Func.SetNeedctxt(true)
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
index cd64d9a7bf..69eb13f607 100644
--- a/src/cmd/compile/internal/gc/dcl.go
+++ b/src/cmd/compile/internal/gc/dcl.go
@@ -90,7 +90,7 @@ func declare(n *Node, ctxt Class) {
lineno = n.Pos
Fatalf("automatic outside function")
}
- if Curfn != nil {
+ if Curfn != nil && ctxt != PFUNC {
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
}
if n.Op == OTYPE {
@@ -297,6 +297,16 @@ func oldname(s *types.Sym) *Node {
return n
}
+// importName is like oldname, but it reports an error if sym is from another package and not exported.
+func importName(sym *types.Sym) *Node {
+ n := oldname(sym)
+ if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
+ n.SetDiag(true)
+ yyerror("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
+ }
+ return n
+}
+
// := declarations
func colasname(n *Node) bool {
switch n.Op {
@@ -975,10 +985,14 @@ func makefuncsym(s *types.Sym) {
}
}
-// disableExport prevents sym from being included in package export
-// data. To be effectual, it must be called before declare.
-func disableExport(sym *types.Sym) {
- sym.SetOnExportList(true)
+// setNodeNameFunc marks a node as a function.
+func setNodeNameFunc(n *Node) {
+ if n.Op != ONAME || n.Class() != Pxxx {
+ Fatalf("expected ONAME/Pxxx node, got %v", n)
+ }
+
+ n.SetClass(PFUNC)
+ n.Sym.SetFunc(true)
}
func dclfunc(sym *types.Sym, tfn *Node) *Node {
@@ -990,7 +1004,7 @@ func dclfunc(sym *types.Sym, tfn *Node) *Node {
fn.Func.Nname = newfuncnamel(lineno, sym)
fn.Func.Nname.Name.Defn = fn
fn.Func.Nname.Name.Param.Ntype = tfn
- declare(fn.Func.Nname, PFUNC)
+ setNodeNameFunc(fn.Func.Nname)
funchdr(fn)
fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, ctxType)
return fn
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index 4b843aba35..375331d1f5 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -377,7 +377,7 @@ 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 f.Type.IsUintptr() {
if Debug['m'] != 0 {
Warnl(f.Pos, "assuming %v is unsafe uintptr", name())
}
@@ -407,13 +407,13 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
}
if fn.Func.Pragma&UintptrEscapes != 0 {
- if f.Type.Etype == TUINTPTR {
+ 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 {
Warnl(f.Pos, "marking %v as escaping ...uintptr", name())
diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go
index ddf89f6159..75da439bb7 100644
--- a/src/cmd/compile/internal/gc/escape.go
+++ b/src/cmd/compile/internal/gc/escape.go
@@ -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)
@@ -1029,6 +1029,9 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
if e.curfn == nil {
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)
+ }
n = canonicalNode(n)
loc := &EscLocation{
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index d6cc9fa4cf..866cd0a714 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -1616,7 +1616,8 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
}
n1.exprfmt(s, nprec, mode)
}
-
+ case ODDD:
+ mode.Fprintf(s, "...")
default:
mode.Fprintf(s, "<node %v>", n.Op)
}
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index 15a84a8a43..480d411f49 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -342,6 +342,6 @@ func Patch(p *obj.Prog, to *obj.Prog) {
if p.To.Type != obj.TYPE_BRANCH {
Fatalf("patch: not a branch")
}
- p.To.Val = to
+ p.To.SetTarget(to)
p.To.Offset = to.Pc
}
diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go
index 03e475e85a..94cbcf9846 100644
--- a/src/cmd/compile/internal/gc/init.go
+++ b/src/cmd/compile/internal/gc/init.go
@@ -45,7 +45,6 @@ func fninit(n []*Node) {
if len(nf) > 0 {
lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
initializers := lookup("init")
- disableExport(initializers)
fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
for _, dcl := range dummyInitFn.Func.Dcl {
dcl.Name.Curfn = fn
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index 802aab2268..5dce533e4b 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -653,7 +653,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
obj := p.expr(expr.X)
if obj.Op == OPACK {
obj.Name.SetUsed(true)
- return oldname(restrictlookup(expr.Sel.Value, obj.Name.Pkg))
+ return importName(obj.Name.Pkg.Lookup(expr.Sel.Value))
}
n := nodSym(OXDOT, obj, p.name(expr.Sel))
n.Pos = p.pos(expr) // lineno may have been changed by p.expr(expr.X)
@@ -857,7 +857,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
p.setlineno(method)
var n *Node
if method.Name == nil {
- n = p.nodSym(method, ODCLFIELD, oldname(p.packname(method.Type)), nil)
+ n = p.nodSym(method, ODCLFIELD, importName(p.packname(method.Type)), nil)
} else {
mname := p.name(method.Name)
sig := p.typeExpr(method.Type)
@@ -896,7 +896,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
def.Name.SetUsed(true)
pkg = def.Name.Pkg
}
- return restrictlookup(expr.Sel.Value, pkg)
+ return pkg.Lookup(expr.Sel.Value)
}
panic(fmt.Sprintf("unexpected packname: %#v", expr))
}
@@ -911,7 +911,7 @@ func (p *noder) embedded(typ syntax.Expr) *Node {
}
sym := p.packname(typ)
- n := p.nodSym(typ, ODCLFIELD, oldname(sym), lookup(sym.Name))
+ n := p.nodSym(typ, ODCLFIELD, importName(sym), lookup(sym.Name))
n.SetEmbedded(true)
if isStar {
@@ -1641,10 +1641,3 @@ func mkname(sym *types.Sym) *Node {
}
return n
}
-
-func unparen(x *Node) *Node {
- for x.Op == OPAREN {
- x = x.Left
- }
- return x
-}
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index aa91160e5c..412f073a8d 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -502,6 +502,7 @@ func (o *Order) call(n *Node) {
x := o.copyExpr(arg.Left, arg.Left.Type, false)
x.Name.SetKeepalive(true)
arg.Left = x
+ n.SetNeedsWrapper(true)
}
}
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index ca8cccf4ae..74262595b0 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -507,7 +507,7 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
if Ctxt.FixedFrameSize() == 0 {
offs -= int64(Widthptr)
}
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) || objabi.GOARCH == "arm64" {
+ if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
// There is a word space for FP on ARM64 even if the frame pointer is disabled
offs -= int64(Widthptr)
}
@@ -703,7 +703,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
if Ctxt.FixedFrameSize() == 0 {
base -= int64(Widthptr)
}
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) || objabi.GOARCH == "arm64" {
+ if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
// There is a word space for FP on ARM64 even if the frame pointer is disabled
base -= int64(Widthptr)
}
diff --git a/src/cmd/compile/internal/gc/pgen_test.go b/src/cmd/compile/internal/gc/pgen_test.go
index 41f0808a1c..b1db29825c 100644
--- a/src/cmd/compile/internal/gc/pgen_test.go
+++ b/src/cmd/compile/internal/gc/pgen_test.go
@@ -20,7 +20,7 @@ func typeWithoutPointers() *types.Type {
func typeWithPointers() *types.Type {
t := types.New(TSTRUCT)
- f := &types.Field{Type: types.New(TPTR)}
+ f := &types.Field{Type: types.NewPtr(types.New(TINT))}
t.SetFields([]*types.Field{f})
return t
}
@@ -181,14 +181,6 @@ func TestStackvarSort(t *testing.T) {
nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
nodeWithClass(Node{Type: typeWithoutPointers(), Sym: &types.Sym{}}, PAUTO),
}
- // haspointers updates Type.Haspointers as a side effect, so
- // exercise this function on all inputs so that reflect.DeepEqual
- // doesn't produce false positives.
- for i := range want {
- want[i].Type.HasPointers()
- inp[i].Type.HasPointers()
- }
-
sort.Sort(byStackVar(inp))
if !reflect.DeepEqual(want, inp) {
t.Error("sort failed")
diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go
index 398bfe5baa..8976ed657a 100644
--- a/src/cmd/compile/internal/gc/plive.go
+++ b/src/cmd/compile/internal/gc/plive.go
@@ -436,7 +436,7 @@ func (lv *Liveness) regEffects(v *ssa.Value) (uevar, kill liveRegMask) {
case ssa.LocalSlot:
return mask
case *ssa.Register:
- if ptrOnly && !v.Type.HasHeapPointer() {
+ if ptrOnly && !v.Type.HasPointers() {
return mask
}
regs[0] = loc
@@ -451,7 +451,7 @@ func (lv *Liveness) regEffects(v *ssa.Value) (uevar, kill liveRegMask) {
if loc1 == nil {
continue
}
- if ptrOnly && !v.Type.FieldType(i).HasHeapPointer() {
+ if ptrOnly && !v.Type.FieldType(i).HasPointers() {
continue
}
regs[nreg] = loc1.(*ssa.Register)
@@ -568,13 +568,13 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
if t.Align > 0 && off&int64(t.Align-1) != 0 {
Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
}
+ if !t.HasPointers() {
+ // Note: this case ensures that pointers to go:notinheap types
+ // are not considered pointers by garbage collection and stack copying.
+ return
+ }
switch t.Etype {
- case TINT8, TUINT8, TINT16, TUINT16,
- TINT32, TUINT32, TINT64, TUINT64,
- TINT, TUINT, TUINTPTR, TBOOL,
- TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
-
case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
if off&int64(Widthptr-1) != 0 {
Fatalf("onebitwalktype1: invalid alignment, %v", t)
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index d78a5f0d8d..5434b0167a 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -586,7 +586,7 @@ func arrayClear(n, v1, v2, a *Node) bool {
n.Nbody.Append(nod(OAS, hn, tmp))
var fn *Node
- if a.Type.Elem().HasHeapPointer() {
+ if a.Type.Elem().HasPointers() {
// memclrHasPointers(hp, hn)
Curfn.Func.setWBPos(stmt.Pos)
fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go
index 3812a0e1fa..97e0424ce0 100644
--- a/src/cmd/compile/internal/gc/select.go
+++ b/src/cmd/compile/internal/gc/select.go
@@ -251,10 +251,8 @@ func walkselectcases(cases *Nodes) []*Node {
r = typecheck(r, ctxStmt)
init = append(init, r)
+ // No initialization for order; runtime.selectgo is responsible for that.
order := temp(types.NewArray(types.Types[TUINT16], 2*int64(ncas)))
- r = nod(OAS, order, nil)
- r = typecheck(r, ctxStmt)
- init = append(init, r)
var pc0, pcs *Node
if flag_race {
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index c8fb013ad0..89644cd3f2 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -295,7 +295,10 @@ func (s *state) emitOpenDeferInfo() {
// worker indicates which of the backend workers is doing the processing.
func buildssa(fn *Node, worker int) *ssa.Func {
name := fn.funcname()
- printssa := name == ssaDump
+ printssa := false
+ if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", or a package.name e.g. "compress/gzip.(*Reader).Reset"
+ printssa = name == ssaDump || myimportpath+"."+name == ssaDump
+ }
var astBuf *bytes.Buffer
if printssa {
astBuf = &bytes.Buffer{}
@@ -2110,7 +2113,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
}
@@ -6179,7 +6182,7 @@ func genssa(f *ssa.Func, pp *Progs) {
// Resolve branches, and relax DefaultStmt into NotStmt
for _, br := range s.Branches {
- br.P.To.Val = s.bstart[br.B.ID]
+ br.P.To.SetTarget(s.bstart[br.B.ID])
if br.P.Pos.IsStmt() != src.PosIsStmt {
br.P.Pos = br.P.Pos.WithNotStmt()
} else if v0 := br.B.FirstPossibleStmtValue(); v0 != nil && v0.Pos.Line() == br.P.Pos.Line() && v0.Pos.IsStmt() == src.PosIsStmt {
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 9362c74288..d3ba53ff0c 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -271,13 +271,6 @@ func autolabel(prefix string) *types.Sym {
return lookupN(prefix, int(n))
}
-func restrictlookup(name string, pkg *types.Pkg) *types.Sym {
- if !types.IsExported(name) && pkg != localpkg {
- yyerror("cannot refer to unexported name %s.%s", pkg.Name, name)
- }
- return pkg.Lookup(name)
-}
-
// find all the exported symbols in package opkg
// and make them available in the current package
func importdot(opkg *types.Pkg, pack *Node) {
@@ -788,12 +781,12 @@ func convertop(srcConstant bool, src, dst *types.Type, why *string) Op {
}
// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
- if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR {
+ 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) {
+ if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
return OCONVNOP
}
@@ -1550,7 +1543,6 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
tfn.List.Set(structargs(method.Type.Params(), true))
tfn.Rlist.Set(structargs(method.Type.Results(), false))
- disableExport(newnam)
fn := dclfunc(newnam, tfn)
fn.Func.SetDupok(true)
@@ -1638,8 +1630,7 @@ func hashmem(t *types.Type) *Node {
sym := Runtimepkg.Lookup("memhash")
n := newname(sym)
- n.SetClass(PFUNC)
- n.Sym.SetFunc(true)
+ setNodeNameFunc(n)
n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)),
anonfield(types.Types[TUINTPTR]),
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
index 47e5e59156..5580f789c5 100644
--- a/src/cmd/compile/internal/gc/syntax.go
+++ b/src/cmd/compile/internal/gc/syntax.go
@@ -141,19 +141,20 @@ const (
nodeInitorder, _ // tracks state during init1; two bits
_, _ // 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
- _, nodeIsDDD // is the argument variadic
- _, nodeDiag // already printed error about this
- _, nodeColas // OAS resulting from :=
- _, nodeNonNil // guaranteed to be non-nil
- _, nodeTransient // storage can be reused immediately after this statement
- _, nodeBounded // bounds check unnecessary
- _, nodeHasCall // expression contains a function call
- _, nodeLikely // if statement condition likely
- _, nodeHasVal // node.E contains a Val
- _, nodeHasOpt // node.E contains an Opt
- _, nodeEmbedded // ODCLFIELD embedded type
+ _, 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
+ _, nodeIsDDD // is the argument variadic
+ _, nodeDiag // already printed error about this
+ _, nodeColas // OAS resulting from :=
+ _, nodeNonNil // guaranteed to be non-nil
+ _, nodeTransient // storage can be reused immediately after this statement
+ _, nodeBounded // bounds check unnecessary
+ _, nodeHasCall // expression contains a function call
+ _, nodeLikely // if statement condition likely
+ _, nodeHasVal // node.E contains a Val
+ _, nodeHasOpt // node.E contains an Opt
+ _, nodeEmbedded // ODCLFIELD embedded type
+ _, nodeNeedsWrapper // OCALLxxx node that needs to be wrapped
)
func (n *Node) Class() Class { return Class(n.flags.get3(nodeClass)) }
@@ -286,6 +287,20 @@ func (n *Node) SetIota(x int64) {
n.Xoffset = x
}
+func (n *Node) NeedsWrapper() bool {
+ return n.flags&nodeNeedsWrapper != 0
+}
+
+// SetNeedsWrapper indicates that OCALLxxx node needs to be wrapped by a closure.
+func (n *Node) SetNeedsWrapper(b bool) {
+ switch n.Op {
+ case OCALLFUNC, OCALLMETH, OCALLINTER:
+ default:
+ Fatalf("Node.SetNeedsWrapper %v", n.Op)
+ }
+ n.flags.set(nodeNeedsWrapper, b)
+}
+
// mayBeShared reports whether n may occur in multiple places in the AST.
// Extra care must be taken when mutating such a node.
func (n *Node) mayBeShared() bool {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 77f88d8996..361de7e0f3 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -232,7 +232,11 @@ func walkstmt(n *Node) *Node {
n.Left = copyany(n.Left, &n.Ninit, true)
default:
- n.Left = walkexpr(n.Left, &n.Ninit)
+ if n.Left.NeedsWrapper() {
+ n.Left = wrapCall(n.Left, &n.Ninit)
+ } else {
+ n.Left = walkexpr(n.Left, &n.Ninit)
+ }
}
case OFOR, OFORUNTIL:
@@ -954,11 +958,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
}
@@ -1123,7 +1127,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 {
@@ -1156,6 +1160,9 @@ opswitch:
}
case ONEW:
+ if n.Type.Elem().NotInHeap() {
+ yyerror("%v is go:notinheap; heap allocation disallowed", n.Type.Elem())
+ }
if n.Esc == EscNone {
if n.Type.Elem().Width >= maxImplicitStackVarSize {
Fatalf("large ONEW with EscNone: %v", n)
@@ -1324,6 +1331,9 @@ opswitch:
l = r
}
t := n.Type
+ if t.Elem().NotInHeap() {
+ yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem())
+ }
if n.Esc == EscNone {
if !isSmallMakeSlice(n) {
Fatalf("non-small OMAKESLICE with EscNone: %v", n)
@@ -1365,10 +1375,6 @@ opswitch:
// When len and cap can fit into int, use makeslice instead of
// makeslice64, which is faster and shorter on 32 bit platforms.
- if t.Elem().NotInHeap() {
- yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem())
- }
-
len, cap := l, r
fnname := "makeslice64"
@@ -1403,7 +1409,7 @@ opswitch:
t := n.Type
if t.Elem().NotInHeap() {
- Fatalf("%v is go:notinheap; heap allocation disallowed", t.Elem())
+ yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem())
}
length := conv(n.Left, types.Types[TINT])
@@ -2012,9 +2018,6 @@ func walkprint(nn *Node, init *Nodes) *Node {
}
func callnew(t *types.Type) *Node {
- if t.NotInHeap() {
- yyerror("%v is go:notinheap; heap allocation disallowed", t)
- }
dowidth(t)
n := nod(ONEWOBJ, typename(t), nil)
n.Type = types.NewPtr(t)
@@ -2589,7 +2592,7 @@ func mapfast(t *types.Type) int {
}
switch algtype(t.Key()) {
case AMEM32:
- if !t.Key().HasHeapPointer() {
+ if !t.Key().HasPointers() {
return mapfast32
}
if Widthptr == 4 {
@@ -2597,7 +2600,7 @@ func mapfast(t *types.Type) int {
}
Fatalf("small pointer %v", t.Key())
case AMEM64:
- if !t.Key().HasHeapPointer() {
+ if !t.Key().HasPointers() {
return mapfast64
}
if Widthptr == 8 {
@@ -2744,7 +2747,7 @@ func appendslice(n *Node, init *Nodes) *Node {
nodes.Append(nod(OAS, s, nt))
var ncopy *Node
- if elemtype.HasHeapPointer() {
+ if elemtype.HasPointers() {
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.Type = s.Type
@@ -3082,7 +3085,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
// Also works if b is a string.
//
func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
- if n.Left.Type.Elem().HasHeapPointer() {
+ if n.Left.Type.Elem().HasPointers() {
Curfn.Func.setWBPos(n.Pos)
fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem())
n.Left = cheapexpr(n.Left, init)
@@ -3167,8 +3170,7 @@ func eqfor(t *types.Type) (n *Node, needsize bool) {
case ASPECIAL:
sym := typesymprefix(".eq", t)
n := newname(sym)
- n.SetClass(PFUNC)
- n.Sym.SetFunc(true)
+ setNodeNameFunc(n)
n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)),
anonfield(types.NewPtr(t)),
@@ -3859,6 +3861,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
@@ -3870,9 +3880,17 @@ func wrapCall(n *Node, init *Nodes) *Node {
init.AppendNodes(&n.Ninit)
}
+ isBuiltinCall := n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER
+ // 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))
}
@@ -3880,10 +3898,22 @@ 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.List.Set(args)
+ fn.Nbody.Set1(call)
funcbody()
@@ -3891,12 +3921,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
@@ -4011,7 +4041,7 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
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/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index 4d2ad48135..f8d9ac2379 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -629,23 +629,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- case ssa.OpPPC64MaskIfNotCarry:
- r := v.Reg()
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = ppc64.REGZERO
- p.To.Type = obj.TYPE_REG
- p.To.Reg = r
-
- case ssa.OpPPC64ADDconstForCarry:
- r1 := v.Args[0].Reg()
- p := s.Prog(v.Op.Asm())
- p.Reg = r1
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
- p.To.Type = obj.TYPE_REG
- p.To.Reg = ppc64.REGTMP // Ignored; this is for the carry effect.
-
case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL,
ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FCFIDS, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW,
ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB, ssa.OpPPC64MFVSRD, ssa.OpPPC64MTVSRD, ssa.OpPPC64FABS, ssa.OpPPC64FNABS,
@@ -666,6 +649,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
+ case ssa.OpPPC64SUBFCconst:
+ p := s.Prog(v.Op.Asm())
+ p.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt})
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = v.Args[0].Reg()
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = v.Reg()
+
case ssa.OpPPC64ANDCCconst:
p := s.Prog(v.Op.Asm())
p.Reg = v.Args[0].Reg()
@@ -1802,7 +1793,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
v.Fatalf("Pseudo-op should not make it to codegen: %s ###\n", v.LongString())
case ssa.OpPPC64InvertFlags:
v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
- case ssa.OpPPC64FlagEQ, ssa.OpPPC64FlagLT, ssa.OpPPC64FlagGT, ssa.OpPPC64FlagCarrySet, ssa.OpPPC64FlagCarryClear:
+ case ssa.OpPPC64FlagEQ, ssa.OpPPC64FlagLT, ssa.OpPPC64FlagGT:
v.Fatalf("Flag* ops should never make it to codegen %v", v.LongString())
case ssa.OpClobber:
// TODO: implement for clobberdead experiment. Nop is ok for now.
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index 4cf4b70a32..00d253c95a 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -338,8 +338,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
n.To.Reg = dividend
}
- j.To.Val = n
- j2.To.Val = s.Pc()
+ j.To.SetTarget(n)
+ j2.To.SetTarget(s.Pc())
}
case ssa.OpS390XADDconst, ssa.OpS390XADDWconst:
opregregimm(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg(), v.AuxInt)
diff --git a/src/cmd/compile/internal/ssa/addressingmodes.go b/src/cmd/compile/internal/ssa/addressingmodes.go
index 97a5ab4f03..aae0def27f 100644
--- a/src/cmd/compile/internal/ssa/addressingmodes.go
+++ b/src/cmd/compile/internal/ssa/addressingmodes.go
@@ -7,12 +7,14 @@ package ssa
// addressingModes combines address calculations into memory operations
// that can perform complicated addressing modes.
func addressingModes(f *Func) {
+ isInImmediateRange := is32Bit
switch f.Config.arch {
default:
// Most architectures can't do this.
return
case "amd64", "386":
- // TODO: s390x?
+ case "s390x":
+ isInImmediateRange = is20Bit
}
var tmp []*Value
@@ -40,7 +42,7 @@ func addressingModes(f *Func) {
switch [2]auxType{opcodeTable[v.Op].auxType, opcodeTable[p.Op].auxType} {
case [2]auxType{auxSymOff, auxInt32}:
// TODO: introduce auxSymOff32
- if !is32Bit(v.AuxInt + p.AuxInt) {
+ if !isInImmediateRange(v.AuxInt + p.AuxInt) {
continue
}
v.AuxInt += p.AuxInt
@@ -48,7 +50,7 @@ func addressingModes(f *Func) {
if v.Aux != nil && p.Aux != nil {
continue
}
- if !is32Bit(v.AuxInt + p.AuxInt) {
+ if !isInImmediateRange(v.AuxInt + p.AuxInt) {
continue
}
if p.Aux != nil {
@@ -398,4 +400,61 @@ var combine = map[[2]Op]Op{
[2]Op{Op386ANDLconstmodify, Op386LEAL4}: Op386ANDLconstmodifyidx4,
[2]Op{Op386ORLconstmodify, Op386LEAL4}: Op386ORLconstmodifyidx4,
[2]Op{Op386XORLconstmodify, Op386LEAL4}: Op386XORLconstmodifyidx4,
+
+ // s390x
+ [2]Op{OpS390XMOVDload, OpS390XADD}: OpS390XMOVDloadidx,
+ [2]Op{OpS390XMOVWload, OpS390XADD}: OpS390XMOVWloadidx,
+ [2]Op{OpS390XMOVHload, OpS390XADD}: OpS390XMOVHloadidx,
+ [2]Op{OpS390XMOVBload, OpS390XADD}: OpS390XMOVBloadidx,
+
+ [2]Op{OpS390XMOVWZload, OpS390XADD}: OpS390XMOVWZloadidx,
+ [2]Op{OpS390XMOVHZload, OpS390XADD}: OpS390XMOVHZloadidx,
+ [2]Op{OpS390XMOVBZload, OpS390XADD}: OpS390XMOVBZloadidx,
+
+ [2]Op{OpS390XMOVDBRload, OpS390XADD}: OpS390XMOVDBRloadidx,
+ [2]Op{OpS390XMOVWBRload, OpS390XADD}: OpS390XMOVWBRloadidx,
+ [2]Op{OpS390XMOVHBRload, OpS390XADD}: OpS390XMOVHBRloadidx,
+
+ [2]Op{OpS390XFMOVDload, OpS390XADD}: OpS390XFMOVDloadidx,
+ [2]Op{OpS390XFMOVSload, OpS390XADD}: OpS390XFMOVSloadidx,
+
+ [2]Op{OpS390XMOVDstore, OpS390XADD}: OpS390XMOVDstoreidx,
+ [2]Op{OpS390XMOVWstore, OpS390XADD}: OpS390XMOVWstoreidx,
+ [2]Op{OpS390XMOVHstore, OpS390XADD}: OpS390XMOVHstoreidx,
+ [2]Op{OpS390XMOVBstore, OpS390XADD}: OpS390XMOVBstoreidx,
+
+ [2]Op{OpS390XMOVDBRstore, OpS390XADD}: OpS390XMOVDBRstoreidx,
+ [2]Op{OpS390XMOVWBRstore, OpS390XADD}: OpS390XMOVWBRstoreidx,
+ [2]Op{OpS390XMOVHBRstore, OpS390XADD}: OpS390XMOVHBRstoreidx,
+
+ [2]Op{OpS390XFMOVDstore, OpS390XADD}: OpS390XFMOVDstoreidx,
+ [2]Op{OpS390XFMOVSstore, OpS390XADD}: OpS390XFMOVSstoreidx,
+
+ [2]Op{OpS390XMOVDload, OpS390XMOVDaddridx}: OpS390XMOVDloadidx,
+ [2]Op{OpS390XMOVWload, OpS390XMOVDaddridx}: OpS390XMOVWloadidx,
+ [2]Op{OpS390XMOVHload, OpS390XMOVDaddridx}: OpS390XMOVHloadidx,
+ [2]Op{OpS390XMOVBload, OpS390XMOVDaddridx}: OpS390XMOVBloadidx,
+
+ [2]Op{OpS390XMOVWZload, OpS390XMOVDaddridx}: OpS390XMOVWZloadidx,
+ [2]Op{OpS390XMOVHZload, OpS390XMOVDaddridx}: OpS390XMOVHZloadidx,
+ [2]Op{OpS390XMOVBZload, OpS390XMOVDaddridx}: OpS390XMOVBZloadidx,
+
+ [2]Op{OpS390XMOVDBRload, OpS390XMOVDaddridx}: OpS390XMOVDBRloadidx,
+ [2]Op{OpS390XMOVWBRload, OpS390XMOVDaddridx}: OpS390XMOVWBRloadidx,
+ [2]Op{OpS390XMOVHBRload, OpS390XMOVDaddridx}: OpS390XMOVHBRloadidx,
+
+ [2]Op{OpS390XFMOVDload, OpS390XMOVDaddridx}: OpS390XFMOVDloadidx,
+ [2]Op{OpS390XFMOVSload, OpS390XMOVDaddridx}: OpS390XFMOVSloadidx,
+
+ [2]Op{OpS390XMOVDstore, OpS390XMOVDaddridx}: OpS390XMOVDstoreidx,
+ [2]Op{OpS390XMOVWstore, OpS390XMOVDaddridx}: OpS390XMOVWstoreidx,
+ [2]Op{OpS390XMOVHstore, OpS390XMOVDaddridx}: OpS390XMOVHstoreidx,
+ [2]Op{OpS390XMOVBstore, OpS390XMOVDaddridx}: OpS390XMOVBstoreidx,
+
+ [2]Op{OpS390XMOVDBRstore, OpS390XMOVDaddridx}: OpS390XMOVDBRstoreidx,
+ [2]Op{OpS390XMOVWBRstore, OpS390XMOVDaddridx}: OpS390XMOVWBRstoreidx,
+ [2]Op{OpS390XMOVHBRstore, OpS390XMOVDaddridx}: OpS390XMOVHBRstoreidx,
+
+ [2]Op{OpS390XFMOVDstore, OpS390XMOVDaddridx}: OpS390XFMOVDstoreidx,
+ [2]Op{OpS390XFMOVSstore, OpS390XMOVDaddridx}: OpS390XFMOVSstoreidx,
}
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index 98e1b79334..828f645b39 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -171,10 +171,10 @@ func checkFunc(f *Func) {
canHaveAuxInt = true
canHaveAux = true
case auxCCop:
- if _, ok := v.Aux.(Op); !ok {
- f.Fatalf("bad type %T for CCop in %v", v.Aux, v)
+ if opcodeTable[Op(v.AuxInt)].name == "OpInvalid" {
+ f.Fatalf("value %v has an AuxInt value that is a valid opcode", v)
}
- canHaveAux = true
+ canHaveAuxInt = true
case auxS390XCCMask:
if _, ok := v.Aux.(s390x.CCMask); !ok {
f.Fatalf("bad type %T for S390XCCMask in %v", v.Aux, v)
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index c59ec4c77d..ab27ba85ae 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -23,9 +23,11 @@ func decomposeBuiltIn(f *Func) {
}
// Decompose other values
- applyRewrite(f, rewriteBlockdec, rewriteValuedec)
+ // Note: deadcode is false because we need to keep the original
+ // values around so the name component resolution below can still work.
+ applyRewrite(f, rewriteBlockdec, rewriteValuedec, leaveDeadValues)
if f.Config.RegSize == 4 {
- applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
+ applyRewrite(f, rewriteBlockdec64, rewriteValuedec64, leaveDeadValues)
}
// Split up named values into their components.
@@ -139,7 +141,7 @@ func decomposeStringPhi(v *Value) {
func decomposeSlicePhi(v *Value) {
types := &v.Block.Func.Config.Types
- ptrType := types.BytePtr
+ ptrType := v.Type.Elem().PtrTo()
lenType := types.Int
ptr := v.Block.NewValue0(v.Pos, OpPhi, ptrType)
@@ -215,7 +217,7 @@ func decomposeInterfacePhi(v *Value) {
}
func decomposeArgs(f *Func) {
- applyRewrite(f, rewriteBlockdecArgs, rewriteValuedecArgs)
+ applyRewrite(f, rewriteBlockdecArgs, rewriteValuedecArgs, removeDeadValues)
}
func decomposeUser(f *Func) {
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index 6718b778e1..32df0c06f3 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -257,6 +257,49 @@ func (f *Func) LogStat(key string, args ...interface{}) {
f.Warnl(f.Entry.Pos, "\t%s\t%s%s\t%s", n, key, value, f.Name)
}
+// unCacheLine removes v from f's constant cache "line" for aux,
+// resets v.InCache when it is found (and removed),
+// and returns whether v was found in that line.
+func (f *Func) unCacheLine(v *Value, aux int64) bool {
+ vv := f.constants[aux]
+ for i, cv := range vv {
+ if v == cv {
+ vv[i] = vv[len(vv)-1]
+ vv[len(vv)-1] = nil
+ f.constants[aux] = vv[0 : len(vv)-1]
+ v.InCache = false
+ return true
+ }
+ }
+ return false
+}
+
+// unCache removes v from f's constant cache.
+func (f *Func) unCache(v *Value) {
+ if v.InCache {
+ aux := v.AuxInt
+ if f.unCacheLine(v, aux) {
+ return
+ }
+ if aux == 0 {
+ switch v.Op {
+ case OpConstNil:
+ aux = constNilMagic
+ case OpConstSlice:
+ aux = constSliceMagic
+ case OpConstString:
+ aux = constEmptyStringMagic
+ case OpConstInterface:
+ aux = constInterfaceMagic
+ }
+ if aux != 0 && f.unCacheLine(v, aux) {
+ return
+ }
+ }
+ f.Fatalf("unCached value %s not found in cache, auxInt=0x%x, adjusted aux=0x%x", v.LongString(), v.AuxInt, aux)
+ }
+}
+
// freeValue frees a value. It must no longer be referenced or have any args.
func (f *Func) freeValue(v *Value) {
if v.Block == nil {
@@ -270,19 +313,8 @@ func (f *Func) freeValue(v *Value) {
}
// Clear everything but ID (which we reuse).
id := v.ID
-
- // Values with zero arguments and OpOffPtr values might be cached, so remove them there.
- nArgs := opcodeTable[v.Op].argLen
- if nArgs == 0 || v.Op == OpOffPtr {
- vv := f.constants[v.AuxInt]
- for i, cv := range vv {
- if v == cv {
- vv[i] = vv[len(vv)-1]
- vv[len(vv)-1] = nil
- f.constants[v.AuxInt] = vv[0 : len(vv)-1]
- break
- }
- }
+ if v.InCache {
+ f.unCache(v)
}
*v = Value{}
v.ID = id
@@ -548,6 +580,7 @@ func (f *Func) constVal(op Op, t *types.Type, c int64, setAuxInt bool) *Value {
v = f.Entry.NewValue0(src.NoXPos, op, t)
}
f.constants[c] = append(vv, v)
+ v.InCache = true
return v
}
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 5111ef79d3..8898fe55eb 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -436,69 +436,69 @@
// Absorb InvertFlags
(CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
- -> (CMOVQ(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+ => (CMOVQ(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
(CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
- -> (CMOVL(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+ => (CMOVL(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
(CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
- -> (CMOVW(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+ => (CMOVW(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
// Absorb constants generated during lower
-(CMOV(QEQ|QLE|QGE|QCC|QLS|LEQ|LLE|LGE|LCC|LLS|WEQ|WLE|WGE|WCC|WLS) _ x (FlagEQ)) -> x
-(CMOV(QNE|QLT|QGT|QCS|QHI|LNE|LLT|LGT|LCS|LHI|WNE|WLT|WGT|WCS|WHI) y _ (FlagEQ)) -> y
-(CMOV(QNE|QGT|QGE|QHI|QCC|LNE|LGT|LGE|LHI|LCC|WNE|WGT|WGE|WHI|WCC) _ x (FlagGT_UGT)) -> x
-(CMOV(QEQ|QLE|QLT|QLS|QCS|LEQ|LLE|LLT|LLS|LCS|WEQ|WLE|WLT|WLS|WCS) y _ (FlagGT_UGT)) -> y
-(CMOV(QNE|QGT|QGE|QLS|QCS|LNE|LGT|LGE|LLS|LCS|WNE|WGT|WGE|WLS|WCS) _ x (FlagGT_ULT)) -> x
-(CMOV(QEQ|QLE|QLT|QHI|QCC|LEQ|LLE|LLT|LHI|LCC|WEQ|WLE|WLT|WHI|WCC) y _ (FlagGT_ULT)) -> y
-(CMOV(QNE|QLT|QLE|QCS|QLS|LNE|LLT|LLE|LCS|LLS|WNE|WLT|WLE|WCS|WLS) _ x (FlagLT_ULT)) -> x
-(CMOV(QEQ|QGT|QGE|QHI|QCC|LEQ|LGT|LGE|LHI|LCC|WEQ|WGT|WGE|WHI|WCC) y _ (FlagLT_ULT)) -> y
-(CMOV(QNE|QLT|QLE|QHI|QCC|LNE|LLT|LLE|LHI|LCC|WNE|WLT|WLE|WHI|WCC) _ x (FlagLT_UGT)) -> x
-(CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) -> y
+(CMOV(QEQ|QLE|QGE|QCC|QLS|LEQ|LLE|LGE|LCC|LLS|WEQ|WLE|WGE|WCC|WLS) _ x (FlagEQ)) => x
+(CMOV(QNE|QLT|QGT|QCS|QHI|LNE|LLT|LGT|LCS|LHI|WNE|WLT|WGT|WCS|WHI) y _ (FlagEQ)) => y
+(CMOV(QNE|QGT|QGE|QHI|QCC|LNE|LGT|LGE|LHI|LCC|WNE|WGT|WGE|WHI|WCC) _ x (FlagGT_UGT)) => x
+(CMOV(QEQ|QLE|QLT|QLS|QCS|LEQ|LLE|LLT|LLS|LCS|WEQ|WLE|WLT|WLS|WCS) y _ (FlagGT_UGT)) => y
+(CMOV(QNE|QGT|QGE|QLS|QCS|LNE|LGT|LGE|LLS|LCS|WNE|WGT|WGE|WLS|WCS) _ x (FlagGT_ULT)) => x
+(CMOV(QEQ|QLE|QLT|QHI|QCC|LEQ|LLE|LLT|LHI|LCC|WEQ|WLE|WLT|WHI|WCC) y _ (FlagGT_ULT)) => y
+(CMOV(QNE|QLT|QLE|QCS|QLS|LNE|LLT|LLE|LCS|LLS|WNE|WLT|WLE|WCS|WLS) _ x (FlagLT_ULT)) => x
+(CMOV(QEQ|QGT|QGE|QHI|QCC|LEQ|LGT|LGE|LHI|LCC|WEQ|WGT|WGE|WHI|WCC) y _ (FlagLT_ULT)) => y
+(CMOV(QNE|QLT|QLE|QHI|QCC|LNE|LLT|LLE|LHI|LCC|WNE|WLT|WLE|WHI|WCC) _ x (FlagLT_UGT)) => x
+(CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) => y
// Miscellaneous
-(IsNonNil p) -> (SETNE (TESTQ p p))
-(IsInBounds idx len) -> (SETB (CMPQ idx len))
-(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
-(NilCheck ...) -> (LoweredNilCheck ...)
-(GetG ...) -> (LoweredGetG ...)
-(GetClosurePtr ...) -> (LoweredGetClosurePtr ...)
-(GetCallerPC ...) -> (LoweredGetCallerPC ...)
-(GetCallerSP ...) -> (LoweredGetCallerSP ...)
-
-(HasCPUFeature {s}) -> (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s})))
+(IsNonNil p) => (SETNE (TESTQ p p))
+(IsInBounds idx len) => (SETB (CMPQ idx len))
+(IsSliceInBounds idx len) => (SETBE (CMPQ idx len))
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetG ...) => (LoweredGetG ...)
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+
+(HasCPUFeature {s}) => (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s})))
(Addr ...) -> (LEAQ ...)
-(LocalAddr {sym} base _) -> (LEAQ {sym} base)
-
-(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 -> (SETLstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 -> (SETLEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETG x) mem) && y.Uses == 1 -> (SETGstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETGE x) mem) && y.Uses == 1 -> (SETGEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETEQ x) mem) && y.Uses == 1 -> (SETEQstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETNE x) mem) && y.Uses == 1 -> (SETNEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETB x) mem) && y.Uses == 1 -> (SETBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETBE x) mem) && y.Uses == 1 -> (SETBEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETA x) mem) && y.Uses == 1 -> (SETAstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETAE x) mem) && y.Uses == 1 -> (SETAEstore [off] {sym} ptr x mem)
+(LocalAddr {sym} base _) => (LEAQ {sym} base)
+
+(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 => (SETLstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 => (SETLEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETG x) mem) && y.Uses == 1 => (SETGstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETGE x) mem) && y.Uses == 1 => (SETGEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETEQ x) mem) && y.Uses == 1 => (SETEQstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETNE x) mem) && y.Uses == 1 => (SETNEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETB x) mem) && y.Uses == 1 => (SETBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETBE x) mem) && y.Uses == 1 => (SETBEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETA x) mem) && y.Uses == 1 => (SETAstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETAE x) mem) && y.Uses == 1 => (SETAEstore [off] {sym} ptr x mem)
// block rewrites
-(If (SETL cmp) yes no) -> (LT cmp yes no)
-(If (SETLE cmp) yes no) -> (LE cmp yes no)
-(If (SETG cmp) yes no) -> (GT cmp yes no)
-(If (SETGE cmp) yes no) -> (GE cmp yes no)
-(If (SETEQ cmp) yes no) -> (EQ cmp yes no)
-(If (SETNE cmp) yes no) -> (NE cmp yes no)
-(If (SETB cmp) yes no) -> (ULT cmp yes no)
-(If (SETBE cmp) yes no) -> (ULE cmp yes no)
-(If (SETA cmp) yes no) -> (UGT cmp yes no)
-(If (SETAE cmp) yes no) -> (UGE cmp yes no)
-(If (SETO cmp) yes no) -> (OS cmp yes no)
+(If (SETL cmp) yes no) => (LT cmp yes no)
+(If (SETLE cmp) yes no) => (LE cmp yes no)
+(If (SETG cmp) yes no) => (GT cmp yes no)
+(If (SETGE cmp) yes no) => (GE cmp yes no)
+(If (SETEQ cmp) yes no) => (EQ cmp yes no)
+(If (SETNE cmp) yes no) => (NE cmp yes no)
+(If (SETB cmp) yes no) => (ULT cmp yes no)
+(If (SETBE cmp) yes no) => (ULE cmp yes no)
+(If (SETA cmp) yes no) => (UGT cmp yes no)
+(If (SETAE cmp) yes no) => (UGE cmp yes no)
+(If (SETO cmp) yes no) => (OS cmp yes no)
// Special case for floating point - LF/LEF not generated
-(If (SETGF cmp) yes no) -> (UGT cmp yes no)
-(If (SETGEF cmp) yes no) -> (UGE cmp yes no)
-(If (SETEQF cmp) yes no) -> (EQF cmp yes no)
-(If (SETNEF cmp) yes no) -> (NEF cmp yes no)
+(If (SETGF cmp) yes no) => (UGT cmp yes no)
+(If (SETGEF cmp) yes no) => (UGE cmp yes no)
+(If (SETEQF cmp) yes no) => (EQF cmp yes no)
+(If (SETNEF cmp) yes no) => (NEF cmp yes no)
-(If cond yes no) -> (NE (TESTB cond cond) yes no)
+(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 ...)
@@ -508,22 +508,22 @@
// 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?
-(AtomicStore8 ptr val mem) -> (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
-(AtomicStore32 ptr val mem) -> (Select1 (XCHGL <types.NewTuple(typ.UInt32,types.TypeMem)> val ptr mem))
-(AtomicStore64 ptr val mem) -> (Select1 (XCHGQ <types.NewTuple(typ.UInt64,types.TypeMem)> val ptr mem))
-(AtomicStorePtrNoWB ptr val mem) -> (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
+(AtomicStore8 ptr val mem) => (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
+(AtomicStore32 ptr val mem) => (Select1 (XCHGL <types.NewTuple(typ.UInt32,types.TypeMem)> val ptr mem))
+(AtomicStore64 ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.UInt64,types.TypeMem)> val ptr mem))
+(AtomicStorePtrNoWB ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
// Atomic exchanges.
-(AtomicExchange32 ptr val mem) -> (XCHGL val ptr mem)
-(AtomicExchange64 ptr val mem) -> (XCHGQ val ptr mem)
+(AtomicExchange32 ptr val mem) => (XCHGL val ptr mem)
+(AtomicExchange64 ptr val mem) => (XCHGQ val ptr mem)
// Atomic adds.
-(AtomicAdd32 ptr val mem) -> (AddTupleFirst32 val (XADDLlock val ptr mem))
-(AtomicAdd64 ptr val mem) -> (AddTupleFirst64 val (XADDQlock val ptr mem))
-(Select0 <t> (AddTupleFirst32 val tuple)) -> (ADDL val (Select0 <t> tuple))
-(Select1 (AddTupleFirst32 _ tuple)) -> (Select1 tuple)
-(Select0 <t> (AddTupleFirst64 val tuple)) -> (ADDQ val (Select0 <t> tuple))
-(Select1 (AddTupleFirst64 _ tuple)) -> (Select1 tuple)
+(AtomicAdd32 ptr val mem) => (AddTupleFirst32 val (XADDLlock val ptr mem))
+(AtomicAdd64 ptr val mem) => (AddTupleFirst64 val (XADDQlock val ptr mem))
+(Select0 <t> (AddTupleFirst32 val tuple)) => (ADDL val (Select0 <t> tuple))
+(Select1 (AddTupleFirst32 _ tuple)) => (Select1 tuple)
+(Select0 <t> (AddTupleFirst64 val tuple)) => (ADDQ val (Select0 <t> tuple))
+(Select1 (AddTupleFirst64 _ tuple)) => (Select1 tuple)
// Atomic compare and swap.
(AtomicCompareAndSwap32 ...) -> (CMPXCHGLlock ...)
@@ -536,9 +536,9 @@
// Write barrier.
(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)
// ***************************
// Above: lowering rules
@@ -547,23 +547,23 @@
// TODO: Should the optimizations be a separate pass?
// Fold boolean tests into blocks
-(NE (TESTB (SETL cmp) (SETL cmp)) yes no) -> (LT cmp yes no)
-(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) -> (LE cmp yes no)
-(NE (TESTB (SETG cmp) (SETG cmp)) yes no) -> (GT cmp yes no)
-(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) -> (GE cmp yes no)
-(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) -> (EQ cmp yes no)
-(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) -> (NE cmp yes no)
-(NE (TESTB (SETB cmp) (SETB cmp)) yes no) -> (ULT cmp yes no)
-(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) -> (ULE cmp yes no)
-(NE (TESTB (SETA cmp) (SETA cmp)) yes no) -> (UGT cmp yes no)
-(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) -> (UGE cmp yes no)
-(NE (TESTB (SETO cmp) (SETO cmp)) yes no) -> (OS cmp yes no)
+(NE (TESTB (SETL cmp) (SETL cmp)) yes no) => (LT cmp yes no)
+(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) => (LE cmp yes no)
+(NE (TESTB (SETG cmp) (SETG cmp)) yes no) => (GT cmp yes no)
+(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) => (GE cmp yes no)
+(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) => (EQ cmp yes no)
+(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) => (NE cmp yes no)
+(NE (TESTB (SETB cmp) (SETB cmp)) yes no) => (ULT cmp yes no)
+(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) => (ULE cmp yes no)
+(NE (TESTB (SETA cmp) (SETA cmp)) yes no) => (UGT cmp yes no)
+(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) => (UGE cmp yes no)
+(NE (TESTB (SETO cmp) (SETO cmp)) yes no) => (OS cmp yes no)
// Unsigned comparisons to 0/1
-(ULT (TEST(Q|L|W|B) x x) yes no) -> (First no yes)
-(UGE (TEST(Q|L|W|B) x x) yes no) -> (First yes no)
-(SETB (TEST(Q|L|W|B) x x)) -> (ConstBool [0])
-(SETAE (TEST(Q|L|W|B) x x)) -> (ConstBool [1])
+(ULT (TEST(Q|L|W|B) x x) yes no) => (First no yes)
+(UGE (TEST(Q|L|W|B) x x) yes no) => (First yes no)
+(SETB (TEST(Q|L|W|B) x x)) => (ConstBool [false])
+(SETAE (TEST(Q|L|W|B) x x)) => (ConstBool [true])
// x & 1 != 0 -> x & 1
(SETNE (TEST(B|W)const [1] x)) => (AND(L|L)const [1] x)
@@ -574,75 +574,75 @@
// into tests for carry flags.
// ULT and SETB check the carry flag; they are identical to CS and SETCS. Same, mutatis
// mutandis, for UGE and SETAE, and CC and SETCC.
-((NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) -> ((ULT|UGE) (BTL x y))
-((NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) -> ((ULT|UGE) (BTQ x y))
-((NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(c)
- -> ((ULT|UGE) (BTLconst [log2uint32(c)] x))
-((NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(c)
- -> ((ULT|UGE) (BTQconst [log2(c)] x))
+((NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => ((ULT|UGE) (BTL x y))
+((NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => ((ULT|UGE) (BTQ x y))
+((NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c))
+ => ((ULT|UGE) (BTLconst [int8(log32(c))] x))
+((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 [log2(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(c)
- -> (SET(B|AE) (BTLconst [log2uint32(c)] x))
-(SET(NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(c)
- -> (SET(B|AE) (BTQconst [log2(c)] x))
+ => ((ULT|UGE) (BTQconst [int8(log2(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))
+ => (SET(B|AE) (BTLconst [int8(log32(c))] x))
+(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 [log2(c)] x))
+ => (SET(B|AE) (BTQconst [int8(log2(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)
+ => (SET(B|AE)store [off] {sym} ptr (BTL x y) mem)
(SET(NE|EQ)store [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
- -> (SET(B|AE)store [off] {sym} ptr (BTQ x y) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUint32PowerOfTwo(c)
- -> (SET(B|AE)store [off] {sym} ptr (BTLconst [log2uint32(c)] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUint64PowerOfTwo(c)
- -> (SET(B|AE)store [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTQ x y) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUint32PowerOfTwo(int64(c))
+ => (SET(B|AE)store [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
+(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 [log2(c)] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem)
// Handle bit-testing in the form (a>>b)&1 != 0 by building the above rules
// and further combining shifts.
-(BT(Q|L)const [c] (SHRQconst [d] x)) && (c+d)<64 -> (BTQconst [c+d] x)
-(BT(Q|L)const [c] (SHLQconst [d] x)) && c>d -> (BT(Q|L)const [c-d] x)
-(BT(Q|L)const [0] s:(SHRQ x y)) -> (BTQ y x)
-(BTLconst [c] (SHRLconst [d] x)) && (c+d)<32 -> (BTLconst [c+d] x)
-(BTLconst [c] (SHLLconst [d] x)) && c>d -> (BTLconst [c-d] x)
-(BTLconst [0] s:(SHRL x y)) -> (BTL y x)
+(BT(Q|L)const [c] (SHRQconst [d] x)) && (c+d)<64 => (BTQconst [c+d] x)
+(BT(Q|L)const [c] (SHLQconst [d] x)) && c>d => (BT(Q|L)const [c-d] x)
+(BT(Q|L)const [0] s:(SHRQ x y)) => (BTQ y x)
+(BTLconst [c] (SHRLconst [d] x)) && (c+d)<32 => (BTLconst [c+d] x)
+(BTLconst [c] (SHLLconst [d] x)) && c>d => (BTLconst [c-d] x)
+(BTLconst [0] s:(SHRL x y)) => (BTL y x)
// Rewrite a & 1 != 1 into a & 1 == 0.
// Among other things, this lets us turn (a>>b)&1 != 1 into a bit test.
-(SET(NE|EQ) (CMPLconst [1] s:(ANDLconst [1] _))) -> (SET(EQ|NE) (CMPLconst [0] s))
-(SET(NE|EQ)store [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem) -> (SET(EQ|NE)store [off] {sym} ptr (CMPLconst [0] s) mem)
-(SET(NE|EQ) (CMPQconst [1] s:(ANDQconst [1] _))) -> (SET(EQ|NE) (CMPQconst [0] s))
-(SET(NE|EQ)store [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem) -> (SET(EQ|NE)store [off] {sym} ptr (CMPQconst [0] s) mem)
+(SET(NE|EQ) (CMPLconst [1] s:(ANDLconst [1] _))) => (SET(EQ|NE) (CMPLconst [0] s))
+(SET(NE|EQ)store [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPLconst [0] s) mem)
+(SET(NE|EQ) (CMPQconst [1] s:(ANDQconst [1] _))) => (SET(EQ|NE) (CMPQconst [0] s))
+(SET(NE|EQ)store [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPQconst [0] s) mem)
// Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b)
-(OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) -> (BTS(Q|L) x y)
-(XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) -> (BTC(Q|L) x y)
+(OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y)
+(XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
// Convert ORconst into BTS, if the code gets smaller, with boundary being
// (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes).
-((ORQ|XORQ)const [c] x) && isUint64PowerOfTwo(c) && uint64(c) >= 128
- -> (BT(S|C)Qconst [log2(c)] x)
-((ORL|XORL)const [c] x) && isUint32PowerOfTwo(c) && uint64(c) >= 128
- -> (BT(S|C)Lconst [log2uint32(c)] x)
+((ORQ|XORQ)const [c] x) && isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128
+ => (BT(S|C)Qconst [int8(log32(c))] x)
+((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 [log2(c)] x)
-((ORL|XORL) (MOVLconst [c]) x) && isUint32PowerOfTwo(c) && uint64(c) >= 128
- -> (BT(S|C)Lconst [log2uint32(c)] x)
+ => (BT(S|C)Qconst [int8(log2(c))] x)
+((ORL|XORL) (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+ => (BT(S|C)Lconst [int8(log32(c))] x)
// Recognize bit clearing: a &^= 1<<b
-(AND(Q|L) (NOT(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y)) x) -> (BTR(Q|L) x y)
-(ANDQconst [c] x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 128
- -> (BTRQconst [log2(^c)] x)
-(ANDLconst [c] x) && isUint32PowerOfTwo(^c) && uint64(^c) >= 128
- -> (BTRLconst [log2uint32(^c)] x)
+(AND(Q|L) (NOT(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y)) x) => (BTR(Q|L) x y)
+(ANDQconst [c] x) && isUint64PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ => (BTRQconst [int8(log32(^c))] x)
+(ANDLconst [c] x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ => (BTRLconst [int8(log32(^c))] x)
(ANDQ (MOVQconst [c]) x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 128
- -> (BTRQconst [log2(^c)] x)
-(ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(^c) && uint64(^c) >= 128
- -> (BTRLconst [log2uint32(^c)] x)
+ => (BTRQconst [int8(log2(^c))] x)
+(ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ => (BTRLconst [int8(log32(^c))] x)
// Special-case bit patterns on first/last bit.
// generic.rules changes ANDs of high-part/low-part masks into a couple of shifts,
@@ -656,84 +656,84 @@
// Special case resetting first/last bit
(SHL(L|Q)const [1] (SHR(L|Q)const [1] x))
- -> (BTR(L|Q)const [0] x)
+ => (BTR(L|Q)const [0] x)
(SHRLconst [1] (SHLLconst [1] x))
- -> (BTRLconst [31] x)
+ => (BTRLconst [31] x)
(SHRQconst [1] (SHLQconst [1] x))
- -> (BTRQconst [63] x)
+ => (BTRQconst [63] x)
// Special case testing first/last bit (with double-shift generated by generic.rules)
((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
+ => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHLLconst [31] (SHRQconst [31] x)) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTQconst [31] x))
+ => ((SETB|SETAE|ULT|UGE) (BTQconst [31] x))
(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHLLconst [31] (SHRLconst [31] x)) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTQconst [0] x))
+ => ((SETB|SETAE|ULT|UGE) (BTQconst [0] x))
((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTLconst [0] x))
+ => ((SETB|SETAE|ULT|UGE) (BTLconst [0] x))
(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTQconst [0] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTQconst [0] x) mem)
(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTLconst [0] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTLconst [0] x) mem)
// Special-case manually testing last bit with "a>>63 != 0" (without "&1")
((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] x) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
+ => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] x) z2)) && z1==z2
- -> ((SETB|SETAE|ULT|UGE) (BTLconst [31] x))
+ => ((SETB|SETAE|ULT|UGE) (BTLconst [31] x))
(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] x) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] x) z2) mem) && z1==z2
- -> (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
+ => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
// Fold combinations of bit ops on same bit. An example is math.Copysign(c,-1)
-(BTS(Q|L)const [c] (BTR(Q|L)const [c] x)) -> (BTS(Q|L)const [c] x)
-(BTS(Q|L)const [c] (BTC(Q|L)const [c] x)) -> (BTS(Q|L)const [c] x)
-(BTR(Q|L)const [c] (BTS(Q|L)const [c] x)) -> (BTR(Q|L)const [c] x)
-(BTR(Q|L)const [c] (BTC(Q|L)const [c] x)) -> (BTR(Q|L)const [c] x)
+(BTS(Q|L)const [c] (BTR(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
+(BTS(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
+(BTR(Q|L)const [c] (BTS(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
+(BTR(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
// Fold boolean negation into SETcc.
-(XORLconst [1] (SETNE x)) -> (SETEQ x)
-(XORLconst [1] (SETEQ x)) -> (SETNE x)
-(XORLconst [1] (SETL x)) -> (SETGE x)
-(XORLconst [1] (SETGE x)) -> (SETL x)
-(XORLconst [1] (SETLE x)) -> (SETG x)
-(XORLconst [1] (SETG x)) -> (SETLE x)
-(XORLconst [1] (SETB x)) -> (SETAE x)
-(XORLconst [1] (SETAE x)) -> (SETB x)
-(XORLconst [1] (SETBE x)) -> (SETA x)
-(XORLconst [1] (SETA x)) -> (SETBE x)
+(XORLconst [1] (SETNE x)) => (SETEQ x)
+(XORLconst [1] (SETEQ x)) => (SETNE x)
+(XORLconst [1] (SETL x)) => (SETGE x)
+(XORLconst [1] (SETGE x)) => (SETL x)
+(XORLconst [1] (SETLE x)) => (SETG x)
+(XORLconst [1] (SETG x)) => (SETLE x)
+(XORLconst [1] (SETB x)) => (SETAE x)
+(XORLconst [1] (SETAE x)) => (SETB x)
+(XORLconst [1] (SETBE x)) => (SETA x)
+(XORLconst [1] (SETA x)) => (SETBE x)
// Special case for floating point - LF/LEF not generated
-(NE (TESTB (SETGF cmp) (SETGF cmp)) yes no) -> (UGT cmp yes no)
-(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) -> (UGE cmp yes no)
-(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) -> (EQF cmp yes no)
-(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) -> (NEF cmp yes no)
+(NE (TESTB (SETGF cmp) (SETGF cmp)) yes no) => (UGT cmp yes no)
+(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) => (UGE cmp yes no)
+(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) => (EQF cmp yes no)
+(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) => (NEF cmp yes no)
// Disabled because it interferes with the pattern match above and makes worse code.
-// (SETNEF x) -> (ORQ (SETNE <typ.Int8> x) (SETNAN <typ.Int8> x))
-// (SETEQF x) -> (ANDQ (SETEQ <typ.Int8> x) (SETORD <typ.Int8> x))
+// (SETNEF x) => (ORQ (SETNE <typ.Int8> x) (SETNAN <typ.Int8> x))
+// (SETEQF x) => (ANDQ (SETEQ <typ.Int8> x) (SETORD <typ.Int8> x))
// fold constants into instructions
-(ADDQ x (MOVQconst [c])) && is32Bit(c) -> (ADDQconst [c] x)
-(ADDQ x (MOVLconst [c])) && is32Bit(c) -> (ADDQconst [int64(int32(c))] x)
-(ADDL x (MOVLconst [c])) -> (ADDLconst [c] x)
+(ADDQ x (MOVQconst [c])) && is32Bit(c) => (ADDQconst [int32(c)] x)
+(ADDQ x (MOVLconst [c])) => (ADDQconst [c] x)
+(ADDL x (MOVLconst [c])) => (ADDLconst [c] x)
-(SUBQ x (MOVQconst [c])) && is32Bit(c) -> (SUBQconst x [c])
-(SUBQ (MOVQconst [c]) x) && is32Bit(c) -> (NEGQ (SUBQconst <v.Type> x [c]))
-(SUBL x (MOVLconst [c])) -> (SUBLconst x [c])
-(SUBL (MOVLconst [c]) x) -> (NEGL (SUBLconst <v.Type> x [c]))
+(SUBQ x (MOVQconst [c])) && is32Bit(c) => (SUBQconst x [int32(c)])
+(SUBQ (MOVQconst [c]) x) && is32Bit(c) => (NEGQ (SUBQconst <v.Type> x [int32(c)]))
+(SUBL x (MOVLconst [c])) => (SUBLconst x [c])
+(SUBL (MOVLconst [c]) x) => (NEGL (SUBLconst <v.Type> x [c]))
-(MULQ x (MOVQconst [c])) && is32Bit(c) -> (MULQconst [c] x)
-(MULL x (MOVLconst [c])) -> (MULLconst [c] x)
+(MULQ x (MOVQconst [c])) && is32Bit(c) => (MULQconst [int32(c)] x)
+(MULL x (MOVLconst [c])) => (MULLconst [c] x)
-(ANDQ x (MOVQconst [c])) && is32Bit(c) -> (ANDQconst [c] x)
-(ANDL x (MOVLconst [c])) -> (ANDLconst [c] x)
+(ANDQ x (MOVQconst [c])) && is32Bit(c) => (ANDQconst [int32(c)] x)
+(ANDL x (MOVLconst [c])) => (ANDLconst [c] x)
(AND(L|Q)const [c] (AND(L|Q)const [d] x)) => (AND(L|Q)const [c & d] x)
(XOR(L|Q)const [c] (XOR(L|Q)const [d] x)) => (XOR(L|Q)const [c ^ d] x)
@@ -763,68 +763,70 @@
(ORQconst [c] (BTSQconst [d] x)) && is32Bit(int64(c) | 1<<uint32(d)) => (ORQconst [c | 1<<uint32(d)] x)
(BTSQconst [c] (BTSQconst [d] x)) && is32Bit(1<<uint32(c) | 1<<uint32(d)) => (ORQconst [1<<uint32(c) | 1<<uint32(d)] x)
-(MULLconst [c] (MULLconst [d] x)) -> (MULLconst [int64(int32(c * d))] x)
-(MULQconst [c] (MULQconst [d] x)) && is32Bit(c*d) -> (MULQconst [c * d] x)
-(ORQ x (MOVQconst [c])) && is32Bit(c) -> (ORQconst [c] x)
-(ORQ x (MOVLconst [c])) -> (ORQconst [c] x)
-(ORL x (MOVLconst [c])) -> (ORLconst [c] x)
+(MULLconst [c] (MULLconst [d] x)) => (MULLconst [c * d] x)
+(MULQconst [c] (MULQconst [d] x)) && is32Bit(int64(c)*int64(d)) => (MULQconst [c * d] x)
-(XORQ x (MOVQconst [c])) && is32Bit(c) -> (XORQconst [c] x)
-(XORL x (MOVLconst [c])) -> (XORLconst [c] x)
+(ORQ x (MOVQconst [c])) && is32Bit(c) => (ORQconst [int32(c)] x)
+(ORQ x (MOVLconst [c])) => (ORQconst [c] x)
+(ORL x (MOVLconst [c])) => (ORLconst [c] x)
-(SHLQ x (MOV(Q|L)const [c])) -> (SHLQconst [c&63] x)
-(SHLL x (MOV(Q|L)const [c])) -> (SHLLconst [c&31] x)
+(XORQ x (MOVQconst [c])) && is32Bit(c) => (XORQconst [int32(c)] x)
+(XORL x (MOVLconst [c])) => (XORLconst [c] x)
-(SHRQ x (MOV(Q|L)const [c])) -> (SHRQconst [c&63] x)
-(SHRL x (MOV(Q|L)const [c])) -> (SHRLconst [c&31] x)
-(SHRW x (MOV(Q|L)const [c])) && c&31 < 16 -> (SHRWconst [c&31] x)
-(SHRW _ (MOV(Q|L)const [c])) && c&31 >= 16 -> (MOVLconst [0])
-(SHRB x (MOV(Q|L)const [c])) && c&31 < 8 -> (SHRBconst [c&31] x)
-(SHRB _ (MOV(Q|L)const [c])) && c&31 >= 8 -> (MOVLconst [0])
+(SHLQ x (MOV(Q|L)const [c])) => (SHLQconst [int8(c&63)] x)
+(SHLL x (MOV(Q|L)const [c])) => (SHLLconst [int8(c&31)] x)
+
+(SHRQ x (MOV(Q|L)const [c])) => (SHRQconst [int8(c&63)] x)
+(SHRL x (MOV(Q|L)const [c])) => (SHRLconst [int8(c&31)] x)
+(SHRW x (MOV(Q|L)const [c])) && c&31 < 16 => (SHRWconst [int8(c&31)] x)
+(SHRW _ (MOV(Q|L)const [c])) && c&31 >= 16 => (MOVLconst [0])
+(SHRB x (MOV(Q|L)const [c])) && c&31 < 8 => (SHRBconst [int8(c&31)] x)
+(SHRB _ (MOV(Q|L)const [c])) && c&31 >= 8 => (MOVLconst [0])
+
+(SARQ x (MOV(Q|L)const [c])) => (SARQconst [int8(c&63)] x)
+(SARL x (MOV(Q|L)const [c])) => (SARLconst [int8(c&31)] x)
+(SARW x (MOV(Q|L)const [c])) => (SARWconst [int8(min(int64(c)&31,15))] x)
+(SARB x (MOV(Q|L)const [c])) => (SARBconst [int8(min(int64(c)&31,7))] x)
-(SARQ x (MOV(Q|L)const [c])) -> (SARQconst [c&63] x)
-(SARL x (MOV(Q|L)const [c])) -> (SARLconst [c&31] x)
-(SARW x (MOV(Q|L)const [c])) -> (SARWconst [min(c&31,15)] x)
-(SARB x (MOV(Q|L)const [c])) -> (SARBconst [min(c&31,7)] x)
// Operations which don't affect the low 6/5 bits of the shift amount are NOPs.
-((SHLQ|SHRQ|SARQ) x (ADDQconst [c] y)) && c & 63 == 0 -> ((SHLQ|SHRQ|SARQ) x y)
-((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0 -> ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
-((SHLQ|SHRQ|SARQ) x (ANDQconst [c] y)) && c & 63 == 63 -> ((SHLQ|SHRQ|SARQ) x y)
-((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 -> ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
-
-((SHLL|SHRL|SARL) x (ADDQconst [c] y)) && c & 31 == 0 -> ((SHLL|SHRL|SARL) x y)
-((SHLL|SHRL|SARL) x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0 -> ((SHLL|SHRL|SARL) x (NEGQ <t> y))
-((SHLL|SHRL|SARL) x (ANDQconst [c] y)) && c & 31 == 31 -> ((SHLL|SHRL|SARL) x y)
-((SHLL|SHRL|SARL) x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 -> ((SHLL|SHRL|SARL) x (NEGQ <t> y))
-
-((SHLQ|SHRQ|SARQ) x (ADDLconst [c] y)) && c & 63 == 0 -> ((SHLQ|SHRQ|SARQ) x y)
-((SHLQ|SHRQ|SARQ) x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0 -> ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
-((SHLQ|SHRQ|SARQ) x (ANDLconst [c] y)) && c & 63 == 63 -> ((SHLQ|SHRQ|SARQ) x y)
-((SHLQ|SHRQ|SARQ) x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 -> ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
-
-((SHLL|SHRL|SARL) x (ADDLconst [c] y)) && c & 31 == 0 -> ((SHLL|SHRL|SARL) x y)
-((SHLL|SHRL|SARL) x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0 -> ((SHLL|SHRL|SARL) x (NEGL <t> y))
-((SHLL|SHRL|SARL) x (ANDLconst [c] y)) && c & 31 == 31 -> ((SHLL|SHRL|SARL) x y)
-((SHLL|SHRL|SARL) x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 -> ((SHLL|SHRL|SARL) x (NEGL <t> y))
+((SHLQ|SHRQ|SARQ) x (ADDQconst [c] y)) && c & 63 == 0 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0 => ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
+((SHLQ|SHRQ|SARQ) x (ANDQconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
+
+((SHLL|SHRL|SARL) x (ADDQconst [c] y)) && c & 31 == 0 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0 => ((SHLL|SHRL|SARL) x (NEGQ <t> y))
+((SHLL|SHRL|SARL) x (ANDQconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL) x (NEGQ <t> y))
+
+((SHLQ|SHRQ|SARQ) x (ADDLconst [c] y)) && c & 63 == 0 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0 => ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
+((SHLQ|SHRQ|SARQ) x (ANDLconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
+
+((SHLL|SHRL|SARL) x (ADDLconst [c] y)) && c & 31 == 0 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0 => ((SHLL|SHRL|SARL) x (NEGL <t> y))
+((SHLL|SHRL|SARL) x (ANDLconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL) x (NEGL <t> y))
// Constant rotate instructions
-((ADDQ|ORQ|XORQ) (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c -> (ROLQconst x [c])
-((ADDL|ORL|XORL) (SHLLconst x [c]) (SHRLconst x [d])) && d==32-c -> (ROLLconst x [c])
+((ADDQ|ORQ|XORQ) (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c => (ROLQconst x [c])
+((ADDL|ORL|XORL) (SHLLconst x [c]) (SHRLconst x [d])) && d==32-c => (ROLLconst x [c])
-((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRWconst x [d])) && d==16-c && c < 16 && t.Size() == 2 -> (ROLWconst x [c])
-((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRBconst x [d])) && d==8-c && c < 8 && t.Size() == 1 -> (ROLBconst x [c])
+((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRWconst x [d])) && d==16-c && c < 16 && t.Size() == 2 => (ROLWconst x [c])
+((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRBconst x [d])) && d==8-c && c < 8 && t.Size() == 1 => (ROLBconst x [c])
-(ROLQconst [c] (ROLQconst [d] x)) -> (ROLQconst [(c+d)&63] x)
-(ROLLconst [c] (ROLLconst [d] x)) -> (ROLLconst [(c+d)&31] x)
-(ROLWconst [c] (ROLWconst [d] x)) -> (ROLWconst [(c+d)&15] x)
-(ROLBconst [c] (ROLBconst [d] x)) -> (ROLBconst [(c+d)& 7] x)
+(ROLQconst [c] (ROLQconst [d] x)) => (ROLQconst [(c+d)&63] x)
+(ROLLconst [c] (ROLLconst [d] x)) => (ROLLconst [(c+d)&31] x)
+(ROLWconst [c] (ROLWconst [d] x)) => (ROLWconst [(c+d)&15] x)
+(ROLBconst [c] (ROLBconst [d] x)) => (ROLBconst [(c+d)& 7] x)
-(RotateLeft8 ...) -> (ROLB ...)
-(RotateLeft16 ...) -> (ROLW ...)
-(RotateLeft32 ...) -> (ROLL ...)
-(RotateLeft64 ...) -> (ROLQ ...)
+(RotateLeft8 ...) => (ROLB ...)
+(RotateLeft16 ...) => (ROLW ...)
+(RotateLeft32 ...) => (ROLL ...)
+(RotateLeft64 ...) => (ROLQ ...)
// Non-constant rotates.
// We want to issue a rotate when the Go source contains code like
@@ -837,15 +839,15 @@
// But x >> 64 is 0, not x. So there's an additional mask that is ANDed in
// to force the second term to 0. We don't need that mask, but we must match
// it in order to strip it out.
-(ORQ (SHLQ x y) (ANDQ (SHRQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) -> (ROLQ x y)
-(ORQ (SHRQ x y) (ANDQ (SHLQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) -> (RORQ x y)
+(ORQ (SHLQ x y) (ANDQ (SHRQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (ROLQ x y)
+(ORQ (SHRQ x y) (ANDQ (SHLQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (RORQ x y)
-(ORL (SHLL x y) (ANDL (SHRL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) -> (ROLL x y)
-(ORL (SHRL x y) (ANDL (SHLL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) -> (RORL x y)
+(ORL (SHLL x y) (ANDL (SHRL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (ROLL x y)
+(ORL (SHRL x y) (ANDL (SHLL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (RORL x y)
// Help with rotate detection
-(CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32]) -> (FlagLT_ULT)
-(CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst [7] _))) [32]) -> (FlagLT_ULT)
+(CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32]) => (FlagLT_ULT)
+(CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst [7] _))) [32]) => (FlagLT_ULT)
(ORL (SHLL x (AND(Q|L)const y [15]))
(ANDL (SHRW x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])))
@@ -855,69 +857,74 @@
(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
- -> (RORW x y)
+ => (RORW x y)
(ORL (SHLL x (AND(Q|L)const y [ 7]))
(ANDL (SHRB x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])))
(SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])) [ 8]))))
&& v.Type.Size() == 1
- -> (ROLB x y)
+ => (ROLB x y)
(ORL (SHRB x (AND(Q|L)const y [ 7]))
(SHLL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8]))))
&& v.Type.Size() == 1
- -> (RORB x y)
+ => (RORB x y)
// rotate left negative = rotate right
-(ROLQ x (NEG(Q|L) y)) -> (RORQ x y)
-(ROLL x (NEG(Q|L) y)) -> (RORL x y)
-(ROLW x (NEG(Q|L) y)) -> (RORW x y)
-(ROLB x (NEG(Q|L) y)) -> (RORB x y)
+(ROLQ x (NEG(Q|L) y)) => (RORQ x y)
+(ROLL x (NEG(Q|L) y)) => (RORL x y)
+(ROLW x (NEG(Q|L) y)) => (RORW x y)
+(ROLB x (NEG(Q|L) y)) => (RORB x y)
// rotate right negative = rotate left
-(RORQ x (NEG(Q|L) y)) -> (ROLQ x y)
-(RORL x (NEG(Q|L) y)) -> (ROLL x y)
-(RORW x (NEG(Q|L) y)) -> (ROLW x y)
-(RORB x (NEG(Q|L) y)) -> (ROLB x y)
+(RORQ x (NEG(Q|L) y)) => (ROLQ x y)
+(RORL x (NEG(Q|L) y)) => (ROLL x y)
+(RORW x (NEG(Q|L) y)) => (ROLW x y)
+(RORB x (NEG(Q|L) y)) => (ROLB x y)
// rotate by constants
-(ROLQ x (MOV(Q|L)const [c])) -> (ROLQconst [c&63] x)
-(ROLL x (MOV(Q|L)const [c])) -> (ROLLconst [c&31] x)
-(ROLW x (MOV(Q|L)const [c])) -> (ROLWconst [c&15] x)
-(ROLB x (MOV(Q|L)const [c])) -> (ROLBconst [c&7 ] x)
+(ROLQ x (MOV(Q|L)const [c])) => (ROLQconst [int8(c&63)] x)
+(ROLL x (MOV(Q|L)const [c])) => (ROLLconst [int8(c&31)] x)
+(ROLW x (MOV(Q|L)const [c])) => (ROLWconst [int8(c&15)] x)
+(ROLB x (MOV(Q|L)const [c])) => (ROLBconst [int8(c&7) ] x)
-(RORQ x (MOV(Q|L)const [c])) -> (ROLQconst [(-c)&63] x)
-(RORL x (MOV(Q|L)const [c])) -> (ROLLconst [(-c)&31] x)
-(RORW x (MOV(Q|L)const [c])) -> (ROLWconst [(-c)&15] x)
-(RORB x (MOV(Q|L)const [c])) -> (ROLBconst [(-c)&7 ] x)
+(RORQ x (MOV(Q|L)const [c])) => (ROLQconst [int8((-c)&63)] x)
+(RORL x (MOV(Q|L)const [c])) => (ROLLconst [int8((-c)&31)] x)
+(RORW x (MOV(Q|L)const [c])) => (ROLWconst [int8((-c)&15)] x)
+(RORB x (MOV(Q|L)const [c])) => (ROLBconst [int8((-c)&7) ] x)
// Constant shift simplifications
-((SHLQ|SHRQ|SARQ)const x [0]) -> x
-((SHLL|SHRL|SARL)const x [0]) -> x
-((SHRW|SARW)const x [0]) -> x
-((SHRB|SARB)const x [0]) -> x
-((ROLQ|ROLL|ROLW|ROLB)const x [0]) -> x
+((SHLQ|SHRQ|SARQ)const x [0]) => x
+((SHLL|SHRL|SARL)const x [0]) => x
+((SHRW|SARW)const x [0]) => x
+((SHRB|SARB)const x [0]) => x
+((ROLQ|ROLL|ROLW|ROLB)const x [0]) => x
// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
// because the x86 instructions are defined to use all 5 bits of the shift even
// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
// (SHRW x (MOVLconst [24])), but just in case.
-(CMPQ x (MOVQconst [c])) && is32Bit(c) -> (CMPQconst x [c])
-(CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst x [c]))
-(CMPL x (MOVLconst [c])) -> (CMPLconst x [c])
-(CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst x [c]))
-(CMPW x (MOVLconst [c])) -> (CMPWconst x [int64(int16(c))])
-(CMPW (MOVLconst [c]) x) -> (InvertFlags (CMPWconst x [int64(int16(c))]))
-(CMPB x (MOVLconst [c])) -> (CMPBconst x [int64(int8(c))])
-(CMPB (MOVLconst [c]) x) -> (InvertFlags (CMPBconst x [int64(int8(c))]))
+(CMPQ x (MOVQconst [c])) && is32Bit(c) => (CMPQconst x [int32(c)])
+(CMPQ (MOVQconst [c]) x) && is32Bit(c) => (InvertFlags (CMPQconst x [int32(c)]))
+(CMPL x (MOVLconst [c])) => (CMPLconst x [c])
+(CMPL (MOVLconst [c]) x) => (InvertFlags (CMPLconst x [c]))
+(CMPW x (MOVLconst [c])) => (CMPWconst x [int16(c)])
+(CMPW (MOVLconst [c]) x) => (InvertFlags (CMPWconst x [int16(c)]))
+(CMPB x (MOVLconst [c])) => (CMPBconst x [int8(c)])
+(CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
// Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP(Q|L|W|B) x y) && x.ID > y.ID -> (InvertFlags (CMP(Q|L|W|B) y x))
+(CMP(Q|L|W|B) x y) && x.ID > y.ID => (InvertFlags (CMP(Q|L|W|B) y x))
// Using MOVZX instead of AND is cheaper.
-(AND(Q|L)const [ 0xFF] x) -> (MOVBQZX x)
-(AND(Q|L)const [0xFFFF] x) -> (MOVWQZX x)
-(ANDQconst [0xFFFFFFFF] x) -> (MOVLQZX x)
+(AND(Q|L)const [ 0xFF] x) => (MOVBQZX x)
+(AND(Q|L)const [0xFFFF] x) => (MOVWQZX x)
+// This rule is currently invalid because 0xFFFFFFFF is not representable by a signed int32.
+// Commenting out for now, because it also can't trigger because of the is32bit guard on the
+// ANDQconst lowering-rule, above, prevents 0xFFFFFFFF from matching (for the same reason)
+// Using an alternate form of this rule segfaults some binaries because of
+// adverse interactions with other passes.
+// (ANDQconst [0xFFFFFFFF] x) => (MOVLQZX x)
// strength reduction
// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
@@ -928,98 +935,98 @@
// which can require a register-register move
// to preserve the original value,
// so it must be used with care.
-(MUL(Q|L)const [-9] x) -> (NEG(Q|L) (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [-5] x) -> (NEG(Q|L) (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [-3] x) -> (NEG(Q|L) (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [-1] x) -> (NEG(Q|L) x)
-(MUL(Q|L)const [ 0] _) -> (MOV(Q|L)const [0])
-(MUL(Q|L)const [ 1] x) -> x
-(MUL(Q|L)const [ 3] x) -> (LEA(Q|L)2 x x)
-(MUL(Q|L)const [ 5] x) -> (LEA(Q|L)4 x x)
-(MUL(Q|L)const [ 7] x) -> (LEA(Q|L)2 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [ 9] x) -> (LEA(Q|L)8 x x)
-(MUL(Q|L)const [11] x) -> (LEA(Q|L)2 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [13] x) -> (LEA(Q|L)4 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [19] x) -> (LEA(Q|L)2 x (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [21] x) -> (LEA(Q|L)4 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [25] x) -> (LEA(Q|L)8 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [27] x) -> (LEA(Q|L)8 (LEA(Q|L)2 <v.Type> x x) (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [37] x) -> (LEA(Q|L)4 x (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [41] x) -> (LEA(Q|L)8 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [45] x) -> (LEA(Q|L)8 (LEA(Q|L)4 <v.Type> x x) (LEA(Q|L)4 <v.Type> x x))
-(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(c+1) && c >= 15 -> (SUB(Q|L) (SHL(Q|L)const <v.Type> [log2(c+1)] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEA(Q|L)1 (SHL(Q|L)const <v.Type> [log2(c-1)] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo(c-2) && c >= 34 -> (LEA(Q|L)2 (SHL(Q|L)const <v.Type> [log2(c-2)] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo(c-4) && c >= 68 -> (LEA(Q|L)4 (SHL(Q|L)const <v.Type> [log2(c-4)] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo(c-8) && c >= 136 -> (LEA(Q|L)8 (SHL(Q|L)const <v.Type> [log2(c-8)] x) x)
-(MUL(Q|L)const [c] x) && c%3 == 0 && isPowerOfTwo(c/3) -> (SHL(Q|L)const [log2(c/3)] (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [c] x) && c%5 == 0 && isPowerOfTwo(c/5) -> (SHL(Q|L)const [log2(c/5)] (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [c] x) && c%9 == 0 && isPowerOfTwo(c/9) -> (SHL(Q|L)const [log2(c/9)] (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [-9] x) => (NEG(Q|L) (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [-5] x) => (NEG(Q|L) (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [-3] x) => (NEG(Q|L) (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [-1] x) => (NEG(Q|L) x)
+(MUL(Q|L)const [ 0] _) => (MOV(Q|L)const [0])
+(MUL(Q|L)const [ 1] x) => x
+(MUL(Q|L)const [ 3] x) => (LEA(Q|L)2 x x)
+(MUL(Q|L)const [ 5] x) => (LEA(Q|L)4 x x)
+(MUL(Q|L)const [ 7] x) => (LEA(Q|L)2 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [ 9] x) => (LEA(Q|L)8 x x)
+(MUL(Q|L)const [11] x) => (LEA(Q|L)2 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [13] x) => (LEA(Q|L)4 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [19] x) => (LEA(Q|L)2 x (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [21] x) => (LEA(Q|L)4 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [25] x) => (LEA(Q|L)8 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [27] x) => (LEA(Q|L)8 (LEA(Q|L)2 <v.Type> x x) (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [37] x) => (LEA(Q|L)4 x (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [41] x) => (LEA(Q|L)8 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [45] x) => (LEA(Q|L)8 (LEA(Q|L)4 <v.Type> x x) (LEA(Q|L)4 <v.Type> x x))
+(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) && 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)
+(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-8) && c >= 136 => (LEA(Q|L)8 (SHL(Q|L)const <v.Type> [int8(log32(c-8))] x) x)
+(MUL(Q|L)const [c] x) && c%3 == 0 && isPowerOfTwo32(c/3) => (SHL(Q|L)const [int8(log32(c/3))] (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [c] x) && c%5 == 0 && isPowerOfTwo32(c/5) => (SHL(Q|L)const [int8(log32(c/5))] (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [c] x) && c%9 == 0 && isPowerOfTwo32(c/9) => (SHL(Q|L)const [int8(log32(c/9))] (LEA(Q|L)8 <v.Type> x x))
// combine add/shift into LEAQ/LEAL
-(ADD(L|Q) x (SHL(L|Q)const [3] y)) -> (LEA(L|Q)8 x y)
-(ADD(L|Q) x (SHL(L|Q)const [2] y)) -> (LEA(L|Q)4 x y)
-(ADD(L|Q) x (SHL(L|Q)const [1] y)) -> (LEA(L|Q)2 x y)
-(ADD(L|Q) x (ADD(L|Q) y y)) -> (LEA(L|Q)2 x y)
-(ADD(L|Q) x (ADD(L|Q) x y)) -> (LEA(L|Q)2 y x)
+(ADD(L|Q) x (SHL(L|Q)const [3] y)) => (LEA(L|Q)8 x y)
+(ADD(L|Q) x (SHL(L|Q)const [2] y)) => (LEA(L|Q)4 x y)
+(ADD(L|Q) x (SHL(L|Q)const [1] y)) => (LEA(L|Q)2 x y)
+(ADD(L|Q) x (ADD(L|Q) y y)) => (LEA(L|Q)2 x y)
+(ADD(L|Q) x (ADD(L|Q) x y)) => (LEA(L|Q)2 y x)
// combine ADDQ/ADDQconst into LEAQ1/LEAL1
-(ADD(Q|L)const [c] (ADD(Q|L) x y)) -> (LEA(Q|L)1 [c] x y)
-(ADD(Q|L) (ADD(Q|L)const [c] x) y) -> (LEA(Q|L)1 [c] x y)
-(ADD(Q|L)const [c] (SHL(Q|L)const [1] x)) -> (LEA(Q|L)1 [c] x x)
+(ADD(Q|L)const [c] (ADD(Q|L) x y)) => (LEA(Q|L)1 [c] x y)
+(ADD(Q|L) (ADD(Q|L)const [c] x) y) => (LEA(Q|L)1 [c] x y)
+(ADD(Q|L)const [c] (SHL(Q|L)const [1] x)) => (LEA(Q|L)1 [c] x x)
// fold ADDQ/ADDL into LEAQ/LEAL
-(ADD(Q|L)const [c] (LEA(Q|L) [d] {s} x)) && is32Bit(c+d) -> (LEA(Q|L) [c+d] {s} x)
-(LEA(Q|L) [c] {s} (ADD(Q|L)const [d] x)) && is32Bit(c+d) -> (LEA(Q|L) [c+d] {s} x)
-(LEA(Q|L) [c] {s} (ADD(Q|L) x y)) && x.Op != OpSB && y.Op != OpSB -> (LEA(Q|L)1 [c] {s} x y)
-(ADD(Q|L) x (LEA(Q|L) [c] {s} y)) && x.Op != OpSB && y.Op != OpSB -> (LEA(Q|L)1 [c] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L) [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
+(LEA(Q|L) [c] {s} (ADD(Q|L)const [d] x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
+(LEA(Q|L) [c] {s} (ADD(Q|L) x y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
+(ADD(Q|L) x (LEA(Q|L) [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
// fold ADDQconst/ADDLconst into LEAQx/LEALx
-(ADD(Q|L)const [c] (LEA(Q|L)1 [d] {s} x y)) && is32Bit(c+d) -> (LEA(Q|L)1 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)2 [d] {s} x y)) && is32Bit(c+d) -> (LEA(Q|L)2 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)4 [d] {s} x y)) && is32Bit(c+d) -> (LEA(Q|L)4 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)8 [d] {s} x y)) && is32Bit(c+d) -> (LEA(Q|L)8 [c+d] {s} x y)
-(LEA(Q|L)1 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(c+d) && x.Op != OpSB -> (LEA(Q|L)1 [c+d] {s} x y)
-(LEA(Q|L)2 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(c+d) && x.Op != OpSB -> (LEA(Q|L)2 [c+d] {s} x y)
-(LEA(Q|L)2 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(c+2*d) && y.Op != OpSB -> (LEA(Q|L)2 [c+2*d] {s} x y)
-(LEA(Q|L)4 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(c+d) && x.Op != OpSB -> (LEA(Q|L)4 [c+d] {s} x y)
-(LEA(Q|L)4 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(c+4*d) && y.Op != OpSB -> (LEA(Q|L)4 [c+4*d] {s} x y)
-(LEA(Q|L)8 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(c+d) && x.Op != OpSB -> (LEA(Q|L)8 [c+d] {s} x y)
-(LEA(Q|L)8 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(c+8*d) && y.Op != OpSB -> (LEA(Q|L)8 [c+8*d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)1 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)1 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)2 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)2 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)4 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)4 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)8 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)8 [c+d] {s} x y)
+(LEA(Q|L)1 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d)) && x.Op != OpSB => (LEA(Q|L)1 [c+d] {s} x y)
+(LEA(Q|L)2 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d)) && x.Op != OpSB => (LEA(Q|L)2 [c+d] {s} x y)
+(LEA(Q|L)2 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB => (LEA(Q|L)2 [c+2*d] {s} x y)
+(LEA(Q|L)4 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d)) && x.Op != OpSB => (LEA(Q|L)4 [c+d] {s} x y)
+(LEA(Q|L)4 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB => (LEA(Q|L)4 [c+4*d] {s} x y)
+(LEA(Q|L)8 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d)) && x.Op != OpSB => (LEA(Q|L)8 [c+d] {s} x y)
+(LEA(Q|L)8 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB => (LEA(Q|L)8 [c+8*d] {s} x y)
// fold shifts into LEAQx/LEALx
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [1] y)) -> (LEA(Q|L)2 [c] {s} x y)
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [2] y)) -> (LEA(Q|L)4 [c] {s} x y)
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [3] y)) -> (LEA(Q|L)8 [c] {s} x y)
-(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [1] y)) -> (LEA(Q|L)4 [c] {s} x y)
-(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [2] y)) -> (LEA(Q|L)8 [c] {s} x y)
-(LEA(Q|L)4 [c] {s} x (SHL(Q|L)const [1] y)) -> (LEA(Q|L)8 [c] {s} x y)
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)2 [c] {s} x y)
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)4 [c] {s} x y)
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [3] y)) => (LEA(Q|L)8 [c] {s} x y)
+(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)4 [c] {s} x y)
+(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)8 [c] {s} x y)
+(LEA(Q|L)4 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)8 [c] {s} x y)
// reverse ordering of compare instruction
-(SETL (InvertFlags x)) -> (SETG x)
-(SETG (InvertFlags x)) -> (SETL x)
-(SETB (InvertFlags x)) -> (SETA x)
-(SETA (InvertFlags x)) -> (SETB x)
-(SETLE (InvertFlags x)) -> (SETGE x)
-(SETGE (InvertFlags x)) -> (SETLE x)
-(SETBE (InvertFlags x)) -> (SETAE x)
-(SETAE (InvertFlags x)) -> (SETBE x)
-(SETEQ (InvertFlags x)) -> (SETEQ x)
-(SETNE (InvertFlags x)) -> (SETNE x)
-
-(SETLstore [off] {sym} ptr (InvertFlags x) mem) -> (SETGstore [off] {sym} ptr x mem)
-(SETGstore [off] {sym} ptr (InvertFlags x) mem) -> (SETLstore [off] {sym} ptr x mem)
-(SETBstore [off] {sym} ptr (InvertFlags x) mem) -> (SETAstore [off] {sym} ptr x mem)
-(SETAstore [off] {sym} ptr (InvertFlags x) mem) -> (SETBstore [off] {sym} ptr x mem)
-(SETLEstore [off] {sym} ptr (InvertFlags x) mem) -> (SETGEstore [off] {sym} ptr x mem)
-(SETGEstore [off] {sym} ptr (InvertFlags x) mem) -> (SETLEstore [off] {sym} ptr x mem)
-(SETBEstore [off] {sym} ptr (InvertFlags x) mem) -> (SETAEstore [off] {sym} ptr x mem)
-(SETAEstore [off] {sym} ptr (InvertFlags x) mem) -> (SETBEstore [off] {sym} ptr x mem)
-(SETEQstore [off] {sym} ptr (InvertFlags x) mem) -> (SETEQstore [off] {sym} ptr x mem)
-(SETNEstore [off] {sym} ptr (InvertFlags x) mem) -> (SETNEstore [off] {sym} ptr x mem)
+(SETL (InvertFlags x)) => (SETG x)
+(SETG (InvertFlags x)) => (SETL x)
+(SETB (InvertFlags x)) => (SETA x)
+(SETA (InvertFlags x)) => (SETB x)
+(SETLE (InvertFlags x)) => (SETGE x)
+(SETGE (InvertFlags x)) => (SETLE x)
+(SETBE (InvertFlags x)) => (SETAE x)
+(SETAE (InvertFlags x)) => (SETBE x)
+(SETEQ (InvertFlags x)) => (SETEQ x)
+(SETNE (InvertFlags x)) => (SETNE x)
+
+(SETLstore [off] {sym} ptr (InvertFlags x) mem) => (SETGstore [off] {sym} ptr x mem)
+(SETGstore [off] {sym} ptr (InvertFlags x) mem) => (SETLstore [off] {sym} ptr x mem)
+(SETBstore [off] {sym} ptr (InvertFlags x) mem) => (SETAstore [off] {sym} ptr x mem)
+(SETAstore [off] {sym} ptr (InvertFlags x) mem) => (SETBstore [off] {sym} ptr x mem)
+(SETLEstore [off] {sym} ptr (InvertFlags x) mem) => (SETGEstore [off] {sym} ptr x mem)
+(SETGEstore [off] {sym} ptr (InvertFlags x) mem) => (SETLEstore [off] {sym} ptr x mem)
+(SETBEstore [off] {sym} ptr (InvertFlags x) mem) => (SETAEstore [off] {sym} ptr x mem)
+(SETAEstore [off] {sym} ptr (InvertFlags x) mem) => (SETBEstore [off] {sym} ptr x mem)
+(SETEQstore [off] {sym} ptr (InvertFlags x) mem) => (SETEQstore [off] {sym} ptr x mem)
+(SETNEstore [off] {sym} ptr (InvertFlags x) mem) => (SETNEstore [off] {sym} ptr x mem)
// sign extended loads
// Note: The combined instruction must end up in the same block
@@ -1029,100 +1036,100 @@
// Make sure we don't combine these ops if the load has another use.
// This prevents a single load from being split into multiple loads
// which then might return different values. See test/atomicload.go.
-(MOVBQSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVLQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
-(MOVLQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
-(MOVLQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
-(MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
-
-(MOVLQZX x) && zeroUpper32Bits(x,3) -> x
-(MOVWQZX x) && zeroUpper48Bits(x,3) -> x
-(MOVBQZX x) && zeroUpper56Bits(x,3) -> x
+(MOVBQSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVLQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
+(MOVLQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
+(MOVLQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
+(MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
+
+(MOVLQZX x) && zeroUpper32Bits(x,3) => x
+(MOVWQZX x) && zeroUpper48Bits(x,3) => x
+(MOVBQZX x) && zeroUpper56Bits(x,3) => x
// 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) -> (MOVBQZX x)
-(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWQZX x)
-(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVLQZX x)
-(MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-(MOVBQSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBQSX x)
-(MOVWQSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWQSX x)
-(MOVLQSXload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVLQSX x)
+(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQZX x)
+(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQZX x)
+(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQZX x)
+(MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+(MOVBQSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQSX x)
+(MOVWQSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQSX x)
+(MOVLQSXload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQSX x)
// Fold extensions and ANDs together.
-(MOVBQZX (ANDLconst [c] x)) -> (ANDLconst [c & 0xff] x)
-(MOVWQZX (ANDLconst [c] x)) -> (ANDLconst [c & 0xffff] x)
-(MOVLQZX (ANDLconst [c] x)) -> (ANDLconst [c] x)
-(MOVBQSX (ANDLconst [c] x)) && c & 0x80 == 0 -> (ANDLconst [c & 0x7f] x)
-(MOVWQSX (ANDLconst [c] x)) && c & 0x8000 == 0 -> (ANDLconst [c & 0x7fff] x)
-(MOVLQSX (ANDLconst [c] x)) && c & 0x80000000 == 0 -> (ANDLconst [c & 0x7fffffff] x)
+(MOVBQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xff] x)
+(MOVWQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xffff] x)
+(MOVLQZX (ANDLconst [c] x)) => (ANDLconst [c] x)
+(MOVBQSX (ANDLconst [c] x)) && c & 0x80 == 0 => (ANDLconst [c & 0x7f] x)
+(MOVWQSX (ANDLconst [c] x)) && c & 0x8000 == 0 => (ANDLconst [c & 0x7fff] x)
+(MOVLQSX (ANDLconst [c] x)) && uint32(c) & 0x80000000 == 0 => (ANDLconst [c & 0x7fffffff] x)
// Don't extend before storing
-(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) -> (MOVLstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWQSX x) mem) -> (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBQSX x) mem) -> (MOVBstore [off] {sym} ptr x mem)
-(MOVLstore [off] {sym} ptr (MOVLQZX x) mem) -> (MOVLstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWQZX x) mem) -> (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBQZX x) mem) -> (MOVBstore [off] {sym} ptr x mem)
+(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) => (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQSX x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQSX x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVLstore [off] {sym} ptr (MOVLQZX x) mem) => (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQZX x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQZX x) mem) => (MOVBstore [off] {sym} ptr x mem)
// fold constants into memory operations
// Note that this is not always a good idea because if not all the uses of
// the ADDQconst get eliminated, we still have to compute the ADDQconst and we now
// have potentially two live values (ptr and (ADDQconst [off] ptr)) instead of one.
// Nevertheless, let's do it!
-(MOV(Q|L|W|B|SS|SD|O)load [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(off1+off2) ->
+(MOV(Q|L|W|B|SS|SD|O)load [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
(MOV(Q|L|W|B|SS|SD|O)load [off1+off2] {sym} ptr mem)
-(MOV(Q|L|W|B|SS|SD|O)store [off1] {sym} (ADDQconst [off2] ptr) val mem) && is32Bit(off1+off2) ->
+(MOV(Q|L|W|B|SS|SD|O)store [off1] {sym} (ADDQconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) =>
(MOV(Q|L|W|B|SS|SD|O)store [off1+off2] {sym} ptr val mem)
-(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(off1+off2) ->
+(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {sym} base val mem)
-((ADD|SUB|AND|OR|XOR)Qload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(off1+off2) ->
+((ADD|SUB|AND|OR|XOR)Qload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {sym} val base mem)
-((ADD|SUB|AND|OR|XOR)Lload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(off1+off2) ->
+((ADD|SUB|AND|OR|XOR)Lload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
-(CMP(Q|L|W|B)load [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(off1+off2) ->
+(CMP(Q|L|W|B)load [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
(CMP(Q|L|W|B)load [off1+off2] {sym} base val mem)
-(CMP(Q|L|W|B)constload [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd(off2) ->
- (CMP(Q|L|W|B)constload [ValAndOff(valoff1).add(off2)] {sym} base mem)
+(CMP(Q|L|W|B)constload [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+ (CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(off1+off2) ->
+((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
-((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(off1+off2) ->
+((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd(off2) ->
- ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
-((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd(off2) ->
- ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(off1+off2) ->
+((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+ ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+ ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {sym} base val mem)
-((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(off1+off2) ->
+((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {sym} base val mem)
// Fold constants into stores.
-(MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validValAndOff(c,off) ->
- (MOVQstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
-(MOVLstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) && validOff(off) ->
- (MOVLstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) && validOff(off) ->
- (MOVWstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) && validOff(off) ->
- (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
+(MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validVal(c) =>
+ (MOVQstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+(MOVLstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+ (MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+ (MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+ (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
// Fold address offsets into constant stores.
-(MOV(Q|L|W|B)storeconst [sc] {s} (ADDQconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) ->
- (MOV(Q|L|W|B)storeconst [ValAndOff(sc).add(off)] {s} ptr mem)
+(MOV(Q|L|W|B)storeconst [sc] {s} (ADDQconst [off] ptr) mem) && ValAndOff(sc).canAdd32(off) =>
+ (MOV(Q|L|W|B)storeconst [ValAndOff(sc).addOffset32(off)] {s} ptr mem)
// 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.
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
index c29e7f7edf..311067e87a 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules
@@ -132,65 +132,65 @@
// we compare to 64 to ensure Go semantics for large shifts
// Rules about rotates with non-const shift are based on the following rules,
// if the following rules change, please also modify the rules based on them.
-(Lsh64x64 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh64x32 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh64x8 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Lsh32x64 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh32x32 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh32x8 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Lsh16x64 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh16x32 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh16x8 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Lsh8x64 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh8x32 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh8x8 <t> x y) => (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Rsh64Ux64 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh64Ux32 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh64Ux8 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Rsh32Ux64 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh32Ux32 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh32Ux8 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Rsh16Ux64 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh16Ux32 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh16Ux8 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Rsh8Ux64 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh8Ux32 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh8Ux8 <t> x y) => (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
-
-(Rsh64x64 x y) => (SRA x (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh64x32 x y) => (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh64x16 x y) => (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh64x8 x y) => (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
-
-(Rsh32x64 x y) => (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh32x32 x y) => (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh32x16 x y) => (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh32x8 x y) => (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
-
-(Rsh16x64 x y) => (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh16x32 x y) => (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh16x16 x y) => (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh16x8 x y) => (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
-
-(Rsh8x64 x y) => (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh8x32 x y) => (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh8x16 x y) => (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh8x8 x y) => (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+(Lsh64x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh64x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh64x8 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Lsh32x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh32x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh32x8 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Lsh16x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh16x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh16x8 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Lsh8x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh8x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh8x8 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Rsh64Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh64Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh64Ux8 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Rsh32Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh32Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh32Ux8 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Rsh16Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh16Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh16Ux8 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Rsh8Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh8Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh8Ux8 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+
+(Rsh64x64 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh64x32 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh64x16 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh64x8 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+
+(Rsh32x64 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh32x32 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh32x16 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh32x8 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+
+(Rsh16x64 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh16x32 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh16x16 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh16x8 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+
+(Rsh8x64 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh8x32 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh8x16 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh8x8 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
// constants
(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
@@ -315,8 +315,8 @@
(FCMPD (FMOVDconst [0]) x) => (InvertFlags (FCMPD0 x))
// CSEL needs a flag-generating argument. Synthesize a CMPW if necessary.
-(CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL {boolval.Op} x y flagArg(boolval))
-(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL {OpARM64NotEqual} x y (CMPWconst [0] boolval))
+(CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL [boolval.Op] x y flagArg(boolval))
+(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVDaddr [int32(off)] ptr)
(OffPtr [off] ptr) => (ADDconst [off] ptr)
@@ -1324,8 +1324,8 @@
(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.(Op))} y flag)
+(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))
@@ -1481,8 +1481,8 @@
(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
// absorb InvertFlags into CSEL(0)
-(CSEL {cc} x y (InvertFlags cmp)) => (CSEL {arm64Invert(cc)} x y cmp)
-(CSEL0 {cc} x (InvertFlags cmp)) => (CSEL0 {arm64Invert(cc)} x cmp)
+(CSEL [cc] x y (InvertFlags cmp)) => (CSEL [arm64Invert(cc)] x y cmp)
+(CSEL0 [cc] x (InvertFlags cmp)) => (CSEL0 [arm64Invert(cc)] x cmp)
// absorb flag constants into boolean values
(Equal (FlagConstant [fc])) => (MOVDconst [b2i(fc.eq())])
@@ -1517,20 +1517,20 @@
(MOVBUreg x) && x.Type.IsBoolean() => (MOVDreg x)
// absorb flag constants into conditional instructions
-(CSEL {cc} x _ flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSEL {cc} _ y flag) && ccARM64Eval(cc, flag) < 0 => y
-(CSEL0 {cc} x flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSEL0 {cc} _ flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
+(CSEL [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSEL [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => y
+(CSEL0 [cc] x flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSEL0 [cc] _ flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
// absorb flags back into boolean CSEL
-(CSEL {cc} x y (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
- (CSEL {boolval.Op} x y flagArg(boolval))
-(CSEL {cc} x y (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
- (CSEL {arm64Negate(boolval.Op)} x y flagArg(boolval))
-(CSEL0 {cc} x (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
- (CSEL0 {boolval.Op} x flagArg(boolval))
-(CSEL0 {cc} x (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
- (CSEL0 {arm64Negate(boolval.Op)} x flagArg(boolval))
+(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
+ (CSEL [boolval.Op] x y flagArg(boolval))
+(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
+ (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
+(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
+ (CSEL0 [boolval.Op] x flagArg(boolval))
+(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
+ (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
// absorb shifts into ops
(NEG x:(SLLconst [c] y)) && clobberIfDead(x) => (NEGshiftLL [c] y)
@@ -1691,11 +1691,11 @@
// "|" can also be "^" or "+".
// As arm64 does not have a ROL instruction, so ROL(x, y) is replaced by ROR(x, -y).
((ADD|OR|XOR) (SLL x (ANDconst <t> [63] y))
- (CSEL0 <typ.UInt64> {cc} (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
+ (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
(CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))))) && cc == OpARM64LessThanU
=> (ROR x (NEG <t> y))
((ADD|OR|XOR) (SRL <typ.UInt64> x (ANDconst <t> [63] y))
- (CSEL0 <typ.UInt64> {cc} (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
+ (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
(CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))))) && cc == OpARM64LessThanU
=> (ROR x y)
@@ -1705,11 +1705,11 @@
// "|" can also be "^" or "+".
// As arm64 does not have a ROLW instruction, so ROLW(x, y) is replaced by RORW(x, -y).
((ADD|OR|XOR) (SLL x (ANDconst <t> [31] y))
- (CSEL0 <typ.UInt32> {cc} (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
+ (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
(CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))))) && cc == OpARM64LessThanU
=> (RORW x (NEG <t> y))
((ADD|OR|XOR) (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y))
- (CSEL0 <typ.UInt32> {cc} (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
+ (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
(CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))))) && cc == OpARM64LessThanU
=> (RORW x y)
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
index 2424e67e20..e9af261a6a 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
@@ -467,8 +467,8 @@ func init() {
// conditional instructions; auxint is
// one of the arm64 comparison pseudo-ops (LessThan, LessThanU, etc.)
- {name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"}, // aux(flags) ? arg0 : arg1
- {name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"}, // aux(flags) ? arg0 : 0
+ {name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"}, // auxint(flags) ? arg0 : arg1
+ {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
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index 14942d50f9..e5fb1e98c2 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -110,13 +110,21 @@
// Rotate generation with non-const shift
// these match patterns from math/bits/RotateLeft[32|64], but there could be others
(ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+(ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
(XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+(XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+
+(ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
(ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+(XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
(XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+
// Lowering rotates
(RotateLeft32 x y) => (ROTLW x y)
(RotateLeft64 x y) => (ROTL x y)
@@ -192,11 +200,15 @@
(Rsh64Ux64 x (AND y (MOVDconst [63]))) => (SRD x (ANDconst <typ.Int64> [63] y))
(Rsh64Ux64 x (ANDconst <typ.UInt> [63] y)) => (SRD x (ANDconst <typ.UInt> [63] y))
(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) => (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))) => (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) => (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63])))) => (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
(Rsh64x64 x (AND y (MOVDconst [63]))) => (SRAD x (ANDconst <typ.Int64> [63] y))
(Rsh64x64 x (ANDconst <typ.UInt> [63] y)) => (SRAD x (ANDconst <typ.UInt> [63] y))
(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) => (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64x64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))) => (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) => (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
+(Rsh64x64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63])))) => (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
(Lsh64x64 x y) => (SLD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
(Rsh64x64 x y) => (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
@@ -208,12 +220,16 @@
(Rsh32Ux64 x (AND y (MOVDconst [31]))) => (SRW x (ANDconst <typ.Int32> [31] y))
(Rsh32Ux64 x (ANDconst <typ.UInt> [31] y)) => (SRW x (ANDconst <typ.UInt> [31] y))
(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) => (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))) => (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) => (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31])))) => (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
(Rsh32x64 x (AND y (MOVDconst [31]))) => (SRAW x (ANDconst <typ.Int32> [31] y))
(Rsh32x64 x (ANDconst <typ.UInt> [31] y)) => (SRAW x (ANDconst <typ.UInt> [31] y))
(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) => (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32x64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))) => (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) => (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
+(Rsh32x64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31])))) => (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
(Rsh32x64 x y) => (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
(Rsh32Ux64 x y) => (SRW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
@@ -276,18 +292,11 @@
(Rsh8Ux8 x y) => (SRW (ZeroExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
(Lsh8x8 x y) => (SLW x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
-// Cleaning up shift ops when input is masked
-(MaskIfNotCarry (ADDconstForCarry [c] (ANDconst [d] _))) && c < 0 && d > 0 && int64(c) + d < 0 => (MOVDconst [-1])
+// Cleaning up shift ops
(ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPU (ANDconst [d] y) (MOVDconst [c]))) && c >= d => (ANDconst [d] y)
(ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPUconst [c] (ANDconst [d] y))) && c >= d => (ANDconst [d] y)
(ORN x (MOVDconst [-1])) => x
-(ADDconstForCarry [c] (MOVDconst [d])) && c < 0 && (c < 0 || int64(c) + d >= 0) => (FlagCarryClear)
-(ADDconstForCarry [c] (MOVDconst [d])) && c < 0 && c >= 0 && int64(c) + d < 0 => (FlagCarrySet)
-
-(MaskIfNotCarry (FlagCarrySet)) => (MOVDconst [0])
-(MaskIfNotCarry (FlagCarryClear)) => (MOVDconst [-1])
-
(S(RAD|RD|LD) x (MOVDconst [c])) => (S(RAD|RD|LD)const [c&63 | (c>>6&1*63)] x)
(S(RAW|RW|LW) x (MOVDconst [c])) => (S(RAW|RW|LW)const [c&31 | (c>>5&1*31)] x)
@@ -306,8 +315,8 @@
(Ctz16 x) => (POPCNTW (MOVHZreg (ANDN <typ.Int16> (ADDconst <typ.Int16> [-1] x) x)))
(Ctz8 x) => (POPCNTB (MOVBZreg (ANDN <typ.UInt8> (ADDconst <typ.UInt8> [-1] x) x)))
-(BitLen64 x) => (SUB (MOVDconst [64]) (CNTLZD <typ.Int> x))
-(BitLen32 x) => (SUB (MOVDconst [32]) (CNTLZW <typ.Int> x))
+(BitLen64 x) => (SUBFCconst [64] (CNTLZD <typ.Int> x))
+(BitLen32 x) => (SUBFCconst [32] (CNTLZW <typ.Int> x))
(PopCount64 ...) => (POPCNTD ...)
(PopCount32 x) => (POPCNTW (MOVWZreg x))
@@ -777,10 +786,19 @@
(ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) => (ADDconst [c+d] x)
(ADDconst [0] x) => x
(SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x)
-// TODO deal with subtract-from-const
(ADDconst [c] (MOVDaddr [d] {sym} x)) && is32Bit(c+int64(d)) => (MOVDaddr [int32(c+int64(d))] {sym} x)
+// Subtract from (with carry, but ignored) constant.
+// Note, these clobber the carry bit.
+(SUB (MOVDconst [c]) x) && is32Bit(c) => (SUBFCconst [c] x)
+(SUBFCconst [c] (NEG x)) => (ADDconst [c] x)
+(SUBFCconst [c] (SUBFCconst [d] x)) && is32Bit(c-d) => (ADDconst [c-d] x)
+(SUBFCconst [0] x) => (NEG x)
+(ADDconst [c] (SUBFCconst [d] x)) && is32Bit(c+d) => (SUBFCconst [c+d] x)
+(NEG (ADDconst [c] x)) && is32Bit(-c) => (SUBFCconst [-c] x)
+(NEG (SUBFCconst [c] x)) && is32Bit(-c) => (ADDconst [-c] x)
+
// Use register moves instead of stores and loads to move int<=>float values
// Common with math Float64bits, Float64frombits
(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _)) => (MFVSRD x)
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
index 825d0faf34..44f6a74c63 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
@@ -175,6 +175,7 @@ func init() {
{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true}, // arg0+arg1
{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true}, // arg0+arg1
{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"}, // arg0-arg1
+ {name: "SUBFCconst", argLength: 1, reg: gp11, asm: "SUBC", aux: "Int64"}, // auxInt - arg0 (with carry)
{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"}, // arg0-arg1
{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"}, // arg0-arg1
@@ -206,9 +207,7 @@ 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
- {name: "LoweredAdd64Carry", argLength: 3, reg: gp32, resultNotInArgs: true}, // arg0 + arg1 + carry, returns (sum, carry)
- {name: "ADDconstForCarry", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, aux: "Int16", asm: "ADDC", typ: "Flags"}, // _, carry := arg0 + auxint
- {name: "MaskIfNotCarry", argLength: 1, reg: crgp, asm: "ADDME", typ: "Int64"}, // carry - 1 (if carry then 0 else -1)
+ {name: "LoweredAdd64Carry", argLength: 3, reg: gp32, resultNotInArgs: true}, // arg0 + arg1 + carry, returns (sum, carry)
{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
@@ -674,11 +673,9 @@ func init() {
// These ops are for temporary use by rewrite rules. They
// cannot appear in the generated assembly.
- {name: "FlagEQ"}, // equal
- {name: "FlagLT"}, // signed < or unsigned <
- {name: "FlagGT"}, // signed > or unsigned >
- {name: "FlagCarrySet"}, // carry flag set
- {name: "FlagCarryClear"}, // carry flag clear
+ {name: "FlagEQ"}, // equal
+ {name: "FlagLT"}, // signed < or unsigned <
+ {name: "FlagGT"}, // signed > or unsigned >
}
blocks := []blockData{
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index 5e4c436ca1..e564f638d3 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -498,27 +498,19 @@
// Remove zero extensions after zero extending load.
// Note: take care that if x is spilled it is restored correctly.
(MOV(B|H|W)Zreg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
-(MOV(B|H|W)Zreg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
(MOV(H|W)Zreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
-(MOV(H|W)Zreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
(MOVWZreg x:(MOVWZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) => x
-(MOVWZreg x:(MOVWZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) => x
// Remove sign extensions after sign extending load.
// Note: take care that if x is spilled it is restored correctly.
(MOV(B|H|W)reg x:(MOVBload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-(MOV(B|H|W)reg x:(MOVBloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
(MOV(H|W)reg x:(MOVHload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-(MOV(H|W)reg x:(MOVHloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
(MOVWreg x:(MOVWload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-(MOVWreg x:(MOVWloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
// Remove sign extensions after zero extending load.
// These type checks are probably unnecessary but do them anyway just in case.
(MOV(H|W)reg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
-(MOV(H|W)reg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
(MOVWreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
-(MOVWreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
// Fold sign and zero extensions into loads.
//
@@ -538,14 +530,6 @@
&& x.Uses == 1
&& clobber(x)
=> @x.Block (MOV(B|H|W)load <t> [o] {s} p mem)
-(MOV(B|H|W)Zreg <t> x:(MOV(B|H|W)loadidx [o] {s} p i mem))
- && x.Uses == 1
- && clobber(x)
- => @x.Block (MOV(B|H|W)Zloadidx <t> [o] {s} p i mem)
-(MOV(B|H|W)reg <t> x:(MOV(B|H|W)Zloadidx [o] {s} p i mem))
- && x.Uses == 1
- && clobber(x)
- => @x.Block (MOV(B|H|W)loadidx <t> [o] {s} p i mem)
// Remove zero extensions after argument load.
(MOVBZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() == 1 => x
@@ -641,41 +625,37 @@
(BRC {c} (CMPWUconst x [y]) yes no) && y == int32( int8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CIJ {c} x [ int8(y)] yes no)
// Fold constants into instructions.
-(ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x)
-(ADDW x (MOVDconst [c])) -> (ADDWconst [int64(int32(c))] x)
+(ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [int32(c)] x)
+(ADDW x (MOVDconst [c])) => (ADDWconst [int32(c)] x)
-(SUB x (MOVDconst [c])) && is32Bit(c) -> (SUBconst x [c])
-(SUB (MOVDconst [c]) x) && is32Bit(c) -> (NEG (SUBconst <v.Type> x [c]))
-(SUBW x (MOVDconst [c])) -> (SUBWconst x [int64(int32(c))])
-(SUBW (MOVDconst [c]) x) -> (NEGW (SUBWconst <v.Type> x [int64(int32(c))]))
+(SUB x (MOVDconst [c])) && is32Bit(c) => (SUBconst x [int32(c)])
+(SUB (MOVDconst [c]) x) && is32Bit(c) => (NEG (SUBconst <v.Type> x [int32(c)]))
+(SUBW x (MOVDconst [c])) => (SUBWconst x [int32(c)])
+(SUBW (MOVDconst [c]) x) => (NEGW (SUBWconst <v.Type> x [int32(c)]))
-(MULLD x (MOVDconst [c])) && is32Bit(c) -> (MULLDconst [c] x)
-(MULLW x (MOVDconst [c])) -> (MULLWconst [int64(int32(c))] x)
+(MULLD x (MOVDconst [c])) && is32Bit(c) => (MULLDconst [int32(c)] x)
+(MULLW x (MOVDconst [c])) => (MULLWconst [int32(c)] x)
// NILF instructions leave the high 32 bits unchanged which is
// 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> [int64(int32(c))] x))
-(ANDW x (MOVDconst [c])) -> (ANDWconst [int64(int32(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)
-(ANDWconst [c] (ANDWconst [d] x)) => (ANDWconst [c & d] x)
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c & d] x)
+((AND|ANDW)const [c] ((AND|ANDW)const [d] x)) => ((AND|ANDW)const [c&d] x)
-(OR x (MOVDconst [c])) && isU32Bit(c) => (ORconst [c] x)
-(ORW x (MOVDconst [c])) -> (ORWconst [int64(int32(c))] x)
-
-(XOR x (MOVDconst [c])) && isU32Bit(c) => (XORconst [c] x)
-(XORW x (MOVDconst [c])) -> (XORWconst [int64(int32(c))] x)
+((OR|XOR) x (MOVDconst [c])) && isU32Bit(c) => ((OR|XOR)const [c] x)
+((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 [c&63])
+ => (S(LD|RD|RAD|LW|RW|RAW)const x [int8(c&63)])
// Shifts only use the rightmost 6 bits of the shift value.
(S(LD|RD|RAD|LW|RW|RAW) x (AND (MOVDconst [c]) y))
- -> (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [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)
(SLD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLD x y)
@@ -686,8 +666,8 @@
(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
// Constant rotate generation
-(RLL x (MOVDconst [c])) -> (RLLconst x [c&31])
-(RLLG x (MOVDconst [c])) -> (RLLGconst x [c&63])
+(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)])
+(RLLG x (MOVDconst [c])) => (RLLGconst x [int8(c&63)])
(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)
@@ -697,14 +677,17 @@
( 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)
-(CMP x (MOVDconst [c])) && is32Bit(c) -> (CMPconst x [c])
-(CMP (MOVDconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPconst x [c]))
-(CMPW x (MOVDconst [c])) -> (CMPWconst x [int64(int32(c))])
-(CMPW (MOVDconst [c]) x) -> (InvertFlags (CMPWconst x [int64(int32(c))]))
-(CMPU x (MOVDconst [c])) && isU32Bit(c) -> (CMPUconst x [int64(int32(c))])
-(CMPU (MOVDconst [c]) x) && isU32Bit(c) -> (InvertFlags (CMPUconst x [int64(int32(c))]))
-(CMPWU x (MOVDconst [c])) -> (CMPWUconst x [int64(int32(c))])
-(CMPWU (MOVDconst [c]) x) -> (InvertFlags (CMPWUconst x [int64(int32(c))]))
+// Signed 64-bit comparison with immediate.
+(CMP x (MOVDconst [c])) && is32Bit(c) => (CMPconst x [int32(c)])
+(CMP (MOVDconst [c]) x) && is32Bit(c) => (InvertFlags (CMPconst x [int32(c)]))
+
+// Unsigned 64-bit comparison with immediate.
+(CMPU x (MOVDconst [c])) && isU32Bit(c) => (CMPUconst x [int32(c)])
+(CMPU (MOVDconst [c]) x) && isU32Bit(c) => (InvertFlags (CMPUconst x [int32(c)]))
+
+// Signed and unsigned 32-bit comparison with immediate.
+(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)]))
// 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))
@@ -752,14 +735,14 @@
(SL(D|W)const <t> x [int8(log32(-c+(-c&^(-c-1))))]))
// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
-(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(c+d) -> (MOVDaddr [c+d] {s} x)
-(ADDconst [c] (MOVDaddr [d] {s} x)) && x.Op != OpSB && is20Bit(c+d) -> (MOVDaddr [c+d] {s} x)
-(ADD idx (MOVDaddr [c] {s} ptr)) && ptr.Op != OpSB && idx.Op != OpSB => (MOVDaddridx [c] {s} ptr idx)
+(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
+(ADDconst [c] (MOVDaddr [d] {s} x)) && x.Op != OpSB && is20Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
+(ADD idx (MOVDaddr [c] {s} ptr)) && ptr.Op != OpSB => (MOVDaddridx [c] {s} ptr idx)
// fold ADDconst into MOVDaddrx
-(ADDconst [c] (MOVDaddridx [d] {s} x y)) && is20Bit(c+d) -> (MOVDaddridx [c+d] {s} x y)
-(MOVDaddridx [c] {s} (ADDconst [d] x) y) && is20Bit(c+d) && x.Op != OpSB -> (MOVDaddridx [c+d] {s} x y)
-(MOVDaddridx [c] {s} x (ADDconst [d] y)) && is20Bit(c+d) && y.Op != OpSB -> (MOVDaddridx [c+d] {s} x y)
+(ADDconst [c] (MOVDaddridx [d] {s} x y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
+(MOVDaddridx [c] {s} (ADDconst [d] x) y) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
+(MOVDaddridx [c] {s} x (ADDconst [d] y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
// reverse ordering of compare instruction
(LOCGR {c} x y (InvertFlags cmp)) => (LOCGR {c.ReverseComparison()} x y cmp)
@@ -799,11 +782,11 @@
// 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> [c]) 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> [c]) x))
-(CPSDR y (FMOVDconst [c])) && c & -1<<63 == 0 -> (LPDFR y)
-(CPSDR y (FMOVDconst [c])) && c & -1<<63 != 0 -> (LNDFR y)
+(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))
+(CPSDR y (FMOVDconst [c])) && !math.Signbit(c) => (LPDFR y)
+(CPSDR y (FMOVDconst [c])) && math.Signbit(c) => (LNDFR y)
// absorb negations into set/clear sign bit
(FNEG (LPDFR x)) => (LNDFR x)
@@ -832,216 +815,131 @@
// the ADDconst get eliminated, we still have to compute the ADDconst and we now
// have potentially two live values (ptr and (ADDconst [off] ptr)) instead of one.
// Nevertheless, let's do it!
-(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVDload [off1+off2] {sym} ptr mem)
-(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVWload [off1+off2] {sym} ptr mem)
-(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVHload [off1+off2] {sym} ptr mem)
-(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVBload [off1+off2] {sym} ptr mem)
-(MOVWZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVWZload [off1+off2] {sym} ptr mem)
-(MOVHZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVHZload [off1+off2] {sym} ptr mem)
-(MOVBZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (MOVBZload [off1+off2] {sym} ptr mem)
-(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (FMOVSload [off1+off2] {sym} ptr mem)
-(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(off1+off2) -> (FMOVDload [off1+off2] {sym} ptr mem)
-
-(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (MOVDstore [off1+off2] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (MOVWstore [off1+off2] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (MOVHstore [off1+off2] {sym} ptr val mem)
-(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} ptr val mem)
-(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (FMOVSstore [off1+off2] {sym} ptr val mem)
-(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(off1+off2) -> (FMOVDstore [off1+off2] {sym} ptr val mem)
-
-(ADDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ADDload [off1+off2] {sym} x ptr mem)
-(ADDWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ADDWload [off1+off2] {sym} x ptr mem)
-(MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (MULLDload [off1+off2] {sym} x ptr mem)
-(MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (MULLWload [off1+off2] {sym} x ptr mem)
-(SUBload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (SUBload [off1+off2] {sym} x ptr mem)
-(SUBWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (SUBWload [off1+off2] {sym} x ptr mem)
-
-(ANDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ANDload [off1+off2] {sym} x ptr mem)
-(ANDWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ANDWload [off1+off2] {sym} x ptr mem)
-(ORload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ORload [off1+off2] {sym} x ptr mem)
-(ORWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (ORWload [off1+off2] {sym} x ptr mem)
-(XORload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (XORload [off1+off2] {sym} x ptr mem)
-(XORWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(off1+off2) -> (XORWload [off1+off2] {sym} x ptr mem)
+(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDload [off1+off2] {sym} ptr mem)
+(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWload [off1+off2] {sym} ptr mem)
+(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHload [off1+off2] {sym} ptr mem)
+(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBload [off1+off2] {sym} ptr mem)
+(MOVWZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWZload [off1+off2] {sym} ptr mem)
+(MOVHZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHZload [off1+off2] {sym} ptr mem)
+(MOVBZload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBZload [off1+off2] {sym} ptr mem)
+(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSload [off1+off2] {sym} ptr mem)
+(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDload [off1+off2] {sym} ptr mem)
+
+(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDstore [off1+off2] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWstore [off1+off2] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHstore [off1+off2] {sym} ptr val mem)
+(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBstore [off1+off2] {sym} ptr val mem)
+(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSstore [off1+off2] {sym} ptr val mem)
+(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDstore [off1+off2] {sym} ptr val mem)
+
+(ADDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDload [off1+off2] {sym} x ptr mem)
+(ADDWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDWload [off1+off2] {sym} x ptr mem)
+(MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLDload [off1+off2] {sym} x ptr mem)
+(MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLWload [off1+off2] {sym} x ptr mem)
+(SUBload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBload [off1+off2] {sym} x ptr mem)
+(SUBWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBWload [off1+off2] {sym} x ptr mem)
+
+(ANDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDload [off1+off2] {sym} x ptr mem)
+(ANDWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDWload [off1+off2] {sym} x ptr mem)
+(ORload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORload [off1+off2] {sym} x ptr mem)
+(ORWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORWload [off1+off2] {sym} x ptr mem)
+(XORload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORload [off1+off2] {sym} x ptr mem)
+(XORWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORWload [off1+off2] {sym} x ptr mem)
// Fold constants into stores.
-(MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB ->
- (MOVDstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB ->
- (MOVWstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVDconst [c]) mem) && isU12Bit(off) && ptr.Op != OpSB ->
- (MOVHstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOVDconst [c]) mem) && is20Bit(off) && ptr.Op != OpSB ->
- (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
+(MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+ (MOVDstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+ (MOVWstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
+(MOVHstore [off] {sym} ptr (MOVDconst [c]) mem) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+ (MOVHstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOVDconst [c]) mem) && is20Bit(int64(off)) && ptr.Op != OpSB =>
+ (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
// Fold address offsets into constant stores.
-(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(ValAndOff(sc).Off()+off) ->
- (MOVDstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
-(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(ValAndOff(sc).Off()+off) ->
- (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
-(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(ValAndOff(sc).Off()+off) ->
- (MOVHstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
-(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(ValAndOff(sc).Off()+off) ->
- (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+ (MOVDstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+ (MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off()+int64(off)) =>
+ (MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(sc.Off()+int64(off)) =>
+ (MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem)
// Merge address calculations into loads and stores.
// Offsets from SB must not be merged into unaligned memory accesses because
// 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(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) ->
- (MOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVWZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) ->
- (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) ->
- (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOVWload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) ->
- (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) ->
- (MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOVDstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) ->
- (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVWstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) ->
- (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVHstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) ->
- (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-
-(ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+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(o1+o2) && canMergeSym(s1, s2) -> (XORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(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)
+(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)
+(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)
+(MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+ (MOVBZload [off1+off2] {mergeSymTyped(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)
+(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+ (FMOVDload [off1+off2] {mergeSymTyped(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)
+(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)
+(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+ (MOVBload [off1+off2] {mergeSymTyped(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)
+(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)
+(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)
+(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)
+(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)
+(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)
+
+(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)
+
+(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)
// 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) && ValAndOff(sc).canAdd(off) ->
- (MOVDstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) ->
- (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) ->
- (MOVHstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) ->
- (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
-
-// generating indexed loads and stores
-(MOVBZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVBload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVHZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVHZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVHload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVHloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVWZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVWZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVWload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVWloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(MOVDload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVDloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(FMOVSload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVSloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-(FMOVDload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVDloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
-
-(MOVBstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVBstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-(MOVHstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVHstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-(MOVWstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVWstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-(MOVDstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (MOVDstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-(FMOVSstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVSstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-(FMOVDstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
- (FMOVDstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
-
-(MOVBZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVBZloadidx [off] {sym} ptr idx mem)
-(MOVBload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVBloadidx [off] {sym} ptr idx mem)
-(MOVHZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVHZloadidx [off] {sym} ptr idx mem)
-(MOVHload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVHloadidx [off] {sym} ptr idx mem)
-(MOVWZload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVWZloadidx [off] {sym} ptr idx mem)
-(MOVWload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVWloadidx [off] {sym} ptr idx mem)
-(MOVDload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (MOVDloadidx [off] {sym} ptr idx mem)
-(FMOVSload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (FMOVSloadidx [off] {sym} ptr idx mem)
-(FMOVDload [off] {sym} (ADD ptr idx) mem) && ptr.Op != OpSB => (FMOVDloadidx [off] {sym} ptr idx mem)
-
-(MOVBstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (MOVBstoreidx [off] {sym} ptr idx val mem)
-(MOVHstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (MOVHstoreidx [off] {sym} ptr idx val mem)
-(MOVWstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (MOVWstoreidx [off] {sym} ptr idx val mem)
-(MOVDstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (MOVDstoreidx [off] {sym} ptr idx val mem)
-(FMOVSstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (FMOVSstoreidx [off] {sym} ptr idx val mem)
-(FMOVDstore [off] {sym} (ADD ptr idx) val mem) && ptr.Op != OpSB => (FMOVDstoreidx [off] {sym} ptr idx val mem)
-
-// combine ADD into indexed loads and stores
-(MOVBZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
-(MOVBloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVBloadidx [c+d] {sym} ptr idx mem)
-(MOVHZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
-(MOVHloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVHloadidx [c+d] {sym} ptr idx mem)
-(MOVWZloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
-(MOVWloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVWloadidx [c+d] {sym} ptr idx mem)
-(MOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (MOVDloadidx [c+d] {sym} ptr idx mem)
-(FMOVSloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
-(FMOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem) && is20Bit(c+d) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
-
-(MOVBstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVBstoreidx [c+d] {sym} ptr idx val mem)
-(MOVHstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVHstoreidx [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVWstoreidx [c+d] {sym} ptr idx val mem)
-(MOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (MOVDstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVSstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem) && is20Bit(c+d) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
-
-(MOVBZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVBZloadidx [c+d] {sym} ptr idx mem)
-(MOVBloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVBloadidx [c+d] {sym} ptr idx mem)
-(MOVHZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVHZloadidx [c+d] {sym} ptr idx mem)
-(MOVHloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVHloadidx [c+d] {sym} ptr idx mem)
-(MOVWZloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVWZloadidx [c+d] {sym} ptr idx mem)
-(MOVWloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVWloadidx [c+d] {sym} ptr idx mem)
-(MOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (MOVDloadidx [c+d] {sym} ptr idx mem)
-(FMOVSloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (FMOVSloadidx [c+d] {sym} ptr idx mem)
-(FMOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem) && is20Bit(c+d) -> (FMOVDloadidx [c+d] {sym} ptr idx mem)
-
-(MOVBstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVBstoreidx [c+d] {sym} ptr idx val mem)
-(MOVHstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVHstoreidx [c+d] {sym} ptr idx val mem)
-(MOVWstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVWstoreidx [c+d] {sym} ptr idx val mem)
-(MOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (MOVDstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVSstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
-(FMOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem) && is20Bit(c+d) -> (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
+(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)
+(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)
+(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)
+(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)
// MOVDaddr into MOVDaddridx
-(MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB ->
- (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
-(MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y)) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) && y.Op != OpSB ->
- (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
+(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] {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)
// Absorb InvertFlags into branches.
(BRC {c} (InvertFlags cmp) yes no) => (BRC {c.ReverseComparison()} cmp yes no)
// Constant comparisons.
-(CMPconst (MOVDconst [x]) [y]) && x==y -> (FlagEQ)
-(CMPconst (MOVDconst [x]) [y]) && x<y -> (FlagLT)
-(CMPconst (MOVDconst [x]) [y]) && x>y -> (FlagGT)
+(CMPconst (MOVDconst [x]) [y]) && x==int64(y) => (FlagEQ)
+(CMPconst (MOVDconst [x]) [y]) && x<int64(y) => (FlagLT)
+(CMPconst (MOVDconst [x]) [y]) && x>int64(y) => (FlagGT)
(CMPUconst (MOVDconst [x]) [y]) && uint64(x)==uint64(y) => (FlagEQ)
(CMPUconst (MOVDconst [x]) [y]) && uint64(x)<uint64(y) => (FlagLT)
(CMPUconst (MOVDconst [x]) [y]) && uint64(x)>uint64(y) => (FlagGT)
@@ -1158,31 +1056,31 @@
// Convert constant subtracts to constant adds.
(SUBconst [c] x) && c != -(1<<31) => (ADDconst [-c] x)
-(SUBWconst [c] x) -> (ADDWconst [int64(int32(-c))] x)
+(SUBWconst [c] x) => (ADDWconst [-int32(c)] x)
// generic constant folding
// TODO: more of this
-(ADDconst [c] (MOVDconst [d])) -> (MOVDconst [c+d])
-(ADDWconst [c] (MOVDconst [d])) -> (MOVDconst [int64(int32(c+d))])
-(ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) -> (ADDconst [c+d] x)
-(ADDWconst [c] (ADDWconst [d] x)) -> (ADDWconst [int64(int32(c+d))] x)
-(SUBconst (MOVDconst [d]) [c]) -> (MOVDconst [d-c])
-(SUBconst (SUBconst x [d]) [c]) && is32Bit(-c-d) -> (ADDconst [-c-d] x)
+(ADDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
+(ADDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
+(ADDconst [c] (ADDconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDconst [c+d] x)
+(ADDWconst [c] (ADDWconst [d] x)) => (ADDWconst [int32(c+d)] x)
+(SUBconst (MOVDconst [d]) [c]) => (MOVDconst [d-int64(c)])
+(SUBconst (SUBconst x [d]) [c]) && is32Bit(-int64(c)-int64(d)) => (ADDconst [-c-d] x)
(SRADconst [c] (MOVDconst [d])) => (MOVDconst [d>>uint64(c)])
(SRAWconst [c] (MOVDconst [d])) => (MOVDconst [int64(int32(d))>>uint64(c)])
(NEG (MOVDconst [c])) => (MOVDconst [-c])
(NEGW (MOVDconst [c])) => (MOVDconst [int64(int32(-c))])
-(MULLDconst [c] (MOVDconst [d])) -> (MOVDconst [c*d])
-(MULLWconst [c] (MOVDconst [d])) -> (MOVDconst [int64(int32(c*d))])
+(MULLDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)*d])
+(MULLWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c*int32(d))])
(AND (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&d])
(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d])
-(ANDWconst [c] (MOVDconst [d])) -> (MOVDconst [c&d])
+(ANDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)&d])
(OR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|d])
(ORconst [c] (MOVDconst [d])) => (MOVDconst [c|d])
-(ORWconst [c] (MOVDconst [d])) -> (MOVDconst [c|d])
+(ORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)|d])
(XOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c^d])
(XORconst [c] (MOVDconst [d])) => (MOVDconst [c^d])
-(XORWconst [c] (MOVDconst [d])) -> (MOVDconst [c^d])
+(XORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)^d])
(LoweredRound32F x:(FMOVSconst)) => x
(LoweredRound64F x:(FMOVDconst)) => x
@@ -1199,19 +1097,19 @@
(XOR x x) => (MOVDconst [0])
(XORW x x) => (MOVDconst [0])
(NEG (ADDconst [c] (NEG x))) && c != -(1<<31) => (ADDconst [-c] x)
-(MOVBZreg (ANDWconst [m] x)) -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
-(MOVHZreg (ANDWconst [m] x)) -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
-(MOVBreg (ANDWconst [m] x)) && int8(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
-(MOVHreg (ANDWconst [m] x)) && int16(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+(MOVBZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
+(MOVHZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
+(MOVBreg (ANDWconst [m] x)) && int8(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
+(MOVHreg (ANDWconst [m] x)) && int16(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
// carry flag generation
// (only constant fold carry of zero)
(Select1 (ADDCconst (MOVDconst [c]) [d]))
- && uint64(c+d) >= uint64(c) && c+d == 0
- -> (FlagEQ)
+ && uint64(c+int64(d)) >= uint64(c) && c+int64(d) == 0
+ => (FlagEQ)
(Select1 (ADDCconst (MOVDconst [c]) [d]))
- && uint64(c+d) >= uint64(c) && c+d != 0
- -> (FlagLT)
+ && uint64(c+int64(d)) >= uint64(c) && c+int64(d) != 0
+ => (FlagLT)
// borrow flag generation
// (only constant fold borrow of zero)
@@ -1225,8 +1123,8 @@
// add with carry
(ADDE x y (FlagEQ)) => (ADDC x y)
(ADDE x y (FlagLT)) => (ADDC x y)
-(ADDC x (MOVDconst [c])) && is16Bit(c) -> (ADDCconst x [c])
-(Select0 (ADDCconst (MOVDconst [c]) [d])) -> (MOVDconst [c+d])
+(ADDC x (MOVDconst [c])) && is16Bit(c) => (ADDCconst x [int16(c)])
+(Select0 (ADDCconst (MOVDconst [c]) [d])) => (MOVDconst [c+int64(d)])
// subtract with borrow
(SUBE x y (FlagGT)) => (SUBC x y)
@@ -1256,14 +1154,12 @@
(C(G|LG)IJ {s390x.Greater} (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.Borrow} borrow)
// fused multiply-add
-(Select0 (F(ADD|SUB) (FMUL y z) x)) -> (FM(ADD|SUB) x y z)
-(Select0 (F(ADDS|SUBS) (FMULS y z) x)) -> (FM(ADDS|SUBS) x y z)
+(Select0 (F(ADD|SUB) (FMUL y z) x)) => (FM(ADD|SUB) x y z)
+(Select0 (F(ADDS|SUBS) (FMULS y z) x)) => (FM(ADDS|SUBS) x y z)
// Convert floating point comparisons against zero into 'load and test' instructions.
-(FCMP x (FMOVDconst [c])) && auxTo64F(c) == 0 -> (LTDBR x)
-(FCMPS x (FMOVSconst [c])) && auxTo32F(c) == 0 -> (LTEBR x)
-(FCMP (FMOVDconst [c]) x) && auxTo64F(c) == 0 -> (InvertFlags (LTDBR <v.Type> x))
-(FCMPS (FMOVSconst [c]) x) && auxTo32F(c) == 0 -> (InvertFlags (LTEBR <v.Type> x))
+(F(CMP|CMPS) x (FMOV(D|S)const [0.0])) => (LT(D|E)BR x)
+(F(CMP|CMPS) (FMOV(D|S)const [0.0]) x) => (InvertFlags (LT(D|E)BR <v.Type> x))
// FSUB, FSUBS, FADD, FADDS now produce a condition code representing the
// comparison of the result with 0.0. If a compare with zero instruction
@@ -1274,30 +1170,30 @@
// but moving the flag generating value to a different block seems to
// increase the likelihood that the flags value will have to be regenerated
// by flagalloc which is not what we want.
-(LTDBR (Select0 x:(F(ADD|SUB) _ _))) && b == x.Block -> (Select1 x)
-(LTEBR (Select0 x:(F(ADDS|SUBS) _ _))) && b == x.Block -> (Select1 x)
+(LTDBR (Select0 x:(F(ADD|SUB) _ _))) && b == x.Block => (Select1 x)
+(LTEBR (Select0 x:(F(ADDS|SUBS) _ _))) && b == x.Block => (Select1 x)
// Fold memory operations into operations.
// Exclude global data (SB) because these instructions cannot handle relative addresses.
// TODO(mundaym): indexed versions of these?
((ADD|SUB|MULLD|AND|OR|XOR) <t> x g:(MOVDload [off] {sym} ptr mem))
&& ptr.Op != OpSB
- && is20Bit(off)
+ && is20Bit(int64(off))
&& canMergeLoadClobber(v, g, x)
&& clobber(g)
- -> ((ADD|SUB|MULLD|AND|OR|XOR)load <t> [off] {sym} x ptr mem)
+ => ((ADD|SUB|MULLD|AND|OR|XOR)load <t> [off] {sym} x ptr mem)
((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWload [off] {sym} ptr mem))
&& ptr.Op != OpSB
- && is20Bit(off)
+ && is20Bit(int64(off))
&& canMergeLoadClobber(v, g, x)
&& clobber(g)
- -> ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
+ => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWZload [off] {sym} ptr mem))
&& ptr.Op != OpSB
- && is20Bit(off)
+ && is20Bit(int64(off))
&& canMergeLoadClobber(v, g, x)
&& clobber(g)
- -> ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
+ => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
// Combine constant stores into larger (unaligned) stores.
// Avoid SB because constant stores to relative offsets are
@@ -1305,21 +1201,21 @@
(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
&& p.Op != OpSB
&& x.Uses == 1
- && ValAndOff(a).Off() + 1 == ValAndOff(c).Off()
+ && a.Off() + 1 == c.Off()
&& clobber(x)
- -> (MOVHstoreconst [makeValAndOff(ValAndOff(c).Val()&0xff | ValAndOff(a).Val()<<8, ValAndOff(a).Off())] {s} p mem)
+ => (MOVHstoreconst [makeValAndOff32(c.Val32()&0xff | a.Val32()<<8, a.Off32())] {s} p mem)
(MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
&& p.Op != OpSB
&& x.Uses == 1
- && ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
+ && a.Off() + 2 == c.Off()
&& clobber(x)
- -> (MOVWstore [ValAndOff(a).Off()] {s} p (MOVDconst [int64(int32(ValAndOff(c).Val()&0xffff | ValAndOff(a).Val()<<16))]) mem)
+ => (MOVWstore [a.Off32()] {s} p (MOVDconst [int64(c.Val32()&0xffff | a.Val32()<<16)]) mem)
(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
&& p.Op != OpSB
&& x.Uses == 1
- && ValAndOff(a).Off() + 4 == ValAndOff(c).Off()
+ && a.Off() + 4 == c.Off()
&& clobber(x)
- -> (MOVDstore [ValAndOff(a).Off()] {s} p (MOVDconst [ValAndOff(c).Val()&0xffffffff | ValAndOff(a).Val()<<32]) mem)
+ => (MOVDstore [a.Off32()] {s} p (MOVDconst [c.Val()&0xffffffff | a.Val()<<32]) mem)
// Combine stores into larger (unaligned) stores.
// It doesn't work on global data (based on SB) because stores with relative addressing
@@ -1328,93 +1224,52 @@
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHstore [i-1] {s} p w mem)
+ => (MOVHstore [i-1] {s} p w mem)
(MOVBstore [i] {s} p w0:(SRDconst [j] w) x:(MOVBstore [i-1] {s} p (SRDconst [j+8] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHstore [i-1] {s} p w0 mem)
+ => (MOVHstore [i-1] {s} p w0 mem)
(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHstore [i-1] {s} p w mem)
+ => (MOVHstore [i-1] {s} p w mem)
(MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHstore [i-1] {s} p w0 mem)
+ => (MOVHstore [i-1] {s} p w0 mem)
(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVWstore [i-2] {s} p w mem)
+ => (MOVWstore [i-2] {s} p w mem)
(MOVHstore [i] {s} p w0:(SRDconst [j] w) x:(MOVHstore [i-2] {s} p (SRDconst [j+16] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVWstore [i-2] {s} p w0 mem)
+ => (MOVWstore [i-2] {s} p w0 mem)
(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVWstore [i-2] {s} p w mem)
+ => (MOVWstore [i-2] {s} p w mem)
(MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVWstore [i-2] {s} p w0 mem)
+ => (MOVWstore [i-2] {s} p w0 mem)
(MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVDstore [i-4] {s} p w mem)
+ => (MOVDstore [i-4] {s} p w mem)
(MOVWstore [i] {s} p w0:(SRDconst [j] w) x:(MOVWstore [i-4] {s} p (SRDconst [j+32] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVDstore [i-4] {s} p w0 mem)
-
-(MOVBstoreidx [i] {s} p idx w x:(MOVBstoreidx [i-1] {s} p idx (SRDconst [8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHstoreidx [i-1] {s} p idx w mem)
-(MOVBstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx (SRDconst [j+8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHstoreidx [i-1] {s} p idx w0 mem)
-(MOVBstoreidx [i] {s} p idx w x:(MOVBstoreidx [i-1] {s} p idx (SRWconst [8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHstoreidx [i-1] {s} p idx w mem)
-(MOVBstoreidx [i] {s} p idx w0:(SRWconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx (SRWconst [j+8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHstoreidx [i-1] {s} p idx w0 mem)
-(MOVHstoreidx [i] {s} p idx w x:(MOVHstoreidx [i-2] {s} p idx (SRDconst [16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWstoreidx [i-2] {s} p idx w mem)
-(MOVHstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVHstoreidx [i-2] {s} p idx (SRDconst [j+16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWstoreidx [i-2] {s} p idx w0 mem)
-(MOVHstoreidx [i] {s} p idx w x:(MOVHstoreidx [i-2] {s} p idx (SRWconst [16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWstoreidx [i-2] {s} p idx w mem)
-(MOVHstoreidx [i] {s} p idx w0:(SRWconst [j] w) x:(MOVHstoreidx [i-2] {s} p idx (SRWconst [j+16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWstoreidx [i-2] {s} p idx w0 mem)
-(MOVWstoreidx [i] {s} p idx w x:(MOVWstoreidx [i-4] {s} p idx (SRDconst [32] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVDstoreidx [i-4] {s} p idx w mem)
-(MOVWstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVWstoreidx [i-4] {s} p idx (SRDconst [j+32] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVDstoreidx [i-4] {s} p idx w0 mem)
+ => (MOVDstore [i-4] {s} p w0 mem)
// Combine stores into larger (unaligned) stores with the bytes reversed (little endian).
// Store-with-bytes-reversed instructions do not support relative memory addresses,
@@ -1423,87 +1278,46 @@
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHBRstore [i-1] {s} p w mem)
+ => (MOVHBRstore [i-1] {s} p w mem)
(MOVBstore [i] {s} p (SRDconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRDconst [j-8] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHBRstore [i-1] {s} p w0 mem)
+ => (MOVHBRstore [i-1] {s} p w0 mem)
(MOVBstore [i] {s} p (SRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHBRstore [i-1] {s} p w mem)
+ => (MOVHBRstore [i-1] {s} p w mem)
(MOVBstore [i] {s} p (SRWconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRWconst [j-8] w) mem))
&& p.Op != OpSB
&& x.Uses == 1
&& clobber(x)
- -> (MOVHBRstore [i-1] {s} p w0 mem)
+ => (MOVHBRstore [i-1] {s} p w0 mem)
(MOVHBRstore [i] {s} p (SRDconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVWBRstore [i-2] {s} p w mem)
+ => (MOVWBRstore [i-2] {s} p w mem)
(MOVHBRstore [i] {s} p (SRDconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRDconst [j-16] w) mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVWBRstore [i-2] {s} p w0 mem)
+ => (MOVWBRstore [i-2] {s} p w0 mem)
(MOVHBRstore [i] {s} p (SRWconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVWBRstore [i-2] {s} p w mem)
+ => (MOVWBRstore [i-2] {s} p w mem)
(MOVHBRstore [i] {s} p (SRWconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRWconst [j-16] w) mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVWBRstore [i-2] {s} p w0 mem)
+ => (MOVWBRstore [i-2] {s} p w0 mem)
(MOVWBRstore [i] {s} p (SRDconst [32] w) x:(MOVWBRstore [i-4] {s} p w mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVDBRstore [i-4] {s} p w mem)
+ => (MOVDBRstore [i-4] {s} p w mem)
(MOVWBRstore [i] {s} p (SRDconst [j] w) x:(MOVWBRstore [i-4] {s} p w0:(SRDconst [j-32] w) mem))
&& x.Uses == 1
&& clobber(x)
- -> (MOVDBRstore [i-4] {s} p w0 mem)
-
-(MOVBstoreidx [i] {s} p idx (SRDconst [8] w) x:(MOVBstoreidx [i-1] {s} p idx w mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHBRstoreidx [i-1] {s} p idx w mem)
-(MOVBstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx w0:(SRDconst [j-8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHBRstoreidx [i-1] {s} p idx w0 mem)
-(MOVBstoreidx [i] {s} p idx (SRWconst [8] w) x:(MOVBstoreidx [i-1] {s} p idx w mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHBRstoreidx [i-1] {s} p idx w mem)
-(MOVBstoreidx [i] {s} p idx (SRWconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx w0:(SRWconst [j-8] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVHBRstoreidx [i-1] {s} p idx w0 mem)
-(MOVHBRstoreidx [i] {s} p idx (SRDconst [16] w) x:(MOVHBRstoreidx [i-2] {s} p idx w mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWBRstoreidx [i-2] {s} p idx w mem)
-(MOVHBRstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVHBRstoreidx [i-2] {s} p idx w0:(SRDconst [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWBRstoreidx [i-2] {s} p idx w0 mem)
-(MOVHBRstoreidx [i] {s} p idx (SRWconst [16] w) x:(MOVHBRstoreidx [i-2] {s} p idx w mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWBRstoreidx [i-2] {s} p idx w mem)
-(MOVHBRstoreidx [i] {s} p idx (SRWconst [j] w) x:(MOVHBRstoreidx [i-2] {s} p idx w0:(SRWconst [j-16] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVWBRstoreidx [i-2] {s} p idx w0 mem)
-(MOVWBRstoreidx [i] {s} p idx (SRDconst [32] w) x:(MOVWBRstoreidx [i-4] {s} p idx w mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVDBRstoreidx [i-4] {s} p idx w mem)
-(MOVWBRstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVWBRstoreidx [i-4] {s} p idx w0:(SRDconst [j-32] w) mem))
- && x.Uses == 1
- && clobber(x)
- -> (MOVDBRstoreidx [i-4] {s} p idx w0 mem)
+ => (MOVDBRstore [i-4] {s} p w0 mem)
// Combining byte loads into larger (unaligned) loads.
@@ -1518,7 +1332,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
(OR x1:(MOVBZload [i1] {s} p mem)
sh:(SLDconst [8] x0:(MOVBZload [i0] {s} p mem)))
@@ -1529,7 +1343,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
(ORW x1:(MOVHZload [i1] {s} p mem)
sh:(SLWconst [16] x0:(MOVHZload [i0] {s} p mem)))
@@ -1540,7 +1354,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
(OR x1:(MOVHZload [i1] {s} p mem)
sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)))
@@ -1551,7 +1365,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
(OR x1:(MOVWZload [i1] {s} p mem)
sh:(SLDconst [32] x0:(MOVWZload [i0] {s} p mem)))
@@ -1562,7 +1376,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
(ORW
s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
@@ -1579,7 +1393,7 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
+ => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
(OR
s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
@@ -1596,7 +1410,7 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
+ => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
(OR
s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem))
@@ -1613,115 +1427,7 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
-
-// Big-endian indexed loads
-
-(ORW x1:(MOVBZloadidx [i1] {s} p idx mem)
- sh:(SLWconst [8] x0:(MOVBZloadidx [i0] {s} p idx mem)))
- && i1 == i0+1
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZloadidx [i0] {s} p idx mem)
-
-(OR x1:(MOVBZloadidx [i1] {s} p idx mem)
- sh:(SLDconst [8] x0:(MOVBZloadidx [i0] {s} p idx mem)))
- && i1 == i0+1
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZloadidx [i0] {s} p idx mem)
-
-(ORW x1:(MOVHZloadidx [i1] {s} p idx mem)
- sh:(SLWconst [16] x0:(MOVHZloadidx [i0] {s} p idx mem)))
- && i1 == i0+2
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
-
-(OR x1:(MOVHZloadidx [i1] {s} p idx mem)
- sh:(SLDconst [16] x0:(MOVHZloadidx [i0] {s} p idx mem)))
- && i1 == i0+2
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
-
-(OR x1:(MOVWZloadidx [i1] {s} p idx mem)
- sh:(SLDconst [32] x0:(MOVWZloadidx [i0] {s} p idx mem)))
- && i1 == i0+4
- && p.Op != OpSB
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVDloadidx [i0] {s} p idx mem)
-
-(ORW
- s0:(SLWconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))
- or:(ORW
- s1:(SLWconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))
- y))
- && i1 == i0+1
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
-
-(OR
- s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))
- or:(OR
- s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))
- y))
- && i1 == i0+1
- && j1 == j0-8
- && j1 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
-
-(OR
- s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} p idx mem))
- or:(OR
- s1:(SLDconst [j1] x1:(MOVHZloadidx [i1] {s} p idx mem))
- y))
- && i1 == i0+2
- && j1 == j0-16
- && j1 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
+ => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
// Little-endian loads
@@ -1734,7 +1440,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
+ => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
(OR x0:(MOVBZload [i0] {s} p mem)
sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
@@ -1745,7 +1451,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
+ => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
(ORW r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
@@ -1757,7 +1463,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
(OR r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
@@ -1769,7 +1475,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
+ => @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
(OR r0:(MOVWZreg x0:(MOVWBRload [i0] {s} p mem))
sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRload [i1] {s} p mem))))
@@ -1781,7 +1487,7 @@
&& sh.Uses == 1
&& mergePoint(b,x0,x1) != nil
&& clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
+ => @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
(ORW
s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
@@ -1799,7 +1505,7 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
+ => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
(OR
s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
@@ -1817,7 +1523,7 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
+ => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
(OR
s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem)))
@@ -1836,168 +1542,53 @@
&& or.Uses == 1
&& mergePoint(b,x0,x1,y) != nil
&& clobber(x0, x1, r0, r1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
-
-// Little-endian indexed loads
-
-(ORW x0:(MOVBZloadidx [i0] {s} p idx mem)
- sh:(SLWconst [8] x1:(MOVBZloadidx [i1] {s} p idx mem)))
- && p.Op != OpSB
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))
-
-(OR x0:(MOVBZloadidx [i0] {s} p idx mem)
- sh:(SLDconst [8] x1:(MOVBZloadidx [i1] {s} p idx mem)))
- && p.Op != OpSB
- && i1 == i0+1
- && x0.Uses == 1
- && x1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, sh)
- -> @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))
-
-(ORW r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem))
- sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVWBRloadidx [i0] {s} p idx mem)
-
-(OR r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem))
- sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
- && i1 == i0+2
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))
-
-(OR r0:(MOVWZreg x0:(MOVWBRloadidx [i0] {s} p idx mem))
- sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRloadidx [i1] {s} p idx mem))))
- && i1 == i0+4
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && sh.Uses == 1
- && mergePoint(b,x0,x1) != nil
- && clobber(x0, x1, r0, r1, sh)
- -> @mergePoint(b,x0,x1) (MOVDBRloadidx [i0] {s} p idx mem)
-
-(ORW
- s1:(SLWconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))
- or:(ORW
- s0:(SLWconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))
- y))
- && p.Op != OpSB
- && i1 == i0+1
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
-
-(OR
- s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem))
- or:(OR
- s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem))
- y))
- && p.Op != OpSB
- && i1 == i0+1
- && j1 == j0+8
- && j0 % 16 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
-
-(OR
- s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem)))
- or:(OR
- s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem)))
- y))
- && i1 == i0+2
- && j1 == j0+16
- && j0 % 32 == 0
- && x0.Uses == 1
- && x1.Uses == 1
- && r0.Uses == 1
- && r1.Uses == 1
- && s0.Uses == 1
- && s1.Uses == 1
- && or.Uses == 1
- && mergePoint(b,x0,x1,y) != nil
- && clobber(x0, x1, r0, r1, s0, s1, or)
- -> @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
+ => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
// Combine stores into store multiples.
// 32-bit
(MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
&& p.Op != OpSB
&& x.Uses == 1
- && is20Bit(i-4)
+ && is20Bit(int64(i)-4)
&& clobber(x)
- -> (STM2 [i-4] {s} p w0 w1 mem)
+ => (STM2 [i-4] {s} p w0 w1 mem)
(MOVWstore [i] {s} p w2 x:(STM2 [i-8] {s} p w0 w1 mem))
&& x.Uses == 1
- && is20Bit(i-8)
+ && is20Bit(int64(i)-8)
&& clobber(x)
- -> (STM3 [i-8] {s} p w0 w1 w2 mem)
+ => (STM3 [i-8] {s} p w0 w1 w2 mem)
(MOVWstore [i] {s} p w3 x:(STM3 [i-12] {s} p w0 w1 w2 mem))
&& x.Uses == 1
- && is20Bit(i-12)
+ && is20Bit(int64(i)-12)
&& clobber(x)
- -> (STM4 [i-12] {s} p w0 w1 w2 w3 mem)
+ => (STM4 [i-12] {s} p w0 w1 w2 w3 mem)
(STM2 [i] {s} p w2 w3 x:(STM2 [i-8] {s} p w0 w1 mem))
&& x.Uses == 1
- && is20Bit(i-8)
+ && is20Bit(int64(i)-8)
&& clobber(x)
- -> (STM4 [i-8] {s} p w0 w1 w2 w3 mem)
+ => (STM4 [i-8] {s} p w0 w1 w2 w3 mem)
// 64-bit
(MOVDstore [i] {s} p w1 x:(MOVDstore [i-8] {s} p w0 mem))
&& p.Op != OpSB
&& x.Uses == 1
- && is20Bit(i-8)
+ && is20Bit(int64(i)-8)
&& clobber(x)
- -> (STMG2 [i-8] {s} p w0 w1 mem)
+ => (STMG2 [i-8] {s} p w0 w1 mem)
(MOVDstore [i] {s} p w2 x:(STMG2 [i-16] {s} p w0 w1 mem))
&& x.Uses == 1
- && is20Bit(i-16)
+ && is20Bit(int64(i)-16)
&& clobber(x)
- -> (STMG3 [i-16] {s} p w0 w1 w2 mem)
+ => (STMG3 [i-16] {s} p w0 w1 w2 mem)
(MOVDstore [i] {s} p w3 x:(STMG3 [i-24] {s} p w0 w1 w2 mem))
&& x.Uses == 1
- && is20Bit(i-24)
+ && is20Bit(int64(i)-24)
&& clobber(x)
- -> (STMG4 [i-24] {s} p w0 w1 w2 w3 mem)
+ => (STMG4 [i-24] {s} p w0 w1 w2 w3 mem)
(STMG2 [i] {s} p w2 w3 x:(STMG2 [i-16] {s} p w0 w1 mem))
&& x.Uses == 1
- && is20Bit(i-16)
+ && is20Bit(int64(i)-16)
&& clobber(x)
- -> (STMG4 [i-16] {s} p w0 w1 w2 w3 mem)
+ => (STMG4 [i-16] {s} p w0 w1 w2 w3 mem)
// Convert 32-bit store multiples into 64-bit stores.
-(STM2 [i] {s} p (SRDconst [32] x) x mem) -> (MOVDstore [i] {s} p x mem)
+(STM2 [i] {s} p (SRDconst [32] x) x mem) => (MOVDstore [i] {s} p x mem)
diff --git a/src/cmd/compile/internal/ssa/gen/dec.rules b/src/cmd/compile/internal/ssa/gen/dec.rules
index 3fd2be409f..4c677f8418 100644
--- a/src/cmd/compile/internal/ssa/gen/dec.rules
+++ b/src/cmd/compile/internal/ssa/gen/dec.rules
@@ -66,14 +66,14 @@
(Load <typ.Int>
(OffPtr <typ.IntPtr> [2*config.PtrSize] ptr)
mem))
-(Store dst (SliceMake ptr len cap) mem) =>
+(Store {t} dst (SliceMake ptr len cap) mem) =>
(Store {typ.Int}
(OffPtr <typ.IntPtr> [2*config.PtrSize] dst)
cap
(Store {typ.Int}
(OffPtr <typ.IntPtr> [config.PtrSize] dst)
len
- (Store {typ.BytePtr} dst ptr mem)))
+ (Store {t.Elem().PtrTo()} dst ptr mem)))
// interface ops
(ITab (IMake itab _)) => itab
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index e520503ab1..9e2e112cd7 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -1423,7 +1423,8 @@ 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":
+ case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64",
+ "SymOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
return true
}
return false
@@ -1431,7 +1432,7 @@ func opHasAuxInt(op opData) bool {
func opHasAux(op opData) bool {
switch op.aux {
- case "String", "Sym", "SymOff", "SymValAndOff", "Typ", "TypSize", "CCop",
+ case "String", "Sym", "SymOff", "SymValAndOff", "Typ", "TypSize",
"S390XCCMask", "S390XRotateParams":
return true
}
@@ -1784,8 +1785,6 @@ func (op opData) auxType() string {
return "s390x.CCMask"
case "S390XRotateParams":
return "s390x.RotateParams"
- case "CCop":
- return "CCop"
default:
return "invalid"
}
diff --git a/src/cmd/compile/internal/ssa/lower.go b/src/cmd/compile/internal/ssa/lower.go
index ab0fa803bf..f332b2e028 100644
--- a/src/cmd/compile/internal/ssa/lower.go
+++ b/src/cmd/compile/internal/ssa/lower.go
@@ -7,7 +7,7 @@ package ssa
// convert to machine-dependent ops
func lower(f *Func) {
// repeat rewrites until we find no more rewrites
- applyRewrite(f, f.Config.lowerBlock, f.Config.lowerValue)
+ applyRewrite(f, f.Config.lowerBlock, f.Config.lowerValue, removeDeadValues)
}
// checkLower checks for unlowered opcodes and fails if we find one.
diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go
index 6b24371ac7..d1bad529e7 100644
--- a/src/cmd/compile/internal/ssa/nilcheck.go
+++ b/src/cmd/compile/internal/ssa/nilcheck.go
@@ -235,7 +235,7 @@ func nilcheckelim2(f *Func) {
continue
}
if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
- if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(GCNode).Typ().HasHeapPointer()) {
+ if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(GCNode).Typ().HasPointers()) {
// These ops don't really change memory.
continue
// Note: OpVarDef requires that the defined variable not have pointers.
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 4cd72799e8..45401898c8 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -1828,6 +1828,7 @@ const (
OpPPC64FADD
OpPPC64FADDS
OpPPC64SUB
+ OpPPC64SUBFCconst
OpPPC64FSUB
OpPPC64FSUBS
OpPPC64MULLD
@@ -1853,8 +1854,6 @@ const (
OpPPC64ROTL
OpPPC64ROTLW
OpPPC64LoweredAdd64Carry
- OpPPC64ADDconstForCarry
- OpPPC64MaskIfNotCarry
OpPPC64SRADconst
OpPPC64SRAWconst
OpPPC64SRDconst
@@ -2027,8 +2026,6 @@ const (
OpPPC64FlagEQ
OpPPC64FlagLT
OpPPC64FlagGT
- OpPPC64FlagCarrySet
- OpPPC64FlagCarryClear
OpRISCV64ADD
OpRISCV64ADDI
@@ -24318,6 +24315,20 @@ var opcodeTable = [...]opInfo{
},
},
{
+ name: "SUBFCconst",
+ auxType: auxInt64,
+ argLen: 1,
+ asm: ppc64.ASUBC,
+ 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: "FSUB",
argLen: 2,
asm: ppc64.AFSUB,
@@ -24684,28 +24695,6 @@ var opcodeTable = [...]opInfo{
},
},
{
- name: "ADDconstForCarry",
- auxType: auxInt16,
- argLen: 1,
- asm: ppc64.AADDC,
- 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
- },
- clobbers: 2147483648, // R31
- },
- },
- {
- name: "MaskIfNotCarry",
- argLen: 1,
- asm: ppc64.AADDME,
- reg: regInfo{
- 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: "SRADconst",
auxType: auxInt64,
argLen: 1,
@@ -26964,16 +26953,6 @@ var opcodeTable = [...]opInfo{
argLen: 0,
reg: regInfo{},
},
- {
- name: "FlagCarrySet",
- argLen: 0,
- reg: regInfo{},
- },
- {
- name: "FlagCarryClear",
- argLen: 0,
- reg: regInfo{},
- },
{
name: "ADD",
diff --git a/src/cmd/compile/internal/ssa/opt.go b/src/cmd/compile/internal/ssa/opt.go
index 6e91fd7da3..128e614175 100644
--- a/src/cmd/compile/internal/ssa/opt.go
+++ b/src/cmd/compile/internal/ssa/opt.go
@@ -6,5 +6,5 @@ package ssa
// machine-independent optimization
func opt(f *Func) {
- applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric)
+ applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric, removeDeadValues)
}
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index a2be7bb596..64c6aed3e7 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -588,7 +588,7 @@ func (s *regAllocState) init(f *Func) {
if s.f.Config.hasGReg {
s.allocatable &^= 1 << s.GReg
}
- if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
+ if objabi.Framepointer_enabled && s.f.Config.FPReg >= 0 {
s.allocatable &^= 1 << uint(s.f.Config.FPReg)
}
if s.f.Config.LinkReg != -1 {
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index fb35691296..09f94ef53e 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -20,7 +20,15 @@ import (
"path/filepath"
)
-func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter) {
+type deadValueChoice bool
+
+const (
+ leaveDeadValues deadValueChoice = false
+ removeDeadValues = true
+)
+
+// deadcode indicates that rewrite should try to remove any values that become dead.
+func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValueChoice) {
// repeat rewrites until we find no more rewrites
pendingLines := f.cachedLineStarts // Holds statement boundaries that need to be moved to a new value/block
pendingLines.clear()
@@ -56,6 +64,18 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter) {
*v0 = *v
v0.Args = append([]*Value{}, v.Args...) // make a new copy, not aliasing
}
+ if v.Uses == 0 && v.removeable() {
+ if v.Op != OpInvalid && deadcode == removeDeadValues {
+ // Reset any values that are now unused, so that we decrement
+ // the use count of all of its arguments.
+ // Not quite a deadcode pass, because it does not handle cycles.
+ // But it should help Uses==1 rules to fire.
+ v.reset(OpInvalid)
+ change = true
+ }
+ // No point rewriting values which aren't used.
+ continue
+ }
vchange := phielimValue(v)
if vchange && debug > 1 {
@@ -631,6 +651,10 @@ func auxIntToFlagConstant(x int64) flagConstant {
return flagConstant(x)
}
+func auxIntToOp(cc int64) Op {
+ return Op(cc)
+}
+
func boolToAuxInt(b bool) int64 {
if b {
return 1
@@ -674,6 +698,10 @@ func flagConstantToAuxInt(x flagConstant) int64 {
return int64(x)
}
+func opToAuxInt(o Op) int64 {
+ return int64(o)
+}
+
func auxToString(i interface{}) string {
return i.(string)
}
@@ -707,13 +735,6 @@ func s390xCCMaskToAux(c s390x.CCMask) interface{} {
func s390xRotateParamsToAux(r s390x.RotateParams) interface{} {
return r
}
-func cCopToAux(o Op) interface{} {
- return o
-}
-
-func auxToCCop(cc interface{}) Op {
- return cc.(Op)
-}
// uaddOvf reports whether unsigned a+b would overflow.
func uaddOvf(a, b int64) bool {
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index cda9df56f4..89d64052fe 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -1245,9 +1245,9 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ADDLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1261,17 +1261,17 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRLconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 32-c) {
continue
}
v.reset(OpAMD64ROLLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1286,17 +1286,17 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRWconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
continue
}
v.reset(OpAMD64ROLWconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1311,17 +1311,17 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRBconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
continue
}
v.reset(OpAMD64ROLBconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1332,7 +1332,7 @@ func rewriteValueAMD64_OpAMD64ADDL(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 != OpAMD64SHLLconst || v_1.AuxInt != 3 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 3 {
continue
}
y := v_1.Args[0]
@@ -1347,7 +1347,7 @@ func rewriteValueAMD64_OpAMD64ADDL(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 != OpAMD64SHLLconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 2 {
continue
}
y := v_1.Args[0]
@@ -1362,7 +1362,7 @@ func rewriteValueAMD64_OpAMD64ADDL(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 != OpAMD64SHLLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 1 {
continue
}
y := v_1.Args[0]
@@ -1420,11 +1420,11 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_0.Op != OpAMD64ADDLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
v.reset(OpAMD64LEAL1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, y)
return true
}
@@ -1439,15 +1439,15 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value) bool {
if v_1.Op != OpAMD64LEAL {
continue
}
- c := v_1.AuxInt
- s := v_1.Aux
+ c := auxIntToInt32(v_1.AuxInt)
+ s := auxToSym(v_1.Aux)
y := v_1.Args[0]
if !(x.Op != OpSB && y.Op != OpSB) {
continue
}
v.reset(OpAMD64LEAL1)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -1500,131 +1500,131 @@ func rewriteValueAMD64_OpAMD64ADDLconst(v *Value) bool {
// match: (ADDLconst [c] (ADDL x y))
// result: (LEAL1 [c] x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64ADDL {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpAMD64LEAL1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, y)
return true
}
// match: (ADDLconst [c] (SHLLconst [1] x))
// result: (LEAL1 [c] x x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64SHLLconst || v_0.AuxInt != 1 {
+ c := auxIntToInt32(v.AuxInt)
+ if v_0.Op != OpAMD64SHLLconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64LEAL1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, x)
return true
}
// match: (ADDLconst [c] (LEAL [d] {s} x))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL [c+d] {s} x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAL {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAL)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
// match: (ADDLconst [c] (LEAL1 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL1 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAL1 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAL1)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDLconst [c] (LEAL2 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL2 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAL2 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAL2)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDLconst [c] (LEAL4 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL4 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAL4 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAL4)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDLconst [c] (LEAL8 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL8 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAL8 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAL8)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -1685,23 +1685,23 @@ func rewriteValueAMD64_OpAMD64ADDLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ADDLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ADDLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ADDLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -1736,24 +1736,24 @@ func rewriteValueAMD64_OpAMD64ADDLload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ADDLload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDLload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -1807,24 +1807,24 @@ func rewriteValueAMD64_OpAMD64ADDLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -1858,39 +1858,35 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value) bool {
v_0 := v.Args[0]
// match: (ADDQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (ADDQconst [c] x)
+ // result: (ADDQconst [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 != OpAMD64MOVQconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpAMD64ADDQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
break
}
// match: (ADDQ x (MOVLconst [c]))
- // cond: is32Bit(c)
- // result: (ADDQconst [int64(int32(c))] x)
+ // result: (ADDQconst [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 != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
- if !(is32Bit(c)) {
- continue
- }
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ADDQconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1904,17 +1900,17 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value) bool {
if v_0.Op != OpAMD64SHLQconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRQconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 64-c) {
continue
}
v.reset(OpAMD64ROLQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -1925,7 +1921,7 @@ func rewriteValueAMD64_OpAMD64ADDQ(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 != OpAMD64SHLQconst || v_1.AuxInt != 3 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 3 {
continue
}
y := v_1.Args[0]
@@ -1940,7 +1936,7 @@ func rewriteValueAMD64_OpAMD64ADDQ(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 != OpAMD64SHLQconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 2 {
continue
}
y := v_1.Args[0]
@@ -1955,7 +1951,7 @@ func rewriteValueAMD64_OpAMD64ADDQ(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 != OpAMD64SHLQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 1 {
continue
}
y := v_1.Args[0]
@@ -2013,11 +2009,11 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value) bool {
if v_0.Op != OpAMD64ADDQconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, y)
return true
}
@@ -2032,15 +2028,15 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value) bool {
if v_1.Op != OpAMD64LEAQ {
continue
}
- c := v_1.AuxInt
- s := v_1.Aux
+ c := auxIntToInt32(v_1.AuxInt)
+ s := auxToSym(v_1.Aux)
y := v_1.Args[0]
if !(x.Op != OpSB && y.Op != OpSB) {
continue
}
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -2118,131 +2114,131 @@ func rewriteValueAMD64_OpAMD64ADDQconst(v *Value) bool {
// match: (ADDQconst [c] (ADDQ x y))
// result: (LEAQ1 [c] x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64ADDQ {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, y)
return true
}
// match: (ADDQconst [c] (SHLQconst [1] x))
// result: (LEAQ1 [c] x x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64SHLQconst || v_0.AuxInt != 1 {
+ c := auxIntToInt32(v.AuxInt)
+ if v_0.Op != OpAMD64SHLQconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg2(x, x)
return true
}
// match: (ADDQconst [c] (LEAQ [d] {s} x))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ [c+d] {s} x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAQ {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAQ)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
// match: (ADDQconst [c] (LEAQ1 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ1 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAQ1 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDQconst [c] (LEAQ2 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ2 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAQ2 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAQ2)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDQconst [c] (LEAQ4 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ4 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAQ4 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAQ4)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (ADDQconst [c] (LEAQ8 [d] {s} x y))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ8 [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64LEAQ8 {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is32Bit(c + d)) {
+ if !(is32Bit(int64(c) + int64(d))) {
break
}
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -2305,23 +2301,23 @@ func rewriteValueAMD64_OpAMD64ADDQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ADDQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ADDQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ADDQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -2356,24 +2352,24 @@ func rewriteValueAMD64_OpAMD64ADDQload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ADDQload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDQload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -2427,24 +2423,24 @@ func rewriteValueAMD64_OpAMD64ADDQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -2510,24 +2506,24 @@ func rewriteValueAMD64_OpAMD64ADDSDload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ADDSDload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDSDload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDSDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -2613,24 +2609,24 @@ func rewriteValueAMD64_OpAMD64ADDSSload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ADDSSload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ADDSSload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ADDSSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -2695,7 +2691,7 @@ func rewriteValueAMD64_OpAMD64ANDL(v *Value) bool {
}
y := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVLconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -2706,20 +2702,20 @@ func rewriteValueAMD64_OpAMD64ANDL(v *Value) bool {
break
}
// match: (ANDL (MOVLconst [c]) x)
- // cond: isUint32PowerOfTwo(^c) && uint64(^c) >= 128
- // result: (BTRLconst [log2uint32(^c)] x)
+ // cond: isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ // result: (BTRLconst [int8(log32(^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
- if !(isUint32PowerOfTwo(^c) && uint64(^c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128) {
continue
}
v.reset(OpAMD64BTRLconst)
- v.AuxInt = log2uint32(^c)
+ v.AuxInt = int8ToAuxInt(int8(log32(^c)))
v.AddArg(x)
return true
}
@@ -2733,9 +2729,9 @@ func rewriteValueAMD64_OpAMD64ANDL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -2781,16 +2777,16 @@ func rewriteValueAMD64_OpAMD64ANDL(v *Value) bool {
func rewriteValueAMD64_OpAMD64ANDLconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ANDLconst [c] x)
- // cond: isUint32PowerOfTwo(^c) && uint64(^c) >= 128
- // result: (BTRLconst [log2uint32(^c)] x)
+ // cond: isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ // result: (BTRLconst [int8(log32(^c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint32PowerOfTwo(^c) && uint64(^c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128) {
break
}
v.reset(OpAMD64BTRLconst)
- v.AuxInt = log2uint32(^c)
+ v.AuxInt = int8ToAuxInt(int8(log32(^c)))
v.AddArg(x)
return true
}
@@ -2825,7 +2821,7 @@ func rewriteValueAMD64_OpAMD64ANDLconst(v *Value) bool {
// match: (ANDLconst [ 0xFF] x)
// result: (MOVBQZX x)
for {
- if v.AuxInt != 0xFF {
+ if auxIntToInt32(v.AuxInt) != 0xFF {
break
}
x := v_0
@@ -2836,7 +2832,7 @@ func rewriteValueAMD64_OpAMD64ANDLconst(v *Value) bool {
// match: (ANDLconst [0xFFFF] x)
// result: (MOVWQZX x)
for {
- if v.AuxInt != 0xFFFF {
+ if auxIntToInt32(v.AuxInt) != 0xFFFF {
break
}
x := v_0
@@ -2886,23 +2882,23 @@ func rewriteValueAMD64_OpAMD64ANDLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ANDLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ANDLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ANDLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -2937,24 +2933,24 @@ func rewriteValueAMD64_OpAMD64ANDLload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ANDLload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ANDLload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ANDLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -3008,24 +3004,24 @@ func rewriteValueAMD64_OpAMD64ANDLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ANDLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ANDLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -3070,7 +3066,7 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool {
}
y := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVQconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -3082,19 +3078,19 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool {
}
// match: (ANDQ (MOVQconst [c]) x)
// cond: isUint64PowerOfTwo(^c) && uint64(^c) >= 128
- // result: (BTRQconst [log2(^c)] x)
+ // result: (BTRQconst [int8(log2(^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 !(isUint64PowerOfTwo(^c) && uint64(^c) >= 128) {
continue
}
v.reset(OpAMD64BTRQconst)
- v.AuxInt = log2(^c)
+ v.AuxInt = int8ToAuxInt(int8(log2(^c)))
v.AddArg(x)
return true
}
@@ -3102,19 +3098,19 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool {
}
// match: (ANDQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (ANDQconst [c] x)
+ // result: (ANDQconst [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 != OpAMD64MOVQconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpAMD64ANDQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -3160,16 +3156,16 @@ func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool {
func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ANDQconst [c] x)
- // cond: isUint64PowerOfTwo(^c) && uint64(^c) >= 128
- // result: (BTRQconst [log2(^c)] x)
+ // cond: isUint64PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+ // result: (BTRQconst [int8(log32(^c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint64PowerOfTwo(^c) && uint64(^c) >= 128) {
+ if !(isUint64PowerOfTwo(int64(^c)) && uint64(^c) >= 128) {
break
}
v.reset(OpAMD64BTRQconst)
- v.AuxInt = log2(^c)
+ v.AuxInt = int8ToAuxInt(int8(log32(^c)))
v.AddArg(x)
return true
}
@@ -3208,7 +3204,7 @@ func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool {
// match: (ANDQconst [ 0xFF] x)
// result: (MOVBQZX x)
for {
- if v.AuxInt != 0xFF {
+ if auxIntToInt32(v.AuxInt) != 0xFF {
break
}
x := v_0
@@ -3219,7 +3215,7 @@ func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool {
// match: (ANDQconst [0xFFFF] x)
// result: (MOVWQZX x)
for {
- if v.AuxInt != 0xFFFF {
+ if auxIntToInt32(v.AuxInt) != 0xFFFF {
break
}
x := v_0
@@ -3227,17 +3223,6 @@ func rewriteValueAMD64_OpAMD64ANDQconst(v *Value) bool {
v.AddArg(x)
return true
}
- // match: (ANDQconst [0xFFFFFFFF] x)
- // result: (MOVLQZX x)
- for {
- if v.AuxInt != 0xFFFFFFFF {
- break
- }
- x := v_0
- v.reset(OpAMD64MOVLQZX)
- v.AddArg(x)
- return true
- }
// match: (ANDQconst [0] _)
// result: (MOVQconst [0])
for {
@@ -3276,23 +3261,23 @@ func rewriteValueAMD64_OpAMD64ANDQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ANDQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ANDQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ANDQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -3327,24 +3312,24 @@ func rewriteValueAMD64_OpAMD64ANDQload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ANDQload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ANDQload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ANDQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -3398,24 +3383,24 @@ func rewriteValueAMD64_OpAMD64ANDQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ANDQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ANDQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -3541,23 +3526,23 @@ func rewriteValueAMD64_OpAMD64BTCLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTCLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTCLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTCLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTCLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -3590,24 +3575,24 @@ func rewriteValueAMD64_OpAMD64BTCLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTCLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTCLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTCLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -3692,23 +3677,23 @@ func rewriteValueAMD64_OpAMD64BTCQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTCQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTCQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTCQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTCQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -3741,24 +3726,24 @@ func rewriteValueAMD64_OpAMD64BTCQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTCQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTCQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTCQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -3793,17 +3778,17 @@ func rewriteValueAMD64_OpAMD64BTLconst(v *Value) bool {
// cond: (c+d)<64
// result: (BTQconst [c+d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHRQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !((c + d) < 64) {
break
}
v.reset(OpAMD64BTQconst)
- v.AuxInt = c + d
+ v.AuxInt = int8ToAuxInt(c + d)
v.AddArg(x)
return true
}
@@ -3811,24 +3796,24 @@ func rewriteValueAMD64_OpAMD64BTLconst(v *Value) bool {
// cond: c>d
// result: (BTLconst [c-d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHLQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !(c > d) {
break
}
v.reset(OpAMD64BTLconst)
- v.AuxInt = c - d
+ v.AuxInt = int8ToAuxInt(c - d)
v.AddArg(x)
return true
}
// match: (BTLconst [0] s:(SHRQ x y))
// result: (BTQ y x)
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
s := v_0
@@ -3845,17 +3830,17 @@ func rewriteValueAMD64_OpAMD64BTLconst(v *Value) bool {
// cond: (c+d)<32
// result: (BTLconst [c+d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHRLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !((c + d) < 32) {
break
}
v.reset(OpAMD64BTLconst)
- v.AuxInt = c + d
+ v.AuxInt = int8ToAuxInt(c + d)
v.AddArg(x)
return true
}
@@ -3863,24 +3848,24 @@ func rewriteValueAMD64_OpAMD64BTLconst(v *Value) bool {
// cond: c>d
// result: (BTLconst [c-d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHLLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !(c > d) {
break
}
v.reset(OpAMD64BTLconst)
- v.AuxInt = c - d
+ v.AuxInt = int8ToAuxInt(c - d)
v.AddArg(x)
return true
}
// match: (BTLconst [0] s:(SHRL x y))
// result: (BTL y x)
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
s := v_0
@@ -3901,17 +3886,17 @@ func rewriteValueAMD64_OpAMD64BTQconst(v *Value) bool {
// cond: (c+d)<64
// result: (BTQconst [c+d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHRQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !((c + d) < 64) {
break
}
v.reset(OpAMD64BTQconst)
- v.AuxInt = c + d
+ v.AuxInt = int8ToAuxInt(c + d)
v.AddArg(x)
return true
}
@@ -3919,24 +3904,24 @@ func rewriteValueAMD64_OpAMD64BTQconst(v *Value) bool {
// cond: c>d
// result: (BTQconst [c-d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64SHLQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if !(c > d) {
break
}
v.reset(OpAMD64BTQconst)
- v.AuxInt = c - d
+ v.AuxInt = int8ToAuxInt(c - d)
v.AddArg(x)
return true
}
// match: (BTQconst [0] s:(SHRQ x y))
// result: (BTQ y x)
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
s := v_0
@@ -3956,26 +3941,26 @@ func rewriteValueAMD64_OpAMD64BTRLconst(v *Value) bool {
// match: (BTRLconst [c] (BTSLconst [c] x))
// result: (BTRLconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTSLconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTSLconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (BTRLconst [c] (BTCLconst [c] x))
// result: (BTRLconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTCLconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTCLconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -4025,23 +4010,23 @@ func rewriteValueAMD64_OpAMD64BTRLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTRLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTRLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTRLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTRLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -4074,24 +4059,24 @@ func rewriteValueAMD64_OpAMD64BTRLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTRLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTRLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTRLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -4125,26 +4110,26 @@ func rewriteValueAMD64_OpAMD64BTRQconst(v *Value) bool {
// match: (BTRQconst [c] (BTSQconst [c] x))
// result: (BTRQconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTSQconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTSQconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (BTRQconst [c] (BTCQconst [c] x))
// result: (BTRQconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTCQconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTCQconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -4202,23 +4187,23 @@ func rewriteValueAMD64_OpAMD64BTRQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTRQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTRQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTRQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTRQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -4251,24 +4236,24 @@ func rewriteValueAMD64_OpAMD64BTRQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTRQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTRQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTRQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -4302,26 +4287,26 @@ func rewriteValueAMD64_OpAMD64BTSLconst(v *Value) bool {
// match: (BTSLconst [c] (BTRLconst [c] x))
// result: (BTSLconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTRLconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTRLconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTSLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (BTSLconst [c] (BTCLconst [c] x))
// result: (BTSLconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTCLconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTCLconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTSLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -4371,23 +4356,23 @@ func rewriteValueAMD64_OpAMD64BTSLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTSLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTSLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTSLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTSLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -4420,24 +4405,24 @@ func rewriteValueAMD64_OpAMD64BTSLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTSLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTSLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTSLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -4471,26 +4456,26 @@ func rewriteValueAMD64_OpAMD64BTSQconst(v *Value) bool {
// match: (BTSQconst [c] (BTRQconst [c] x))
// result: (BTSQconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTRQconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTRQconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTSQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (BTSQconst [c] (BTCQconst [c] x))
// result: (BTSQconst [c] x)
for {
- c := v.AuxInt
- if v_0.Op != OpAMD64BTCQconst || v_0.AuxInt != c {
+ c := auxIntToInt8(v.AuxInt)
+ if v_0.Op != OpAMD64BTCQconst || auxIntToInt8(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTSQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -4548,23 +4533,23 @@ func rewriteValueAMD64_OpAMD64BTSQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTSQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (BTSQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (BTSQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64BTSQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -4597,24 +4582,24 @@ func rewriteValueAMD64_OpAMD64BTSQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BTSQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (BTSQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64BTSQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -6741,29 +6726,29 @@ func rewriteValueAMD64_OpAMD64CMPB(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (CMPB x (MOVLconst [c]))
- // result: (CMPBconst x [int64(int8(c))])
+ // result: (CMPBconst x [int8(c)])
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64CMPBconst)
- v.AuxInt = int64(int8(c))
+ v.AuxInt = int8ToAuxInt(int8(c))
v.AddArg(x)
return true
}
// match: (CMPB (MOVLconst [c]) x)
- // result: (InvertFlags (CMPBconst x [int64(int8(c))]))
+ // result: (InvertFlags (CMPBconst x [int8(c)]))
for {
if v_0.Op != OpAMD64MOVLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_1
v.reset(OpAMD64InvertFlags)
v0 := b.NewValue0(v.Pos, OpAMD64CMPBconst, types.TypeFlags)
- v0.AuxInt = int64(int8(c))
+ v0.AuxInt = int8ToAuxInt(int8(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -7006,23 +6991,23 @@ func rewriteValueAMD64_OpAMD64CMPBconstload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPBconstload [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (CMPBconstload [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (CMPBconstload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64CMPBconstload)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -7055,24 +7040,24 @@ func rewriteValueAMD64_OpAMD64CMPBload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPBload [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (CMPBload [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64CMPBload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -7133,9 +7118,9 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64CMPLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -7145,11 +7130,11 @@ func rewriteValueAMD64_OpAMD64CMPL(v *Value) bool {
if v_0.Op != OpAMD64MOVLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_1
v.reset(OpAMD64InvertFlags)
v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -7407,23 +7392,23 @@ func rewriteValueAMD64_OpAMD64CMPLconstload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPLconstload [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (CMPLconstload [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (CMPLconstload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64CMPLconstload)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -7456,24 +7441,24 @@ func rewriteValueAMD64_OpAMD64CMPLload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPLload [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (CMPLload [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64CMPLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -7529,36 +7514,36 @@ func rewriteValueAMD64_OpAMD64CMPQ(v *Value) bool {
b := v.Block
// match: (CMPQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (CMPQconst x [c])
+ // result: (CMPQconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
break
}
v.reset(OpAMD64CMPQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMPQ (MOVQconst [c]) x)
// cond: is32Bit(c)
- // result: (InvertFlags (CMPQconst x [c]))
+ // result: (InvertFlags (CMPQconst x [int32(c)]))
for {
if v_0.Op != OpAMD64MOVQconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
if !(is32Bit(c)) {
break
}
v.reset(OpAMD64InvertFlags)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -7722,15 +7707,15 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool {
// match: (CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32])
// result: (FlagLT_ULT)
for {
- if v.AuxInt != 32 || v_0.Op != OpAMD64NEGQ {
+ if auxIntToInt32(v.AuxInt) != 32 || v_0.Op != OpAMD64NEGQ {
break
}
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64ADDQconst || v_0_0.AuxInt != -16 {
+ if v_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_0_0.AuxInt) != -16 {
break
}
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64ANDQconst || v_0_0_0.AuxInt != 15 {
+ if v_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_0_0.AuxInt) != 15 {
break
}
v.reset(OpAMD64FlagLT_ULT)
@@ -7739,15 +7724,15 @@ func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool {
// match: (CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst [7] _))) [32])
// result: (FlagLT_ULT)
for {
- if v.AuxInt != 32 || v_0.Op != OpAMD64NEGQ {
+ if auxIntToInt32(v.AuxInt) != 32 || v_0.Op != OpAMD64NEGQ {
break
}
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64ADDQconst || v_0_0.AuxInt != -8 {
+ if v_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_0_0.AuxInt) != -8 {
break
}
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64ANDQconst || v_0_0_0.AuxInt != 7 {
+ if v_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_0_0.AuxInt) != 7 {
break
}
v.reset(OpAMD64FlagLT_ULT)
@@ -7988,23 +7973,23 @@ func rewriteValueAMD64_OpAMD64CMPQconstload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPQconstload [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (CMPQconstload [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (CMPQconstload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64CMPQconstload)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -8037,24 +8022,24 @@ func rewriteValueAMD64_OpAMD64CMPQload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPQload [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (CMPQload [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64CMPQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -8109,29 +8094,29 @@ func rewriteValueAMD64_OpAMD64CMPW(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (CMPW x (MOVLconst [c]))
- // result: (CMPWconst x [int64(int16(c))])
+ // result: (CMPWconst x [int16(c)])
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64CMPWconst)
- v.AuxInt = int64(int16(c))
+ v.AuxInt = int16ToAuxInt(int16(c))
v.AddArg(x)
return true
}
// match: (CMPW (MOVLconst [c]) x)
- // result: (InvertFlags (CMPWconst x [int64(int16(c))]))
+ // result: (InvertFlags (CMPWconst x [int16(c)]))
for {
if v_0.Op != OpAMD64MOVLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_1
v.reset(OpAMD64InvertFlags)
v0 := b.NewValue0(v.Pos, OpAMD64CMPWconst, types.TypeFlags)
- v0.AuxInt = int64(int16(c))
+ v0.AuxInt = int16ToAuxInt(int16(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -8374,23 +8359,23 @@ func rewriteValueAMD64_OpAMD64CMPWconstload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPWconstload [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (CMPWconstload [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (CMPWconstload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64CMPWconstload)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -8423,24 +8408,24 @@ func rewriteValueAMD64_OpAMD64CMPWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMPWload [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (CMPWload [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64CMPWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -8582,24 +8567,24 @@ func rewriteValueAMD64_OpAMD64DIVSDload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIVSDload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (DIVSDload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64DIVSDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -8660,24 +8645,24 @@ func rewriteValueAMD64_OpAMD64DIVSSload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIVSSload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (DIVSSload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64DIVSSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -8781,22 +8766,22 @@ func rewriteValueAMD64_OpAMD64HMULQU(v *Value) bool {
func rewriteValueAMD64_OpAMD64LEAL(v *Value) bool {
v_0 := v.Args[0]
// match: (LEAL [c] {s} (ADDLconst [d] x))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAL [c+d] {s} x)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDLconst {
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(OpAMD64LEAL)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
@@ -8804,8 +8789,8 @@ func rewriteValueAMD64_OpAMD64LEAL(v *Value) bool {
// cond: x.Op != OpSB && y.Op != OpSB
// result: (LEAL1 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDL {
break
}
@@ -8819,8 +8804,8 @@ func rewriteValueAMD64_OpAMD64LEAL(v *Value) bool {
continue
}
v.reset(OpAMD64LEAL1)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8832,24 +8817,24 @@ func rewriteValueAMD64_OpAMD64LEAL1(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAL1 [c] {s} (ADDLconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAL1 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpAMD64ADDLconst {
continue
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
continue
}
v.reset(OpAMD64LEAL1)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8858,17 +8843,17 @@ func rewriteValueAMD64_OpAMD64LEAL1(v *Value) bool {
// match: (LEAL1 [c] {s} x (SHLLconst [1] y))
// result: (LEAL2 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 1 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL2)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8877,17 +8862,17 @@ func rewriteValueAMD64_OpAMD64LEAL1(v *Value) bool {
// match: (LEAL1 [c] {s} x (SHLLconst [2] y))
// result: (LEAL4 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLLconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 2 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL4)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8896,17 +8881,17 @@ func rewriteValueAMD64_OpAMD64LEAL1(v *Value) bool {
// match: (LEAL1 [c] {s} x (SHLLconst [3] y))
// result: (LEAL8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLLconst || v_1.AuxInt != 3 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 3 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8918,76 +8903,76 @@ func rewriteValueAMD64_OpAMD64LEAL2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAL2 [c] {s} (ADDLconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAL2 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL2)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL2 [c] {s} x (ADDLconst [d] y))
- // cond: is32Bit(c+2*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB
// result: (LEAL2 [c+2*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDLconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+2*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL2)
- v.AuxInt = c + 2*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 2*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL2 [c] {s} x (SHLLconst [1] y))
// result: (LEAL4 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 1 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL4)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL2 [c] {s} x (SHLLconst [2] y))
// result: (LEAL8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLLconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 2 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -8997,60 +8982,60 @@ func rewriteValueAMD64_OpAMD64LEAL4(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAL4 [c] {s} (ADDLconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAL4 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL4)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL4 [c] {s} x (ADDLconst [d] y))
- // cond: is32Bit(c+4*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB
// result: (LEAL4 [c+4*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDLconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+4*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL4)
- v.AuxInt = c + 4*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 4*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL4 [c] {s} x (SHLLconst [1] y))
// result: (LEAL8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLLconst || auxIntToInt8(v_1.AuxInt) != 1 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAL8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9060,44 +9045,44 @@ func rewriteValueAMD64_OpAMD64LEAL8(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAL8 [c] {s} (ADDLconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAL8 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL8)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAL8 [c] {s} x (ADDLconst [d] y))
- // cond: is32Bit(c+8*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB
// result: (LEAL8 [c+8*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDLconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+8*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAL8)
- v.AuxInt = c + 8*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 8*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9106,22 +9091,22 @@ func rewriteValueAMD64_OpAMD64LEAL8(v *Value) bool {
func rewriteValueAMD64_OpAMD64LEAQ(v *Value) bool {
v_0 := v.Args[0]
// match: (LEAQ [c] {s} (ADDQconst [d] x))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (LEAQ [c+d] {s} x)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
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(OpAMD64LEAQ)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
@@ -9129,8 +9114,8 @@ func rewriteValueAMD64_OpAMD64LEAQ(v *Value) bool {
// cond: x.Op != OpSB && y.Op != OpSB
// result: (LEAQ1 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQ {
break
}
@@ -9144,8 +9129,8 @@ func rewriteValueAMD64_OpAMD64LEAQ(v *Value) bool {
continue
}
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9266,24 +9251,24 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAQ1 [c] {s} (ADDQconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAQ1 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpAMD64ADDQconst {
continue
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
continue
}
v.reset(OpAMD64LEAQ1)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9292,17 +9277,17 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool {
// match: (LEAQ1 [c] {s} x (SHLQconst [1] y))
// result: (LEAQ2 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 1 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ2)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9311,17 +9296,17 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool {
// match: (LEAQ1 [c] {s} x (SHLQconst [2] y))
// result: (LEAQ4 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLQconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 2 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ4)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9330,17 +9315,17 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value) bool {
// match: (LEAQ1 [c] {s} x (SHLQconst [3] y))
// result: (LEAQ8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := 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 != OpAMD64SHLQconst || v_1.AuxInt != 3 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 3 {
continue
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9451,76 +9436,76 @@ func rewriteValueAMD64_OpAMD64LEAQ2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAQ2 [c] {s} (ADDQconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAQ2 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ2)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ2 [c] {s} x (ADDQconst [d] y))
- // cond: is32Bit(c+2*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB
// result: (LEAQ2 [c+2*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDQconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+2*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ2)
- v.AuxInt = c + 2*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 2*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ2 [c] {s} x (SHLQconst [1] y))
// result: (LEAQ4 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 1 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ4)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ2 [c] {s} x (SHLQconst [2] y))
// result: (LEAQ8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLQconst || v_1.AuxInt != 2 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 2 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9614,60 +9599,60 @@ func rewriteValueAMD64_OpAMD64LEAQ4(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAQ4 [c] {s} (ADDQconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAQ4 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ4)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ4 [c] {s} x (ADDQconst [d] y))
- // cond: is32Bit(c+4*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB
// result: (LEAQ4 [c+4*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDQconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+4*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ4)
- v.AuxInt = c + 4*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 4*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ4 [c] {s} x (SHLQconst [1] y))
// result: (LEAQ8 [c] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
- if v_1.Op != OpAMD64SHLQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64SHLQconst || auxIntToInt8(v_1.AuxInt) != 1 {
break
}
y := v_1.Args[0]
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9761,44 +9746,44 @@ func rewriteValueAMD64_OpAMD64LEAQ8(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (LEAQ8 [c] {s} (ADDQconst [d] x) y)
- // cond: is32Bit(c+d) && x.Op != OpSB
+ // cond: is32Bit(int64(c)+int64(d)) && x.Op != OpSB
// result: (LEAQ8 [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is32Bit(c+d) && x.Op != OpSB) {
+ if !(is32Bit(int64(c)+int64(d)) && x.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (LEAQ8 [c] {s} x (ADDQconst [d] y))
- // cond: is32Bit(c+8*d) && y.Op != OpSB
+ // cond: is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB
// result: (LEAQ8 [c+8*d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpAMD64ADDQconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is32Bit(c+8*d) && y.Op != OpSB) {
+ if !(is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB) {
break
}
v.reset(OpAMD64LEAQ8)
- v.AuxInt = c + 8*d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + 8*d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -9877,8 +9862,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
if x.Op != OpAMD64MOVBload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -9887,8 +9872,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -9900,8 +9885,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
if x.Op != OpAMD64MOVWload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -9910,8 +9895,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -9923,8 +9908,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -9933,8 +9918,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -9946,8 +9931,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -9956,8 +9941,8 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -9968,13 +9953,13 @@ func rewriteValueAMD64_OpAMD64MOVBQSX(v *Value) bool {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
if !(c&0x80 == 0) {
break
}
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c & 0x7f
+ v.AuxInt = int32ToAuxInt(c & 0x7f)
v.AddArg(x)
return true
}
@@ -9998,14 +9983,14 @@ func rewriteValueAMD64_OpAMD64MOVBQSXload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVBQSX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVBstore {
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)) {
@@ -10050,8 +10035,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
if x.Op != OpAMD64MOVBload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -10060,8 +10045,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -10073,8 +10058,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
if x.Op != OpAMD64MOVWload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -10083,8 +10068,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -10096,8 +10081,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -10106,8 +10091,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -10119,8 +10104,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -10129,8 +10114,8 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVBload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -10151,10 +10136,10 @@ func rewriteValueAMD64_OpAMD64MOVBQZX(v *Value) bool {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c & 0xff
+ v.AuxInt = int32ToAuxInt(c & 0xff)
v.AddArg(x)
return true
}
@@ -10226,14 +10211,14 @@ func rewriteValueAMD64_OpAMD64MOVBload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVBQZX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVBstore {
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)) {
@@ -10244,23 +10229,23 @@ func rewriteValueAMD64_OpAMD64MOVBload(v *Value) bool {
return true
}
// match: (MOVBload [off1] {sym} (ADDQconst [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 != 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(OpAMD64MOVBload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -10354,8 +10339,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETLstore [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 != OpAMD64SETL {
@@ -10367,8 +10352,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETLstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10376,8 +10361,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETLEstore [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 != OpAMD64SETLE {
@@ -10389,8 +10374,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETLEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10398,8 +10383,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETGstore [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 != OpAMD64SETG {
@@ -10411,8 +10396,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETGstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10420,8 +10405,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETGEstore [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 != OpAMD64SETGE {
@@ -10433,8 +10418,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETGEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10442,8 +10427,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETEQstore [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 != OpAMD64SETEQ {
@@ -10455,8 +10440,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETEQstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10464,8 +10449,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETNEstore [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 != OpAMD64SETNE {
@@ -10477,8 +10462,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETNEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10486,8 +10471,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETBstore [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 != OpAMD64SETB {
@@ -10499,8 +10484,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10508,8 +10493,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETBEstore [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 != OpAMD64SETBE {
@@ -10521,8 +10506,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETBEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10530,8 +10515,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETAstore [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 != OpAMD64SETA {
@@ -10543,8 +10528,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETAstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
@@ -10552,8 +10537,8 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
// cond: y.Uses == 1
// result: (SETAEstore [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 != OpAMD64SETAE {
@@ -10565,16 +10550,16 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
break
}
v.reset(OpAMD64SETAEstore)
- 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 (MOVBQSX 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 != OpAMD64MOVBQSX {
break
@@ -10582,16 +10567,16 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64MOVBstore)
- 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 (MOVBQZX 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 != OpAMD64MOVBQZX {
break
@@ -10599,72 +10584,64 @@ func rewriteValueAMD64_OpAMD64MOVBstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64MOVBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off1] {sym} (ADDQconst [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 != OpAMD64ADDQconst {
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
}
// match: (MOVBstore [off] {sym} ptr (MOVLconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
+ // result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVBstoreconst)
- 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
}
// match: (MOVBstore [off] {sym} ptr (MOVQconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
+ // result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVBstoreconst)
- 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
}
@@ -11542,23 +11519,23 @@ func rewriteValueAMD64_OpAMD64MOVBstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
- // cond: ValAndOff(sc).canAdd(off)
- // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: ValAndOff(sc).canAdd32(off)
+ // result: (MOVBstoreconst [ValAndOff(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 != OpAMD64ADDQconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(ValAndOff(sc).canAdd(off)) {
+ if !(ValAndOff(sc).canAdd32(off)) {
break
}
v.reset(OpAMD64MOVBstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = s
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off))
+ v.Aux = symToAux(s)
v.AddArg2(ptr, mem)
return true
}
@@ -11690,8 +11667,8 @@ func rewriteValueAMD64_OpAMD64MOVLQSX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -11700,8 +11677,8 @@ func rewriteValueAMD64_OpAMD64MOVLQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVLQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -11713,8 +11690,8 @@ func rewriteValueAMD64_OpAMD64MOVLQSX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -11723,25 +11700,25 @@ func rewriteValueAMD64_OpAMD64MOVLQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVLQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
// match: (MOVLQSX (ANDLconst [c] x))
- // cond: c & 0x80000000 == 0
+ // cond: uint32(c) & 0x80000000 == 0
// result: (ANDLconst [c & 0x7fffffff] x)
for {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(c&0x80000000 == 0) {
+ if !(uint32(c)&0x80000000 == 0) {
break
}
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c & 0x7fffffff
+ v.AuxInt = int32ToAuxInt(c & 0x7fffffff)
v.AddArg(x)
return true
}
@@ -11787,14 +11764,14 @@ func rewriteValueAMD64_OpAMD64MOVLQSXload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVLQSX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVLstore {
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)) {
@@ -11839,8 +11816,8 @@ func rewriteValueAMD64_OpAMD64MOVLQZX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -11849,8 +11826,8 @@ func rewriteValueAMD64_OpAMD64MOVLQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVLload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -11862,8 +11839,8 @@ func rewriteValueAMD64_OpAMD64MOVLQZX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -11872,8 +11849,8 @@ func rewriteValueAMD64_OpAMD64MOVLQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVLload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -11894,10 +11871,10 @@ func rewriteValueAMD64_OpAMD64MOVLQZX(v *Value) bool {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -12045,14 +12022,14 @@ func rewriteValueAMD64_OpAMD64MOVLload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVLQZX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVLstore {
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)) {
@@ -12063,23 +12040,23 @@ func rewriteValueAMD64_OpAMD64MOVLload(v *Value) bool {
return true
}
// match: (MOVLload [off1] {sym} (ADDQconst [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 != 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(OpAMD64MOVLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -12189,8 +12166,8 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool {
// match: (MOVLstore [off] {sym} ptr (MOVLQSX x) mem)
// result: (MOVLstore [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 != OpAMD64MOVLQSX {
break
@@ -12198,16 +12175,16 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool {
x := 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, x, mem)
return true
}
// match: (MOVLstore [off] {sym} ptr (MOVLQZX x) mem)
// result: (MOVLstore [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 != OpAMD64MOVLQZX {
break
@@ -12215,72 +12192,64 @@ func rewriteValueAMD64_OpAMD64MOVLstore(v *Value) bool {
x := 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, x, mem)
return true
}
// match: (MOVLstore [off1] {sym} (ADDQconst [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 != OpAMD64ADDQconst {
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
}
// match: (MOVLstore [off] {sym} ptr (MOVLconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVLstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
+ // result: (MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVLstoreconst)
- v.AuxInt = makeValAndOff(int64(int32(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 (MOVQconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVLstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
+ // result: (MOVLstoreconst [makeValAndOff32(int32(c),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVLstoreconst)
- v.AuxInt = makeValAndOff(int64(int32(c)), off)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -13048,23 +13017,23 @@ func rewriteValueAMD64_OpAMD64MOVLstoreconst(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (MOVLstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
- // cond: ValAndOff(sc).canAdd(off)
- // result: (MOVLstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: ValAndOff(sc).canAdd32(off)
+ // result: (MOVLstoreconst [ValAndOff(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 != OpAMD64ADDQconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(ValAndOff(sc).canAdd(off)) {
+ if !(ValAndOff(sc).canAdd32(off)) {
break
}
v.reset(OpAMD64MOVLstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = s
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off))
+ v.Aux = symToAux(s)
v.AddArg2(ptr, mem)
return true
}
@@ -13193,23 +13162,23 @@ func rewriteValueAMD64_OpAMD64MOVOload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVOload [off1] {sym} (ADDQconst [off2] ptr) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVOload [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(OpAMD64MOVOload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -13245,24 +13214,24 @@ func rewriteValueAMD64_OpAMD64MOVOstore(v *Value) bool {
config := b.Func.Config
typ := &b.Func.Config.Types
// match: (MOVOstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVOstore [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 != OpAMD64ADDQconst {
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(OpAMD64MOVOstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
@@ -13434,14 +13403,14 @@ func rewriteValueAMD64_OpAMD64MOVQload(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 != OpAMD64MOVQstore {
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)) {
@@ -13451,23 +13420,23 @@ func rewriteValueAMD64_OpAMD64MOVQload(v *Value) bool {
return true
}
// match: (MOVQload [off1] {sym} (ADDQconst [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 != 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(OpAMD64MOVQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -13573,45 +13542,45 @@ func rewriteValueAMD64_OpAMD64MOVQstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVQstore [off1] {sym} (ADDQconst [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 != OpAMD64ADDQconst {
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
}
// match: (MOVQstore [off] {sym} ptr (MOVQconst [c]) mem)
- // cond: validValAndOff(c,off)
- // result: (MOVQstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+ // cond: validVal(c)
+ // result: (MOVQstoreconst [makeValAndOff32(int32(c),off)] {sym} 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 !(validVal(c)) {
break
}
v.reset(OpAMD64MOVQstoreconst)
- 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
}
@@ -14229,23 +14198,23 @@ func rewriteValueAMD64_OpAMD64MOVQstoreconst(v *Value) bool {
b := v.Block
config := b.Func.Config
// match: (MOVQstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
- // cond: ValAndOff(sc).canAdd(off)
- // result: (MOVQstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: ValAndOff(sc).canAdd32(off)
+ // result: (MOVQstoreconst [ValAndOff(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 != OpAMD64ADDQconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(ValAndOff(sc).canAdd(off)) {
+ if !(ValAndOff(sc).canAdd32(off)) {
break
}
v.reset(OpAMD64MOVQstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = s
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off))
+ v.Aux = symToAux(s)
v.AddArg2(ptr, mem)
return true
}
@@ -14347,23 +14316,23 @@ func rewriteValueAMD64_OpAMD64MOVSDload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVSDload [off1] {sym} (ADDQconst [off2] ptr) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVSDload [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(OpAMD64MOVSDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -14413,24 +14382,24 @@ func rewriteValueAMD64_OpAMD64MOVSDstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVSDstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVSDstore [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 != OpAMD64ADDQconst {
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(OpAMD64MOVSDstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
@@ -14480,23 +14449,23 @@ func rewriteValueAMD64_OpAMD64MOVSSload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVSSload [off1] {sym} (ADDQconst [off2] ptr) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVSSload [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(OpAMD64MOVSSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -14546,24 +14515,24 @@ func rewriteValueAMD64_OpAMD64MOVSSstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVSSstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MOVSSstore [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 != OpAMD64ADDQconst {
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(OpAMD64MOVSSstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
@@ -14620,8 +14589,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
if x.Op != OpAMD64MOVWload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14630,8 +14599,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14643,8 +14612,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14653,8 +14622,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14666,8 +14635,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14676,8 +14645,8 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWQSXload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14688,13 +14657,13 @@ func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
if !(c&0x8000 == 0) {
break
}
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c & 0x7fff
+ v.AuxInt = int32ToAuxInt(c & 0x7fff)
v.AddArg(x)
return true
}
@@ -14729,14 +14698,14 @@ func rewriteValueAMD64_OpAMD64MOVWQSXload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVWQSX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVWstore {
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)) {
@@ -14781,8 +14750,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
if x.Op != OpAMD64MOVWload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14791,8 +14760,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14804,8 +14773,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
if x.Op != OpAMD64MOVLload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14814,8 +14783,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14827,8 +14796,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
if x.Op != OpAMD64MOVQload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ off := auxIntToInt32(x.AuxInt)
+ sym := auxToSym(x.Aux)
mem := x.Args[1]
ptr := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
@@ -14837,8 +14806,8 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
b = x.Block
v0 := b.NewValue0(x.Pos, OpAMD64MOVWload, v.Type)
v.copyOf(v0)
- v0.AuxInt = off
- v0.Aux = sym
+ v0.AuxInt = int32ToAuxInt(off)
+ v0.Aux = symToAux(sym)
v0.AddArg2(ptr, mem)
return true
}
@@ -14859,10 +14828,10 @@ func rewriteValueAMD64_OpAMD64MOVWQZX(v *Value) bool {
if v_0.Op != OpAMD64ANDLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
- v.AuxInt = c & 0xffff
+ v.AuxInt = int32ToAuxInt(c & 0xffff)
v.AddArg(x)
return true
}
@@ -14899,14 +14868,14 @@ func rewriteValueAMD64_OpAMD64MOVWload(v *Value) bool {
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVWQZX x)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64MOVWstore {
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)) {
@@ -14917,23 +14886,23 @@ func rewriteValueAMD64_OpAMD64MOVWload(v *Value) bool {
return true
}
// match: (MOVWload [off1] {sym} (ADDQconst [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 != 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(OpAMD64MOVWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
@@ -15026,8 +14995,8 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool {
// match: (MOVWstore [off] {sym} ptr (MOVWQSX x) mem)
// result: (MOVWstore [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 != OpAMD64MOVWQSX {
break
@@ -15035,16 +15004,16 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64MOVWstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVWstore [off] {sym} ptr (MOVWQZX x) mem)
// result: (MOVWstore [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 != OpAMD64MOVWQZX {
break
@@ -15052,72 +15021,64 @@ func rewriteValueAMD64_OpAMD64MOVWstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64MOVWstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVWstore [off1] {sym} (ADDQconst [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 != OpAMD64ADDQconst {
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
}
// match: (MOVWstore [off] {sym} ptr (MOVLconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVWstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
+ // result: (MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVWstoreconst)
- 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
}
// match: (MOVWstore [off] {sym} ptr (MOVQconst [c]) mem)
- // cond: validOff(off)
- // result: (MOVWstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
+ // result: (MOVWstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} 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 !(validOff(off)) {
- break
- }
v.reset(OpAMD64MOVWstoreconst)
- 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
}
@@ -15454,23 +15415,23 @@ func rewriteValueAMD64_OpAMD64MOVWstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWstoreconst [sc] {s} (ADDQconst [off] ptr) mem)
- // cond: ValAndOff(sc).canAdd(off)
- // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: ValAndOff(sc).canAdd32(off)
+ // result: (MOVWstoreconst [ValAndOff(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 != OpAMD64ADDQconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(ValAndOff(sc).canAdd(off)) {
+ if !(ValAndOff(sc).canAdd32(off)) {
break
}
v.reset(OpAMD64MOVWstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = s
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(sc).addOffset32(off))
+ v.Aux = symToAux(s)
v.AddArg2(ptr, mem)
return true
}
@@ -15602,9 +15563,9 @@ func rewriteValueAMD64_OpAMD64MULL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64MULLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -15616,23 +15577,23 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (MULLconst [c] (MULLconst [d] x))
- // result: (MULLconst [int64(int32(c * d))] x)
+ // result: (MULLconst [c * d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64MULLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64MULLconst)
- v.AuxInt = int64(int32(c * d))
+ v.AuxInt = int32ToAuxInt(c * d)
v.AddArg(x)
return true
}
// match: (MULLconst [-9] x)
// result: (NEGL (LEAL8 <v.Type> x x))
for {
- if v.AuxInt != -9 {
+ if auxIntToInt32(v.AuxInt) != -9 {
break
}
x := v_0
@@ -15645,7 +15606,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [-5] x)
// result: (NEGL (LEAL4 <v.Type> x x))
for {
- if v.AuxInt != -5 {
+ if auxIntToInt32(v.AuxInt) != -5 {
break
}
x := v_0
@@ -15658,7 +15619,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [-3] x)
// result: (NEGL (LEAL2 <v.Type> x x))
for {
- if v.AuxInt != -3 {
+ if auxIntToInt32(v.AuxInt) != -3 {
break
}
x := v_0
@@ -15671,7 +15632,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [-1] x)
// result: (NEGL x)
for {
- if v.AuxInt != -1 {
+ if auxIntToInt32(v.AuxInt) != -1 {
break
}
x := v_0
@@ -15682,17 +15643,17 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [ 0] _)
// result: (MOVLconst [0])
for {
- if v.AuxInt != 0 {
+ if auxIntToInt32(v.AuxInt) != 0 {
break
}
v.reset(OpAMD64MOVLconst)
- v.AuxInt = 0
+ v.AuxInt = int32ToAuxInt(0)
return true
}
// match: (MULLconst [ 1] x)
// result: x
for {
- if v.AuxInt != 1 {
+ if auxIntToInt32(v.AuxInt) != 1 {
break
}
x := v_0
@@ -15702,7 +15663,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [ 3] x)
// result: (LEAL2 x x)
for {
- if v.AuxInt != 3 {
+ if auxIntToInt32(v.AuxInt) != 3 {
break
}
x := v_0
@@ -15713,7 +15674,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [ 5] x)
// result: (LEAL4 x x)
for {
- if v.AuxInt != 5 {
+ if auxIntToInt32(v.AuxInt) != 5 {
break
}
x := v_0
@@ -15724,7 +15685,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [ 7] x)
// result: (LEAL2 x (LEAL2 <v.Type> x x))
for {
- if v.AuxInt != 7 {
+ if auxIntToInt32(v.AuxInt) != 7 {
break
}
x := v_0
@@ -15737,7 +15698,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [ 9] x)
// result: (LEAL8 x x)
for {
- if v.AuxInt != 9 {
+ if auxIntToInt32(v.AuxInt) != 9 {
break
}
x := v_0
@@ -15748,7 +15709,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [11] x)
// result: (LEAL2 x (LEAL4 <v.Type> x x))
for {
- if v.AuxInt != 11 {
+ if auxIntToInt32(v.AuxInt) != 11 {
break
}
x := v_0
@@ -15761,7 +15722,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [13] x)
// result: (LEAL4 x (LEAL2 <v.Type> x x))
for {
- if v.AuxInt != 13 {
+ if auxIntToInt32(v.AuxInt) != 13 {
break
}
x := v_0
@@ -15774,7 +15735,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [19] x)
// result: (LEAL2 x (LEAL8 <v.Type> x x))
for {
- if v.AuxInt != 19 {
+ if auxIntToInt32(v.AuxInt) != 19 {
break
}
x := v_0
@@ -15787,7 +15748,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [21] x)
// result: (LEAL4 x (LEAL4 <v.Type> x x))
for {
- if v.AuxInt != 21 {
+ if auxIntToInt32(v.AuxInt) != 21 {
break
}
x := v_0
@@ -15800,7 +15761,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [25] x)
// result: (LEAL8 x (LEAL2 <v.Type> x x))
for {
- if v.AuxInt != 25 {
+ if auxIntToInt32(v.AuxInt) != 25 {
break
}
x := v_0
@@ -15813,7 +15774,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [27] x)
// result: (LEAL8 (LEAL2 <v.Type> x x) (LEAL2 <v.Type> x x))
for {
- if v.AuxInt != 27 {
+ if auxIntToInt32(v.AuxInt) != 27 {
break
}
x := v_0
@@ -15826,7 +15787,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [37] x)
// result: (LEAL4 x (LEAL8 <v.Type> x x))
for {
- if v.AuxInt != 37 {
+ if auxIntToInt32(v.AuxInt) != 37 {
break
}
x := v_0
@@ -15839,7 +15800,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [41] x)
// result: (LEAL8 x (LEAL4 <v.Type> x x))
for {
- if v.AuxInt != 41 {
+ if auxIntToInt32(v.AuxInt) != 41 {
break
}
x := v_0
@@ -15852,7 +15813,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [45] x)
// result: (LEAL8 (LEAL4 <v.Type> x x) (LEAL4 <v.Type> x x))
for {
- if v.AuxInt != 45 {
+ if auxIntToInt32(v.AuxInt) != 45 {
break
}
x := v_0
@@ -15865,7 +15826,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [73] x)
// result: (LEAL8 x (LEAL8 <v.Type> x x))
for {
- if v.AuxInt != 73 {
+ if auxIntToInt32(v.AuxInt) != 73 {
break
}
x := v_0
@@ -15878,7 +15839,7 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
// match: (MULLconst [81] x)
// result: (LEAL8 (LEAL8 <v.Type> x x) (LEAL8 <v.Type> x x))
for {
- if v.AuxInt != 81 {
+ if auxIntToInt32(v.AuxInt) != 81 {
break
}
x := v_0
@@ -15889,128 +15850,128 @@ func rewriteValueAMD64_OpAMD64MULLconst(v *Value) bool {
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c+1) && c >= 15
- // result: (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
+ // cond: isPowerOfTwo(int64(c)+1) && c >= 15
+ // result: (SUBL (SHLLconst <v.Type> [int8(log2(int64(c)+1))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c+1) && c >= 15) {
+ if !(isPowerOfTwo(int64(c)+1) && c >= 15) {
break
}
v.reset(OpAMD64SUBL)
v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type)
- v0.AuxInt = log2(c + 1)
+ v0.AuxInt = int8ToAuxInt(int8(log2(int64(c) + 1)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c-1) && c >= 17
- // result: (LEAL1 (SHLLconst <v.Type> [log2(c-1)] x) x)
+ // cond: isPowerOfTwo32(c-1) && c >= 17
+ // result: (LEAL1 (SHLLconst <v.Type> [int8(log32(c-1))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-1) && c >= 17) {
+ if !(isPowerOfTwo32(c-1) && c >= 17) {
break
}
v.reset(OpAMD64LEAL1)
v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type)
- v0.AuxInt = log2(c - 1)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 1)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c-2) && c >= 34
- // result: (LEAL2 (SHLLconst <v.Type> [log2(c-2)] x) x)
+ // cond: isPowerOfTwo32(c-2) && c >= 34
+ // result: (LEAL2 (SHLLconst <v.Type> [int8(log32(c-2))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-2) && c >= 34) {
+ if !(isPowerOfTwo32(c-2) && c >= 34) {
break
}
v.reset(OpAMD64LEAL2)
v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type)
- v0.AuxInt = log2(c - 2)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 2)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c-4) && c >= 68
- // result: (LEAL4 (SHLLconst <v.Type> [log2(c-4)] x) x)
+ // cond: isPowerOfTwo32(c-4) && c >= 68
+ // result: (LEAL4 (SHLLconst <v.Type> [int8(log32(c-4))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-4) && c >= 68) {
+ if !(isPowerOfTwo32(c-4) && c >= 68) {
break
}
v.reset(OpAMD64LEAL4)
v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type)
- v0.AuxInt = log2(c - 4)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 4)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c-8) && c >= 136
- // result: (LEAL8 (SHLLconst <v.Type> [log2(c-8)] x) x)
+ // cond: isPowerOfTwo32(c-8) && c >= 136
+ // result: (LEAL8 (SHLLconst <v.Type> [int8(log32(c-8))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-8) && c >= 136) {
+ if !(isPowerOfTwo32(c-8) && c >= 136) {
break
}
v.reset(OpAMD64LEAL8)
v0 := b.NewValue0(v.Pos, OpAMD64SHLLconst, v.Type)
- v0.AuxInt = log2(c - 8)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 8)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULLconst [c] x)
- // cond: c%3 == 0 && isPowerOfTwo(c/3)
- // result: (SHLLconst [log2(c/3)] (LEAL2 <v.Type> x x))
+ // cond: c%3 == 0 && isPowerOfTwo32(c/3)
+ // result: (SHLLconst [int8(log32(c/3))] (LEAL2 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%3 == 0 && isPowerOfTwo(c/3)) {
+ if !(c%3 == 0 && isPowerOfTwo32(c/3)) {
break
}
v.reset(OpAMD64SHLLconst)
- v.AuxInt = log2(c / 3)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 3)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAL2, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
// match: (MULLconst [c] x)
- // cond: c%5 == 0 && isPowerOfTwo(c/5)
- // result: (SHLLconst [log2(c/5)] (LEAL4 <v.Type> x x))
+ // cond: c%5 == 0 && isPowerOfTwo32(c/5)
+ // result: (SHLLconst [int8(log32(c/5))] (LEAL4 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%5 == 0 && isPowerOfTwo(c/5)) {
+ if !(c%5 == 0 && isPowerOfTwo32(c/5)) {
break
}
v.reset(OpAMD64SHLLconst)
- v.AuxInt = log2(c / 5)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 5)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAL4, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
// match: (MULLconst [c] x)
- // cond: c%9 == 0 && isPowerOfTwo(c/9)
- // result: (SHLLconst [log2(c/9)] (LEAL8 <v.Type> x x))
+ // cond: c%9 == 0 && isPowerOfTwo32(c/9)
+ // result: (SHLLconst [int8(log32(c/9))] (LEAL8 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%9 == 0 && isPowerOfTwo(c/9)) {
+ if !(c%9 == 0 && isPowerOfTwo32(c/9)) {
break
}
v.reset(OpAMD64SHLLconst)
- v.AuxInt = log2(c / 9)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 9)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAL8, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
@@ -16035,19 +15996,19 @@ func rewriteValueAMD64_OpAMD64MULQ(v *Value) bool {
v_0 := v.Args[0]
// match: (MULQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (MULQconst [c] x)
+ // result: (MULQconst [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 != OpAMD64MOVQconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpAMD64MULQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -16059,27 +16020,27 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (MULQconst [c] (MULQconst [d] x))
- // cond: is32Bit(c*d)
+ // cond: is32Bit(int64(c)*int64(d))
// result: (MULQconst [c * d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpAMD64MULQconst {
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(OpAMD64MULQconst)
- v.AuxInt = c * d
+ v.AuxInt = int32ToAuxInt(c * d)
v.AddArg(x)
return true
}
// match: (MULQconst [-9] x)
// result: (NEGQ (LEAQ8 <v.Type> x x))
for {
- if v.AuxInt != -9 {
+ if auxIntToInt32(v.AuxInt) != -9 {
break
}
x := v_0
@@ -16092,7 +16053,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [-5] x)
// result: (NEGQ (LEAQ4 <v.Type> x x))
for {
- if v.AuxInt != -5 {
+ if auxIntToInt32(v.AuxInt) != -5 {
break
}
x := v_0
@@ -16105,7 +16066,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [-3] x)
// result: (NEGQ (LEAQ2 <v.Type> x x))
for {
- if v.AuxInt != -3 {
+ if auxIntToInt32(v.AuxInt) != -3 {
break
}
x := v_0
@@ -16118,7 +16079,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [-1] x)
// result: (NEGQ x)
for {
- if v.AuxInt != -1 {
+ if auxIntToInt32(v.AuxInt) != -1 {
break
}
x := v_0
@@ -16129,17 +16090,17 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [ 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: (MULQconst [ 1] x)
// result: x
for {
- if v.AuxInt != 1 {
+ if auxIntToInt32(v.AuxInt) != 1 {
break
}
x := v_0
@@ -16149,7 +16110,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [ 3] x)
// result: (LEAQ2 x x)
for {
- if v.AuxInt != 3 {
+ if auxIntToInt32(v.AuxInt) != 3 {
break
}
x := v_0
@@ -16160,7 +16121,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [ 5] x)
// result: (LEAQ4 x x)
for {
- if v.AuxInt != 5 {
+ if auxIntToInt32(v.AuxInt) != 5 {
break
}
x := v_0
@@ -16171,7 +16132,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [ 7] x)
// result: (LEAQ2 x (LEAQ2 <v.Type> x x))
for {
- if v.AuxInt != 7 {
+ if auxIntToInt32(v.AuxInt) != 7 {
break
}
x := v_0
@@ -16184,7 +16145,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [ 9] x)
// result: (LEAQ8 x x)
for {
- if v.AuxInt != 9 {
+ if auxIntToInt32(v.AuxInt) != 9 {
break
}
x := v_0
@@ -16195,7 +16156,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [11] x)
// result: (LEAQ2 x (LEAQ4 <v.Type> x x))
for {
- if v.AuxInt != 11 {
+ if auxIntToInt32(v.AuxInt) != 11 {
break
}
x := v_0
@@ -16208,7 +16169,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [13] x)
// result: (LEAQ4 x (LEAQ2 <v.Type> x x))
for {
- if v.AuxInt != 13 {
+ if auxIntToInt32(v.AuxInt) != 13 {
break
}
x := v_0
@@ -16221,7 +16182,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [19] x)
// result: (LEAQ2 x (LEAQ8 <v.Type> x x))
for {
- if v.AuxInt != 19 {
+ if auxIntToInt32(v.AuxInt) != 19 {
break
}
x := v_0
@@ -16234,7 +16195,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [21] x)
// result: (LEAQ4 x (LEAQ4 <v.Type> x x))
for {
- if v.AuxInt != 21 {
+ if auxIntToInt32(v.AuxInt) != 21 {
break
}
x := v_0
@@ -16247,7 +16208,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [25] x)
// result: (LEAQ8 x (LEAQ2 <v.Type> x x))
for {
- if v.AuxInt != 25 {
+ if auxIntToInt32(v.AuxInt) != 25 {
break
}
x := v_0
@@ -16260,7 +16221,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [27] x)
// result: (LEAQ8 (LEAQ2 <v.Type> x x) (LEAQ2 <v.Type> x x))
for {
- if v.AuxInt != 27 {
+ if auxIntToInt32(v.AuxInt) != 27 {
break
}
x := v_0
@@ -16273,7 +16234,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [37] x)
// result: (LEAQ4 x (LEAQ8 <v.Type> x x))
for {
- if v.AuxInt != 37 {
+ if auxIntToInt32(v.AuxInt) != 37 {
break
}
x := v_0
@@ -16286,7 +16247,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [41] x)
// result: (LEAQ8 x (LEAQ4 <v.Type> x x))
for {
- if v.AuxInt != 41 {
+ if auxIntToInt32(v.AuxInt) != 41 {
break
}
x := v_0
@@ -16299,7 +16260,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [45] x)
// result: (LEAQ8 (LEAQ4 <v.Type> x x) (LEAQ4 <v.Type> x x))
for {
- if v.AuxInt != 45 {
+ if auxIntToInt32(v.AuxInt) != 45 {
break
}
x := v_0
@@ -16312,7 +16273,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [73] x)
// result: (LEAQ8 x (LEAQ8 <v.Type> x x))
for {
- if v.AuxInt != 73 {
+ if auxIntToInt32(v.AuxInt) != 73 {
break
}
x := v_0
@@ -16325,7 +16286,7 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
// match: (MULQconst [81] x)
// result: (LEAQ8 (LEAQ8 <v.Type> x x) (LEAQ8 <v.Type> x x))
for {
- if v.AuxInt != 81 {
+ if auxIntToInt32(v.AuxInt) != 81 {
break
}
x := v_0
@@ -16336,128 +16297,128 @@ func rewriteValueAMD64_OpAMD64MULQconst(v *Value) bool {
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c+1) && c >= 15
- // result: (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
+ // cond: isPowerOfTwo(int64(c)+1) && c >= 15
+ // result: (SUBQ (SHLQconst <v.Type> [int8(log2(int64(c)+1))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c+1) && c >= 15) {
+ if !(isPowerOfTwo(int64(c)+1) && c >= 15) {
break
}
v.reset(OpAMD64SUBQ)
v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type)
- v0.AuxInt = log2(c + 1)
+ v0.AuxInt = int8ToAuxInt(int8(log2(int64(c) + 1)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c-1) && c >= 17
- // result: (LEAQ1 (SHLQconst <v.Type> [log2(c-1)] x) x)
+ // cond: isPowerOfTwo32(c-1) && c >= 17
+ // result: (LEAQ1 (SHLQconst <v.Type> [int8(log32(c-1))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-1) && c >= 17) {
+ if !(isPowerOfTwo32(c-1) && c >= 17) {
break
}
v.reset(OpAMD64LEAQ1)
v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type)
- v0.AuxInt = log2(c - 1)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 1)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c-2) && c >= 34
- // result: (LEAQ2 (SHLQconst <v.Type> [log2(c-2)] x) x)
+ // cond: isPowerOfTwo32(c-2) && c >= 34
+ // result: (LEAQ2 (SHLQconst <v.Type> [int8(log32(c-2))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-2) && c >= 34) {
+ if !(isPowerOfTwo32(c-2) && c >= 34) {
break
}
v.reset(OpAMD64LEAQ2)
v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type)
- v0.AuxInt = log2(c - 2)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 2)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c-4) && c >= 68
- // result: (LEAQ4 (SHLQconst <v.Type> [log2(c-4)] x) x)
+ // cond: isPowerOfTwo32(c-4) && c >= 68
+ // result: (LEAQ4 (SHLQconst <v.Type> [int8(log32(c-4))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-4) && c >= 68) {
+ if !(isPowerOfTwo32(c-4) && c >= 68) {
break
}
v.reset(OpAMD64LEAQ4)
v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type)
- v0.AuxInt = log2(c - 4)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 4)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c-8) && c >= 136
- // result: (LEAQ8 (SHLQconst <v.Type> [log2(c-8)] x) x)
+ // cond: isPowerOfTwo32(c-8) && c >= 136
+ // result: (LEAQ8 (SHLQconst <v.Type> [int8(log32(c-8))] x) x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isPowerOfTwo(c-8) && c >= 136) {
+ if !(isPowerOfTwo32(c-8) && c >= 136) {
break
}
v.reset(OpAMD64LEAQ8)
v0 := b.NewValue0(v.Pos, OpAMD64SHLQconst, v.Type)
- v0.AuxInt = log2(c - 8)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c - 8)))
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
// match: (MULQconst [c] x)
- // cond: c%3 == 0 && isPowerOfTwo(c/3)
- // result: (SHLQconst [log2(c/3)] (LEAQ2 <v.Type> x x))
+ // cond: c%3 == 0 && isPowerOfTwo32(c/3)
+ // result: (SHLQconst [int8(log32(c/3))] (LEAQ2 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%3 == 0 && isPowerOfTwo(c/3)) {
+ if !(c%3 == 0 && isPowerOfTwo32(c/3)) {
break
}
v.reset(OpAMD64SHLQconst)
- v.AuxInt = log2(c / 3)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 3)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
// match: (MULQconst [c] x)
- // cond: c%5 == 0 && isPowerOfTwo(c/5)
- // result: (SHLQconst [log2(c/5)] (LEAQ4 <v.Type> x x))
+ // cond: c%5 == 0 && isPowerOfTwo32(c/5)
+ // result: (SHLQconst [int8(log32(c/5))] (LEAQ4 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%5 == 0 && isPowerOfTwo(c/5)) {
+ if !(c%5 == 0 && isPowerOfTwo32(c/5)) {
break
}
v.reset(OpAMD64SHLQconst)
- v.AuxInt = log2(c / 5)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 5)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ4, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
// match: (MULQconst [c] x)
- // cond: c%9 == 0 && isPowerOfTwo(c/9)
- // result: (SHLQconst [log2(c/9)] (LEAQ8 <v.Type> x x))
+ // cond: c%9 == 0 && isPowerOfTwo32(c/9)
+ // result: (SHLQconst [int8(log32(c/9))] (LEAQ8 <v.Type> x x))
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(c%9 == 0 && isPowerOfTwo(c/9)) {
+ if !(c%9 == 0 && isPowerOfTwo32(c/9)) {
break
}
v.reset(OpAMD64SHLQconst)
- v.AuxInt = log2(c / 9)
+ v.AuxInt = int8ToAuxInt(int8(log32(c / 9)))
v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, v.Type)
v0.AddArg2(x, x)
v.AddArg(v0)
@@ -16531,24 +16492,24 @@ func rewriteValueAMD64_OpAMD64MULSDload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (MULSDload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MULSDload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64MULSDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -16634,24 +16595,24 @@ func rewriteValueAMD64_OpAMD64MULSSload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (MULSSload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (MULSSload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64MULSSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -16849,7 +16810,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
}
y := v_0.Args[1]
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64MOVLconst || v_0_0.AuxInt != 1 {
+ if v_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -16860,20 +16821,20 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
break
}
// match: (ORL (MOVLconst [c]) x)
- // cond: isUint32PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTSLconst [log2uint32(c)] x)
+ // cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTSLconst [int8(log32(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
- if !(isUint32PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128) {
continue
}
v.reset(OpAMD64BTSLconst)
- v.AuxInt = log2uint32(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
@@ -16887,9 +16848,9 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ORLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -16903,17 +16864,17 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRLconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 32-c) {
continue
}
v.reset(OpAMD64ROLLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -16928,17 +16889,17 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRWconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
continue
}
v.reset(OpAMD64ROLWconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -16953,17 +16914,17 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRBconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
continue
}
v.reset(OpAMD64ROLBconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -16997,7 +16958,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPQconst || v_1_1_0.AuxInt != 32 {
+ if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17005,11 +16966,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 != -32 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
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 != 31 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64ROLL)
@@ -17047,7 +17008,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPLconst || v_1_1_0.AuxInt != 32 {
+ if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17055,11 +17016,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 != -32 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
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 != 31 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64ROLL)
@@ -17097,7 +17058,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPQconst || v_1_1_0.AuxInt != 32 {
+ if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17105,11 +17066,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 != -32 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
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 != 31 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64RORL)
@@ -17147,7 +17108,7 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPLconst || v_1_1_0.AuxInt != 32 {
+ if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17155,11 +17116,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 != -32 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
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 != 31 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64RORL)
@@ -17308,7 +17269,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]
@@ -17324,11 +17285,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64ADDQconst || v_1_1_0.AuxInt != -16 {
+ if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
- if v_1_1_0_0.Op != OpAMD64ANDQconst || v_1_1_0_0.AuxInt != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
+ if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
continue
}
v.reset(OpAMD64RORW)
@@ -17348,7 +17309,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]
@@ -17364,11 +17325,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64ADDLconst || v_1_1_0.AuxInt != -16 {
+ if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
- if v_1_1_0_0.Op != OpAMD64ANDLconst || v_1_1_0_0.AuxInt != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
+ if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
continue
}
v.reset(OpAMD64RORW)
@@ -17388,7 +17349,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 != 7 {
+ if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
continue
}
y := v_0_1.Args[0]
@@ -17411,15 +17372,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 != -8 {
+ if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
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 != 7 || 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) != 7 || 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 != 8 {
+ if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17427,11 +17388,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 != -8 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
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 != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
continue
}
v.reset(OpAMD64ROLB)
@@ -17452,7 +17413,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 != 7 {
+ if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
continue
}
y := v_0_1.Args[0]
@@ -17475,15 +17436,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 != -8 {
+ if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
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 != 7 || 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) != 7 || 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 != 8 {
+ if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -17491,11 +17452,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 != -8 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
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 != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
continue
}
v.reset(OpAMD64ROLB)
@@ -17516,7 +17477,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 != 7 {
+ if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
continue
}
y := v_0_1.Args[0]
@@ -17532,11 +17493,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64ADDQconst || v_1_1_0.AuxInt != -8 {
+ if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
- if v_1_1_0_0.Op != OpAMD64ANDQconst || v_1_1_0_0.AuxInt != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
+ if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
continue
}
v.reset(OpAMD64RORB)
@@ -17556,7 +17517,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 != 7 {
+ if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
continue
}
y := v_0_1.Args[0]
@@ -17572,11 +17533,11 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64ADDLconst || v_1_1_0.AuxInt != -8 {
+ if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
- if v_1_1_0_0.Op != OpAMD64ANDLconst || v_1_1_0_0.AuxInt != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
+ if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
continue
}
v.reset(OpAMD64RORB)
@@ -18203,16 +18164,16 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value) bool {
func rewriteValueAMD64_OpAMD64ORLconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ORLconst [c] x)
- // cond: isUint32PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTSLconst [log2uint32(c)] x)
+ // cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTSLconst [int8(log32(c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint32PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128) {
break
}
v.reset(OpAMD64BTSLconst)
- v.AuxInt = log2uint32(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
@@ -18286,23 +18247,23 @@ func rewriteValueAMD64_OpAMD64ORLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ORLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ORLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ORLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -18337,24 +18298,24 @@ func rewriteValueAMD64_OpAMD64ORLload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ORLload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ORLload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ORLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -18408,24 +18369,24 @@ func rewriteValueAMD64_OpAMD64ORLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ORLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ORLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -18468,7 +18429,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
}
y := v_0.Args[1]
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64MOVQconst || v_0_0.AuxInt != 1 {
+ if v_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -18480,19 +18441,19 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
}
// match: (ORQ (MOVQconst [c]) x)
// cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTSQconst [log2(c)] x)
+ // result: (BTSQconst [int8(log2(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 !(isUint64PowerOfTwo(c) && uint64(c) >= 128) {
continue
}
v.reset(OpAMD64BTSQconst)
- v.AuxInt = log2(c)
+ v.AuxInt = int8ToAuxInt(int8(log2(c)))
v.AddArg(x)
return true
}
@@ -18500,19 +18461,19 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
}
// match: (ORQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (ORQconst [c] x)
+ // result: (ORQconst [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 != OpAMD64MOVQconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpAMD64ORQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -18526,9 +18487,9 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ORQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -18542,17 +18503,17 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
if v_0.Op != OpAMD64SHLQconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRQconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 64-c) {
continue
}
v.reset(OpAMD64ROLQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -18586,7 +18547,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPQconst || v_1_1_0.AuxInt != 64 {
+ if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -18594,11 +18555,11 @@ func rewriteValueAMD64_OpAMD64ORQ(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 != -64 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
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 != 63 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64ROLQ)
@@ -18636,7 +18597,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPLconst || v_1_1_0.AuxInt != 64 {
+ if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -18644,11 +18605,11 @@ func rewriteValueAMD64_OpAMD64ORQ(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 != -64 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
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 != 63 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64ROLQ)
@@ -18686,7 +18647,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPQconst || v_1_1_0.AuxInt != 64 {
+ if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -18694,11 +18655,11 @@ func rewriteValueAMD64_OpAMD64ORQ(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 != -64 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
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 != 63 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64RORQ)
@@ -18736,7 +18697,7 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
continue
}
v_1_1_0 := v_1_1.Args[0]
- if v_1_1_0.Op != OpAMD64CMPLconst || v_1_1_0.AuxInt != 64 {
+ if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
continue
}
v_1_1_0_0 := v_1_1_0.Args[0]
@@ -18744,11 +18705,11 @@ func rewriteValueAMD64_OpAMD64ORQ(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 != -64 {
+ if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
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 != 63 || y != v_1_1_0_0_0_0.Args[0] {
+ if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
continue
}
v.reset(OpAMD64RORQ)
@@ -19830,16 +19791,16 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value) bool {
func rewriteValueAMD64_OpAMD64ORQconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ORQconst [c] x)
- // cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTSQconst [log2(c)] x)
+ // cond: isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTSQconst [int8(log32(c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint64PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128) {
break
}
v.reset(OpAMD64BTSQconst)
- v.AuxInt = log2(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
@@ -19913,23 +19874,23 @@ func rewriteValueAMD64_OpAMD64ORQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (ORQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (ORQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64ORQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -19964,24 +19925,24 @@ func rewriteValueAMD64_OpAMD64ORQload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ORQload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ORQload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ORQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -20035,24 +19996,24 @@ func rewriteValueAMD64_OpAMD64ORQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (ORQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64ORQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -20109,28 +20070,28 @@ func rewriteValueAMD64_OpAMD64ROLB(v *Value) bool {
return true
}
// match: (ROLB x (MOVQconst [c]))
- // result: (ROLBconst [c&7 ] x)
+ // result: (ROLBconst [int8(c&7) ] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLBconst)
- v.AuxInt = c & 7
+ v.AuxInt = int8ToAuxInt(int8(c & 7))
v.AddArg(x)
return true
}
// match: (ROLB x (MOVLconst [c]))
- // result: (ROLBconst [c&7 ] x)
+ // result: (ROLBconst [int8(c&7) ] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLBconst)
- v.AuxInt = c & 7
+ v.AuxInt = int8ToAuxInt(int8(c & 7))
v.AddArg(x)
return true
}
@@ -20141,21 +20102,21 @@ func rewriteValueAMD64_OpAMD64ROLBconst(v *Value) bool {
// match: (ROLBconst [c] (ROLBconst [d] x))
// result: (ROLBconst [(c+d)& 7] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64ROLBconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ROLBconst)
- v.AuxInt = (c + d) & 7
+ v.AuxInt = int8ToAuxInt((c + d) & 7)
v.AddArg(x)
return true
}
// match: (ROLBconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20192,28 +20153,28 @@ func rewriteValueAMD64_OpAMD64ROLL(v *Value) bool {
return true
}
// match: (ROLL x (MOVQconst [c]))
- // result: (ROLLconst [c&31] x)
+ // result: (ROLLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (ROLL x (MOVLconst [c]))
- // result: (ROLLconst [c&31] x)
+ // result: (ROLLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -20224,21 +20185,21 @@ func rewriteValueAMD64_OpAMD64ROLLconst(v *Value) bool {
// match: (ROLLconst [c] (ROLLconst [d] x))
// result: (ROLLconst [(c+d)&31] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64ROLLconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ROLLconst)
- v.AuxInt = (c + d) & 31
+ v.AuxInt = int8ToAuxInt((c + d) & 31)
v.AddArg(x)
return true
}
// match: (ROLLconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20275,28 +20236,28 @@ func rewriteValueAMD64_OpAMD64ROLQ(v *Value) bool {
return true
}
// match: (ROLQ x (MOVQconst [c]))
- // result: (ROLQconst [c&63] x)
+ // result: (ROLQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (ROLQ x (MOVLconst [c]))
- // result: (ROLQconst [c&63] x)
+ // result: (ROLQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
@@ -20307,21 +20268,21 @@ func rewriteValueAMD64_OpAMD64ROLQconst(v *Value) bool {
// match: (ROLQconst [c] (ROLQconst [d] x))
// result: (ROLQconst [(c+d)&63] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64ROLQconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ROLQconst)
- v.AuxInt = (c + d) & 63
+ v.AuxInt = int8ToAuxInt((c + d) & 63)
v.AddArg(x)
return true
}
// match: (ROLQconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20358,28 +20319,28 @@ func rewriteValueAMD64_OpAMD64ROLW(v *Value) bool {
return true
}
// match: (ROLW x (MOVQconst [c]))
- // result: (ROLWconst [c&15] x)
+ // result: (ROLWconst [int8(c&15)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLWconst)
- v.AuxInt = c & 15
+ v.AuxInt = int8ToAuxInt(int8(c & 15))
v.AddArg(x)
return true
}
// match: (ROLW x (MOVLconst [c]))
- // result: (ROLWconst [c&15] x)
+ // result: (ROLWconst [int8(c&15)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLWconst)
- v.AuxInt = c & 15
+ v.AuxInt = int8ToAuxInt(int8(c & 15))
v.AddArg(x)
return true
}
@@ -20390,21 +20351,21 @@ func rewriteValueAMD64_OpAMD64ROLWconst(v *Value) bool {
// match: (ROLWconst [c] (ROLWconst [d] x))
// result: (ROLWconst [(c+d)&15] x)
for {
- c := v.AuxInt
+ c := auxIntToInt8(v.AuxInt)
if v_0.Op != OpAMD64ROLWconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpAMD64ROLWconst)
- v.AuxInt = (c + d) & 15
+ v.AuxInt = int8ToAuxInt((c + d) & 15)
v.AddArg(x)
return true
}
// match: (ROLWconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20441,28 +20402,28 @@ func rewriteValueAMD64_OpAMD64RORB(v *Value) bool {
return true
}
// match: (RORB x (MOVQconst [c]))
- // result: (ROLBconst [(-c)&7 ] x)
+ // result: (ROLBconst [int8((-c)&7) ] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLBconst)
- v.AuxInt = (-c) & 7
+ v.AuxInt = int8ToAuxInt(int8((-c) & 7))
v.AddArg(x)
return true
}
// match: (RORB x (MOVLconst [c]))
- // result: (ROLBconst [(-c)&7 ] x)
+ // result: (ROLBconst [int8((-c)&7) ] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLBconst)
- v.AuxInt = (-c) & 7
+ v.AuxInt = int8ToAuxInt(int8((-c) & 7))
v.AddArg(x)
return true
}
@@ -20496,28 +20457,28 @@ func rewriteValueAMD64_OpAMD64RORL(v *Value) bool {
return true
}
// match: (RORL x (MOVQconst [c]))
- // result: (ROLLconst [(-c)&31] x)
+ // result: (ROLLconst [int8((-c)&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLLconst)
- v.AuxInt = (-c) & 31
+ v.AuxInt = int8ToAuxInt(int8((-c) & 31))
v.AddArg(x)
return true
}
// match: (RORL x (MOVLconst [c]))
- // result: (ROLLconst [(-c)&31] x)
+ // result: (ROLLconst [int8((-c)&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLLconst)
- v.AuxInt = (-c) & 31
+ v.AuxInt = int8ToAuxInt(int8((-c) & 31))
v.AddArg(x)
return true
}
@@ -20551,28 +20512,28 @@ func rewriteValueAMD64_OpAMD64RORQ(v *Value) bool {
return true
}
// match: (RORQ x (MOVQconst [c]))
- // result: (ROLQconst [(-c)&63] x)
+ // result: (ROLQconst [int8((-c)&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLQconst)
- v.AuxInt = (-c) & 63
+ v.AuxInt = int8ToAuxInt(int8((-c) & 63))
v.AddArg(x)
return true
}
// match: (RORQ x (MOVLconst [c]))
- // result: (ROLQconst [(-c)&63] x)
+ // result: (ROLQconst [int8((-c)&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLQconst)
- v.AuxInt = (-c) & 63
+ v.AuxInt = int8ToAuxInt(int8((-c) & 63))
v.AddArg(x)
return true
}
@@ -20606,28 +20567,28 @@ func rewriteValueAMD64_OpAMD64RORW(v *Value) bool {
return true
}
// match: (RORW x (MOVQconst [c]))
- // result: (ROLWconst [(-c)&15] x)
+ // result: (ROLWconst [int8((-c)&15)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64ROLWconst)
- v.AuxInt = (-c) & 15
+ v.AuxInt = int8ToAuxInt(int8((-c) & 15))
v.AddArg(x)
return true
}
// match: (RORW x (MOVLconst [c]))
- // result: (ROLWconst [(-c)&15] x)
+ // result: (ROLWconst [int8((-c)&15)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64ROLWconst)
- v.AuxInt = (-c) & 15
+ v.AuxInt = int8ToAuxInt(int8((-c) & 15))
v.AddArg(x)
return true
}
@@ -20637,28 +20598,28 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SARB x (MOVQconst [c]))
- // result: (SARBconst [min(c&31,7)] x)
+ // result: (SARBconst [int8(min(int64(c)&31,7))] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SARBconst)
- v.AuxInt = min(c&31, 7)
+ v.AuxInt = int8ToAuxInt(int8(min(int64(c)&31, 7)))
v.AddArg(x)
return true
}
// match: (SARB x (MOVLconst [c]))
- // result: (SARBconst [min(c&31,7)] x)
+ // result: (SARBconst [int8(min(int64(c)&31,7))] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SARBconst)
- v.AuxInt = min(c&31, 7)
+ v.AuxInt = int8ToAuxInt(int8(min(int64(c)&31, 7)))
v.AddArg(x)
return true
}
@@ -20669,7 +20630,7 @@ func rewriteValueAMD64_OpAMD64SARBconst(v *Value) bool {
// match: (SARBconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20695,28 +20656,28 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SARL x (MOVQconst [c]))
- // result: (SARLconst [c&31] x)
+ // result: (SARLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SARLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (SARL x (MOVLconst [c]))
- // result: (SARLconst [c&31] x)
+ // result: (SARLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SARLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -20728,7 +20689,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -20750,7 +20711,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -20769,7 +20730,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -20791,7 +20752,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -20810,7 +20771,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -20832,7 +20793,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -20851,7 +20812,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -20873,7 +20834,7 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -20891,7 +20852,7 @@ func rewriteValueAMD64_OpAMD64SARLconst(v *Value) bool {
// match: (SARLconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -20917,28 +20878,28 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SARQ x (MOVQconst [c]))
- // result: (SARQconst [c&63] x)
+ // result: (SARQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SARQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SARQ x (MOVLconst [c]))
- // result: (SARQconst [c&63] x)
+ // result: (SARQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SARQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
@@ -20950,7 +20911,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -20972,7 +20933,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -20991,7 +20952,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -21013,7 +20974,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -21032,7 +20993,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -21054,7 +21015,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -21073,7 +21034,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -21095,7 +21056,7 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -21113,7 +21074,7 @@ func rewriteValueAMD64_OpAMD64SARQconst(v *Value) bool {
// match: (SARQconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -21138,28 +21099,28 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SARW x (MOVQconst [c]))
- // result: (SARWconst [min(c&31,15)] x)
+ // result: (SARWconst [int8(min(int64(c)&31,15))] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SARWconst)
- v.AuxInt = min(c&31, 15)
+ v.AuxInt = int8ToAuxInt(int8(min(int64(c)&31, 15)))
v.AddArg(x)
return true
}
// match: (SARW x (MOVLconst [c]))
- // result: (SARWconst [min(c&31,15)] x)
+ // result: (SARWconst [int8(min(int64(c)&31,15))] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SARWconst)
- v.AuxInt = min(c&31, 15)
+ v.AuxInt = int8ToAuxInt(int8(min(int64(c)&31, 15)))
v.AddArg(x)
return true
}
@@ -21170,7 +21131,7 @@ func rewriteValueAMD64_OpAMD64SARWconst(v *Value) bool {
// match: (SARWconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -21421,7 +21382,7 @@ func rewriteValueAMD64_OpAMD64SETA(v *Value) bool {
func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
v_0 := v.Args[0]
// match: (SETAE (TESTQ x x))
- // result: (ConstBool [1])
+ // result: (ConstBool [true])
for {
if v_0.Op != OpAMD64TESTQ {
break
@@ -21431,11 +21392,11 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 1
+ v.AuxInt = boolToAuxInt(true)
return true
}
// match: (SETAE (TESTL x x))
- // result: (ConstBool [1])
+ // result: (ConstBool [true])
for {
if v_0.Op != OpAMD64TESTL {
break
@@ -21445,11 +21406,11 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 1
+ v.AuxInt = boolToAuxInt(true)
return true
}
// match: (SETAE (TESTW x x))
- // result: (ConstBool [1])
+ // result: (ConstBool [true])
for {
if v_0.Op != OpAMD64TESTW {
break
@@ -21459,11 +21420,11 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 1
+ v.AuxInt = boolToAuxInt(true)
return true
}
// match: (SETAE (TESTB x x))
- // result: (ConstBool [1])
+ // result: (ConstBool [true])
for {
if v_0.Op != OpAMD64TESTB {
break
@@ -21473,7 +21434,7 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 1
+ v.AuxInt = boolToAuxInt(true)
return true
}
// match: (SETAE (InvertFlags x))
@@ -21548,8 +21509,8 @@ func rewriteValueAMD64_OpAMD64SETAEstore(v *Value) bool {
// match: (SETAEstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETBEstore [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 != OpAMD64InvertFlags {
break
@@ -21557,30 +21518,30 @@ func rewriteValueAMD64_OpAMD64SETAEstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETBEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETAEstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETAEstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -21708,8 +21669,8 @@ func rewriteValueAMD64_OpAMD64SETAstore(v *Value) bool {
// match: (SETAstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETBstore [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 != OpAMD64InvertFlags {
break
@@ -21717,30 +21678,30 @@ func rewriteValueAMD64_OpAMD64SETAstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETAstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETAstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETAstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -21862,7 +21823,7 @@ func rewriteValueAMD64_OpAMD64SETAstore(v *Value) bool {
func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
v_0 := v.Args[0]
// match: (SETB (TESTQ x x))
- // result: (ConstBool [0])
+ // result: (ConstBool [false])
for {
if v_0.Op != OpAMD64TESTQ {
break
@@ -21872,11 +21833,11 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 0
+ v.AuxInt = boolToAuxInt(false)
return true
}
// match: (SETB (TESTL x x))
- // result: (ConstBool [0])
+ // result: (ConstBool [false])
for {
if v_0.Op != OpAMD64TESTL {
break
@@ -21886,11 +21847,11 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 0
+ v.AuxInt = boolToAuxInt(false)
return true
}
// match: (SETB (TESTW x x))
- // result: (ConstBool [0])
+ // result: (ConstBool [false])
for {
if v_0.Op != OpAMD64TESTW {
break
@@ -21900,11 +21861,11 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 0
+ v.AuxInt = boolToAuxInt(false)
return true
}
// match: (SETB (TESTB x x))
- // result: (ConstBool [0])
+ // result: (ConstBool [false])
for {
if v_0.Op != OpAMD64TESTB {
break
@@ -21914,7 +21875,7 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
break
}
v.reset(OpConstBool)
- v.AuxInt = 0
+ v.AuxInt = boolToAuxInt(false)
return true
}
// match: (SETB (BTLconst [0] x))
@@ -22078,8 +22039,8 @@ func rewriteValueAMD64_OpAMD64SETBEstore(v *Value) bool {
// match: (SETBEstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETAEstore [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 != OpAMD64InvertFlags {
break
@@ -22087,30 +22048,30 @@ func rewriteValueAMD64_OpAMD64SETBEstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETBEstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETBEstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETBEstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -22238,8 +22199,8 @@ func rewriteValueAMD64_OpAMD64SETBstore(v *Value) bool {
// match: (SETBstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETAstore [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 != OpAMD64InvertFlags {
break
@@ -22247,30 +22208,30 @@ func rewriteValueAMD64_OpAMD64SETBstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETAstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETBstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETBstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -22407,7 +22368,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVLconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -22434,7 +22395,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVQconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -22447,46 +22408,46 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
break
}
// match: (SETEQ (TESTLconst [c] x))
- // cond: isUint32PowerOfTwo(c)
- // result: (SETAE (BTLconst [log2uint32(c)] x))
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (SETAE (BTLconst [int8(log32(c))] x))
for {
if v_0.Op != OpAMD64TESTLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (SETEQ (TESTQconst [c] x))
- // cond: isUint64PowerOfTwo(c)
- // result: (SETAE (BTQconst [log2(c)] x))
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (SETAE (BTQconst [int8(log32(c))] x))
for {
if v_0.Op != OpAMD64TESTQconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (SETEQ (TESTQ (MOVQconst [c]) x))
// cond: isUint64PowerOfTwo(c)
- // result: (SETAE (BTQconst [log2(c)] x))
+ // result: (SETAE (BTQconst [int8(log2(c))] x))
for {
if v_0.Op != OpAMD64TESTQ {
break
@@ -22498,14 +22459,14 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
if v_0_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_0_0.AuxInt
+ c := auxIntToInt64(v_0_0.AuxInt)
x := v_0_1
if !(isUint64PowerOfTwo(c)) {
continue
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22515,16 +22476,16 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
// match: (SETEQ (CMPLconst [1] s:(ANDLconst [1] _)))
// result: (SETNE (CMPLconst [0] s))
for {
- if v_0.Op != OpAMD64CMPLconst || v_0.AuxInt != 1 {
+ if v_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_0.AuxInt) != 1 {
break
}
s := v_0.Args[0]
- if s.Op != OpAMD64ANDLconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDLconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
v.reset(OpAMD64SETNE)
v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg(v0)
return true
@@ -22532,16 +22493,16 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
// match: (SETEQ (CMPQconst [1] s:(ANDQconst [1] _)))
// result: (SETNE (CMPQconst [0] s))
for {
- if v_0.Op != OpAMD64CMPQconst || v_0.AuxInt != 1 {
+ if v_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_0.AuxInt) != 1 {
break
}
s := v_0.Args[0]
- if s.Op != OpAMD64ANDQconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDQconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
v.reset(OpAMD64SETNE)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg(v0)
return true
@@ -22558,11 +22519,11 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -22572,7 +22533,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22591,11 +22552,11 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -22605,7 +22566,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22624,11 +22585,11 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -22638,7 +22599,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22657,11 +22618,11 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -22671,7 +22632,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22690,7 +22651,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -22700,7 +22661,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22719,7 +22680,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -22729,7 +22690,7 @@ func rewriteValueAMD64_OpAMD64SETEQ(v *Value) bool {
}
v.reset(OpAMD64SETAE)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -22808,8 +22769,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// match: (SETEQstore [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
// result: (SETAEstore [off] {sym} ptr (BTL x y) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -22823,14 +22784,14 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
}
x := v_1_0.Args[1]
v_1_0_0 := v_1_0.Args[0]
- if v_1_0_0.Op != OpAMD64MOVLconst || v_1_0_0.AuxInt != 1 {
+ if v_1_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_1_0_0.AuxInt) != 1 {
continue
}
y := v_1_1
mem := v_2
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg3(ptr, v0, mem)
@@ -22841,8 +22802,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// match: (SETEQstore [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
// result: (SETAEstore [off] {sym} ptr (BTQ x y) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -22856,14 +22817,14 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
}
x := v_1_0.Args[1]
v_1_0_0 := v_1_0.Args[0]
- if v_1_0_0.Op != OpAMD64MOVQconst || v_1_0_0.AuxInt != 1 {
+ if v_1_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
continue
}
y := v_1_1
mem := v_2
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg3(ptr, v0, mem)
@@ -22872,61 +22833,61 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
break
}
// match: (SETEQstore [off] {sym} ptr (TESTLconst [c] x) mem)
- // cond: isUint32PowerOfTwo(c)
- // result: (SETAEstore [off] {sym} ptr (BTLconst [log2uint32(c)] x) mem)
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (SETAEstore [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
x := v_1.Args[0]
mem := v_2
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (SETEQstore [off] {sym} ptr (TESTQconst [c] x) mem)
- // cond: isUint64PowerOfTwo(c)
- // result: (SETAEstore [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (SETAEstore [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
x := v_1.Args[0]
mem := v_2
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (SETEQstore [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem)
// cond: isUint64PowerOfTwo(c)
- // result: (SETAEstore [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+ // result: (SETAEstore [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -22938,17 +22899,17 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
if v_1_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
x := v_1_1
mem := v_2
if !(isUint64PowerOfTwo(c)) {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -22958,22 +22919,22 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// match: (SETEQstore [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem)
// result: (SETNEstore [off] {sym} ptr (CMPLconst [0] s) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
- if v_1.Op != OpAMD64CMPLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64CMPLconst || auxIntToInt32(v_1.AuxInt) != 1 {
break
}
s := v_1.Args[0]
- if s.Op != OpAMD64ANDLconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDLconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
mem := v_2
v.reset(OpAMD64SETNEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg3(ptr, v0, mem)
return true
@@ -22981,22 +22942,22 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// match: (SETEQstore [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem)
// result: (SETNEstore [off] {sym} ptr (CMPQconst [0] s) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
- if v_1.Op != OpAMD64CMPQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64CMPQconst || auxIntToInt32(v_1.AuxInt) != 1 {
break
}
s := v_1.Args[0]
- if s.Op != OpAMD64ANDQconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDQconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
mem := v_2
v.reset(OpAMD64SETNEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg3(ptr, v0, mem)
return true
@@ -23005,8 +22966,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTQconst [63] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -23016,11 +22977,11 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -23030,10 +22991,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23044,8 +23005,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTLconst [31] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -23055,11 +23016,11 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -23069,10 +23030,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23083,8 +23044,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTQconst [0] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -23094,11 +23055,11 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -23108,10 +23069,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23122,8 +23083,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTLconst [0] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -23133,11 +23094,11 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -23147,10 +23108,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23161,8 +23122,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTQconst [63] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -23172,7 +23133,7 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -23182,10 +23143,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23196,8 +23157,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// cond: z1==z2
// result: (SETAEstore [off] {sym} ptr (BTLconst [31] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -23207,7 +23168,7 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -23217,10 +23178,10 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETAEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -23230,8 +23191,8 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
// match: (SETEQstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETEQstore [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 != OpAMD64InvertFlags {
break
@@ -23239,30 +23200,30 @@ func rewriteValueAMD64_OpAMD64SETEQstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETEQstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETEQstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETEQstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETEQstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -23520,8 +23481,8 @@ func rewriteValueAMD64_OpAMD64SETGEstore(v *Value) bool {
// match: (SETGEstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETLEstore [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 != OpAMD64InvertFlags {
break
@@ -23529,30 +23490,30 @@ func rewriteValueAMD64_OpAMD64SETGEstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETLEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETGEstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETGEstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETGEstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -23680,8 +23641,8 @@ func rewriteValueAMD64_OpAMD64SETGstore(v *Value) bool {
// match: (SETGstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETLstore [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 != OpAMD64InvertFlags {
break
@@ -23689,30 +23650,30 @@ func rewriteValueAMD64_OpAMD64SETGstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETLstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETGstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETGstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETGstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -23970,8 +23931,8 @@ func rewriteValueAMD64_OpAMD64SETLEstore(v *Value) bool {
// match: (SETLEstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETGEstore [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 != OpAMD64InvertFlags {
break
@@ -23979,30 +23940,30 @@ func rewriteValueAMD64_OpAMD64SETLEstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETGEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETLEstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETLEstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETLEstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -24130,8 +24091,8 @@ func rewriteValueAMD64_OpAMD64SETLstore(v *Value) bool {
// match: (SETLstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETGstore [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 != OpAMD64InvertFlags {
break
@@ -24139,30 +24100,30 @@ func rewriteValueAMD64_OpAMD64SETLstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETGstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETLstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETLstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETLstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -24323,7 +24284,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVLconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -24350,7 +24311,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVQconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -24363,46 +24324,46 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
break
}
// match: (SETNE (TESTLconst [c] x))
- // cond: isUint32PowerOfTwo(c)
- // result: (SETB (BTLconst [log2uint32(c)] x))
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (SETB (BTLconst [int8(log32(c))] x))
for {
if v_0.Op != OpAMD64TESTLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (SETNE (TESTQconst [c] x))
- // cond: isUint64PowerOfTwo(c)
- // result: (SETB (BTQconst [log2(c)] x))
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (SETB (BTQconst [int8(log32(c))] x))
for {
if v_0.Op != OpAMD64TESTQconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (SETNE (TESTQ (MOVQconst [c]) x))
// cond: isUint64PowerOfTwo(c)
- // result: (SETB (BTQconst [log2(c)] x))
+ // result: (SETB (BTQconst [int8(log2(c))] x))
for {
if v_0.Op != OpAMD64TESTQ {
break
@@ -24414,14 +24375,14 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
if v_0_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_0_0.AuxInt
+ c := auxIntToInt64(v_0_0.AuxInt)
x := v_0_1
if !(isUint64PowerOfTwo(c)) {
continue
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24431,16 +24392,16 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
// match: (SETNE (CMPLconst [1] s:(ANDLconst [1] _)))
// result: (SETEQ (CMPLconst [0] s))
for {
- if v_0.Op != OpAMD64CMPLconst || v_0.AuxInt != 1 {
+ if v_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_0.AuxInt) != 1 {
break
}
s := v_0.Args[0]
- if s.Op != OpAMD64ANDLconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDLconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
v.reset(OpAMD64SETEQ)
v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg(v0)
return true
@@ -24448,16 +24409,16 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
// match: (SETNE (CMPQconst [1] s:(ANDQconst [1] _)))
// result: (SETEQ (CMPQconst [0] s))
for {
- if v_0.Op != OpAMD64CMPQconst || v_0.AuxInt != 1 {
+ if v_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_0.AuxInt) != 1 {
break
}
s := v_0.Args[0]
- if s.Op != OpAMD64ANDQconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDQconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
v.reset(OpAMD64SETEQ)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg(v0)
return true
@@ -24474,11 +24435,11 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -24488,7 +24449,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24507,11 +24468,11 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -24521,7 +24482,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24540,11 +24501,11 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -24554,7 +24515,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24573,11 +24534,11 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -24587,7 +24548,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24606,7 +24567,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -24616,7 +24577,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24635,7 +24596,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -24645,7 +24606,7 @@ func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
}
v.reset(OpAMD64SETB)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -24724,8 +24685,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// match: (SETNEstore [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
// result: (SETBstore [off] {sym} ptr (BTL x y) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -24739,14 +24700,14 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
}
x := v_1_0.Args[1]
v_1_0_0 := v_1_0.Args[0]
- if v_1_0_0.Op != OpAMD64MOVLconst || v_1_0_0.AuxInt != 1 {
+ if v_1_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_1_0_0.AuxInt) != 1 {
continue
}
y := v_1_1
mem := v_2
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg3(ptr, v0, mem)
@@ -24757,8 +24718,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// match: (SETNEstore [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
// result: (SETBstore [off] {sym} ptr (BTQ x y) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -24772,14 +24733,14 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
}
x := v_1_0.Args[1]
v_1_0_0 := v_1_0.Args[0]
- if v_1_0_0.Op != OpAMD64MOVQconst || v_1_0_0.AuxInt != 1 {
+ if v_1_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
continue
}
y := v_1_1
mem := v_2
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg3(ptr, v0, mem)
@@ -24788,61 +24749,61 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
break
}
// match: (SETNEstore [off] {sym} ptr (TESTLconst [c] x) mem)
- // cond: isUint32PowerOfTwo(c)
- // result: (SETBstore [off] {sym} ptr (BTLconst [log2uint32(c)] x) mem)
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (SETBstore [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
x := v_1.Args[0]
mem := v_2
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (SETNEstore [off] {sym} ptr (TESTQconst [c] x) mem)
- // cond: isUint64PowerOfTwo(c)
- // result: (SETBstore [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (SETBstore [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
x := v_1.Args[0]
mem := v_2
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (SETNEstore [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem)
// cond: isUint64PowerOfTwo(c)
- // result: (SETBstore [off] {sym} ptr (BTQconst [log2(c)] x) mem)
+ // result: (SETBstore [off] {sym} ptr (BTQconst [int8(log2(c))] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -24854,17 +24815,17 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
if v_1_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
x := v_1_1
mem := v_2
if !(isUint64PowerOfTwo(c)) {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -24874,22 +24835,22 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// match: (SETNEstore [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem)
// result: (SETEQstore [off] {sym} ptr (CMPLconst [0] s) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
- if v_1.Op != OpAMD64CMPLconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64CMPLconst || auxIntToInt32(v_1.AuxInt) != 1 {
break
}
s := v_1.Args[0]
- if s.Op != OpAMD64ANDLconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDLconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
mem := v_2
v.reset(OpAMD64SETEQstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg3(ptr, v0, mem)
return true
@@ -24897,22 +24858,22 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// match: (SETNEstore [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem)
// result: (SETEQstore [off] {sym} ptr (CMPQconst [0] s) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
- if v_1.Op != OpAMD64CMPQconst || v_1.AuxInt != 1 {
+ if v_1.Op != OpAMD64CMPQconst || auxIntToInt32(v_1.AuxInt) != 1 {
break
}
s := v_1.Args[0]
- if s.Op != OpAMD64ANDQconst || s.AuxInt != 1 {
+ if s.Op != OpAMD64ANDQconst || auxIntToInt32(s.AuxInt) != 1 {
break
}
mem := v_2
v.reset(OpAMD64SETEQstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(s)
v.AddArg3(ptr, v0, mem)
return true
@@ -24921,8 +24882,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTQconst [63] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -24932,11 +24893,11 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -24946,10 +24907,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -24960,8 +24921,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTLconst [31] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -24971,11 +24932,11 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -24985,10 +24946,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -24999,8 +24960,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTQconst [0] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -25010,11 +24971,11 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -25024,10 +24985,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -25038,8 +24999,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTLconst [0] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -25049,11 +25010,11 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -25063,10 +25024,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -25077,8 +25038,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTQconst [63] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTQ {
break
@@ -25088,7 +25049,7 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -25098,10 +25059,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -25112,8 +25073,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// cond: z1==z2
// result: (SETBstore [off] {sym} ptr (BTLconst [31] x) mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpAMD64TESTL {
break
@@ -25123,7 +25084,7 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
v_1_1 := v_1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
z1 := v_1_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -25133,10 +25094,10 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
continue
}
v.reset(OpAMD64SETBstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v0 := b.NewValue0(v.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
v.AddArg3(ptr, v0, mem)
return true
@@ -25146,8 +25107,8 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
// match: (SETNEstore [off] {sym} ptr (InvertFlags x) mem)
// result: (SETNEstore [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 != OpAMD64InvertFlags {
break
@@ -25155,30 +25116,30 @@ func rewriteValueAMD64_OpAMD64SETNEstore(v *Value) bool {
x := v_1.Args[0]
mem := v_2
v.reset(OpAMD64SETNEstore)
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (SETNEstore [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SETNEstore [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SETNEstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -25302,28 +25263,28 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SHLL x (MOVQconst [c]))
- // result: (SHLLconst [c&31] x)
+ // result: (SHLLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SHLLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (SHLL x (MOVLconst [c]))
- // result: (SHLLconst [c&31] x)
+ // result: (SHLLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SHLLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -25335,7 +25296,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -25357,7 +25318,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -25376,7 +25337,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -25398,7 +25359,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -25417,7 +25378,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -25439,7 +25400,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -25458,7 +25419,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -25480,7 +25441,7 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -25498,19 +25459,19 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool {
// match: (SHLLconst [1] (SHRLconst [1] x))
// result: (BTRLconst [0] x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SHRLconst || v_0.AuxInt != 1 {
+ if auxIntToInt8(v.AuxInt) != 1 || v_0.Op != OpAMD64SHRLconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRLconst)
- v.AuxInt = 0
+ v.AuxInt = int8ToAuxInt(0)
v.AddArg(x)
return true
}
// match: (SHLLconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -25536,28 +25497,28 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SHLQ x (MOVQconst [c]))
- // result: (SHLQconst [c&63] x)
+ // result: (SHLQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SHLQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SHLQ x (MOVLconst [c]))
- // result: (SHLQconst [c&63] x)
+ // result: (SHLQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SHLQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
@@ -25569,7 +25530,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -25591,7 +25552,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -25610,7 +25571,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -25632,7 +25593,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -25651,7 +25612,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -25673,7 +25634,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -25692,7 +25653,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -25714,7 +25675,7 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -25732,19 +25693,19 @@ func rewriteValueAMD64_OpAMD64SHLQconst(v *Value) bool {
// match: (SHLQconst [1] (SHRQconst [1] x))
// result: (BTRQconst [0] x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SHRQconst || v_0.AuxInt != 1 {
+ if auxIntToInt8(v.AuxInt) != 1 || v_0.Op != OpAMD64SHRQconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRQconst)
- v.AuxInt = 0
+ v.AuxInt = int8ToAuxInt(0)
v.AddArg(x)
return true
}
// match: (SHLQconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -25782,35 +25743,35 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value) bool {
v_0 := v.Args[0]
// match: (SHRB x (MOVQconst [c]))
// cond: c&31 < 8
- // result: (SHRBconst [c&31] x)
+ // result: (SHRBconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(c&31 < 8) {
break
}
v.reset(OpAMD64SHRBconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (SHRB x (MOVLconst [c]))
// cond: c&31 < 8
- // result: (SHRBconst [c&31] x)
+ // result: (SHRBconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
if !(c&31 < 8) {
break
}
v.reset(OpAMD64SHRBconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -25821,12 +25782,12 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value) bool {
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(c&31 >= 8) {
break
}
v.reset(OpAMD64MOVLconst)
- v.AuxInt = 0
+ v.AuxInt = int32ToAuxInt(0)
return true
}
// match: (SHRB _ (MOVLconst [c]))
@@ -25836,12 +25797,12 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
if !(c&31 >= 8) {
break
}
v.reset(OpAMD64MOVLconst)
- v.AuxInt = 0
+ v.AuxInt = int32ToAuxInt(0)
return true
}
return false
@@ -25851,7 +25812,7 @@ func rewriteValueAMD64_OpAMD64SHRBconst(v *Value) bool {
// match: (SHRBconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -25865,28 +25826,28 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SHRL x (MOVQconst [c]))
- // result: (SHRLconst [c&31] x)
+ // result: (SHRLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SHRLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (SHRL x (MOVLconst [c]))
- // result: (SHRLconst [c&31] x)
+ // result: (SHRLconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SHRLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -25898,7 +25859,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -25920,7 +25881,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -25939,7 +25900,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -25961,7 +25922,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -25980,7 +25941,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 0) {
break
@@ -26002,7 +25963,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 0) {
break
@@ -26021,7 +25982,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&31 == 31) {
break
@@ -26043,7 +26004,7 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&31 == 31) {
break
@@ -26061,19 +26022,19 @@ func rewriteValueAMD64_OpAMD64SHRLconst(v *Value) bool {
// match: (SHRLconst [1] (SHLLconst [1] x))
// result: (BTRLconst [31] x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SHLLconst || v_0.AuxInt != 1 {
+ if auxIntToInt8(v.AuxInt) != 1 || v_0.Op != OpAMD64SHLLconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRLconst)
- v.AuxInt = 31
+ v.AuxInt = int8ToAuxInt(31)
v.AddArg(x)
return true
}
// match: (SHRLconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -26087,28 +26048,28 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SHRQ x (MOVQconst [c]))
- // result: (SHRQconst [c&63] x)
+ // result: (SHRQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpAMD64SHRQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SHRQ x (MOVLconst [c]))
- // result: (SHRQconst [c&63] x)
+ // result: (SHRQconst [int8(c&63)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SHRQconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
@@ -26120,7 +26081,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1.Op != OpAMD64ADDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -26142,7 +26103,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -26161,7 +26122,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1.Op != OpAMD64ANDQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -26183,7 +26144,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDQconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -26202,7 +26163,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1.Op != OpAMD64ADDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 0) {
break
@@ -26224,7 +26185,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1_0.Op != OpAMD64ADDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 0) {
break
@@ -26243,7 +26204,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1.Op != OpAMD64ANDLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
if !(c&63 == 63) {
break
@@ -26265,7 +26226,7 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value) bool {
if v_1_0.Op != OpAMD64ANDLconst {
break
}
- c := v_1_0.AuxInt
+ c := auxIntToInt32(v_1_0.AuxInt)
y := v_1_0.Args[0]
if !(c&63 == 63) {
break
@@ -26283,19 +26244,19 @@ func rewriteValueAMD64_OpAMD64SHRQconst(v *Value) bool {
// match: (SHRQconst [1] (SHLQconst [1] x))
// result: (BTRQconst [63] x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SHLQconst || v_0.AuxInt != 1 {
+ if auxIntToInt8(v.AuxInt) != 1 || v_0.Op != OpAMD64SHLQconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64BTRQconst)
- v.AuxInt = 63
+ v.AuxInt = int8ToAuxInt(63)
v.AddArg(x)
return true
}
// match: (SHRQconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -26309,35 +26270,35 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value) bool {
v_0 := v.Args[0]
// match: (SHRW x (MOVQconst [c]))
// cond: c&31 < 16
- // result: (SHRWconst [c&31] x)
+ // result: (SHRWconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(c&31 < 16) {
break
}
v.reset(OpAMD64SHRWconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
// match: (SHRW x (MOVLconst [c]))
// cond: c&31 < 16
- // result: (SHRWconst [c&31] x)
+ // result: (SHRWconst [int8(c&31)] x)
for {
x := v_0
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
if !(c&31 < 16) {
break
}
v.reset(OpAMD64SHRWconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -26348,12 +26309,12 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value) bool {
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(c&31 >= 16) {
break
}
v.reset(OpAMD64MOVLconst)
- v.AuxInt = 0
+ v.AuxInt = int32ToAuxInt(0)
return true
}
// match: (SHRW _ (MOVLconst [c]))
@@ -26363,12 +26324,12 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
if !(c&31 >= 16) {
break
}
v.reset(OpAMD64MOVLconst)
- v.AuxInt = 0
+ v.AuxInt = int32ToAuxInt(0)
return true
}
return false
@@ -26378,7 +26339,7 @@ func rewriteValueAMD64_OpAMD64SHRWconst(v *Value) bool {
// match: (SHRWconst x [0])
// result: x
for {
- if v.AuxInt != 0 {
+ if auxIntToInt8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -26398,9 +26359,9 @@ func rewriteValueAMD64_OpAMD64SUBL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64SUBLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -26410,11 +26371,11 @@ func rewriteValueAMD64_OpAMD64SUBL(v *Value) bool {
if v_0.Op != OpAMD64MOVLconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_1
v.reset(OpAMD64NEGL)
v0 := b.NewValue0(v.Pos, OpAMD64SUBLconst, v.Type)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(c)
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -26486,24 +26447,24 @@ func rewriteValueAMD64_OpAMD64SUBLload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SUBLload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBLload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -26557,24 +26518,24 @@ func rewriteValueAMD64_OpAMD64SUBLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SUBLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -26609,36 +26570,36 @@ func rewriteValueAMD64_OpAMD64SUBQ(v *Value) bool {
b := v.Block
// match: (SUBQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (SUBQconst x [c])
+ // result: (SUBQconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpAMD64MOVQconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
break
}
v.reset(OpAMD64SUBQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (SUBQ (MOVQconst [c]) x)
// cond: is32Bit(c)
- // result: (NEGQ (SUBQconst <v.Type> x [c]))
+ // result: (NEGQ (SUBQconst <v.Type> x [int32(c)]))
for {
if v_0.Op != OpAMD64MOVQconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
if !(is32Bit(c)) {
break
}
v.reset(OpAMD64NEGQ)
v0 := b.NewValue0(v.Pos, OpAMD64SUBQconst, v.Type)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -26765,24 +26726,24 @@ func rewriteValueAMD64_OpAMD64SUBQload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SUBQload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBQload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -26836,24 +26797,24 @@ func rewriteValueAMD64_OpAMD64SUBQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SUBQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -26916,24 +26877,24 @@ func rewriteValueAMD64_OpAMD64SUBSDload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SUBSDload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBSDload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBSDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -27016,24 +26977,24 @@ func rewriteValueAMD64_OpAMD64SUBSSload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SUBSSload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (SUBSSload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64SUBSSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -27594,7 +27555,7 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
}
y := v_0.Args[1]
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64MOVLconst || v_0_0.AuxInt != 1 {
+ if v_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -27605,20 +27566,20 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
break
}
// match: (XORL (MOVLconst [c]) x)
- // cond: isUint32PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTCLconst [log2uint32(c)] x)
+ // cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTCLconst [int8(log32(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
- if !(isUint32PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128) {
continue
}
v.reset(OpAMD64BTCLconst)
- v.AuxInt = log2uint32(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
@@ -27632,9 +27593,9 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
if v_1.Op != OpAMD64MOVLconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt32(v_1.AuxInt)
v.reset(OpAMD64XORLconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -27648,17 +27609,17 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRLconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 32-c) {
continue
}
v.reset(OpAMD64ROLLconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -27673,17 +27634,17 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRWconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
continue
}
v.reset(OpAMD64ROLWconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -27698,17 +27659,17 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
if v_0.Op != OpAMD64SHLLconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRBconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
continue
}
v.reset(OpAMD64ROLBconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -27755,23 +27716,23 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value) bool {
func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
v_0 := v.Args[0]
// match: (XORLconst [c] x)
- // cond: isUint32PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTCLconst [log2uint32(c)] x)
+ // cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTCLconst [int8(log32(c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint32PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128) {
break
}
v.reset(OpAMD64BTCLconst)
- v.AuxInt = log2uint32(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETNE x))
// result: (SETEQ x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETNE {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETNE {
break
}
x := v_0.Args[0]
@@ -27782,7 +27743,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETEQ x))
// result: (SETNE x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETEQ {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETEQ {
break
}
x := v_0.Args[0]
@@ -27793,7 +27754,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETL x))
// result: (SETGE x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETL {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETL {
break
}
x := v_0.Args[0]
@@ -27804,7 +27765,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETGE x))
// result: (SETL x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETGE {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETGE {
break
}
x := v_0.Args[0]
@@ -27815,7 +27776,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETLE x))
// result: (SETG x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETLE {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETLE {
break
}
x := v_0.Args[0]
@@ -27826,7 +27787,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETG x))
// result: (SETLE x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETG {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETG {
break
}
x := v_0.Args[0]
@@ -27837,7 +27798,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETB x))
// result: (SETAE x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETB {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETB {
break
}
x := v_0.Args[0]
@@ -27848,7 +27809,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETAE x))
// result: (SETB x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETAE {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETAE {
break
}
x := v_0.Args[0]
@@ -27859,7 +27820,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETBE x))
// result: (SETA x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETBE {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETBE {
break
}
x := v_0.Args[0]
@@ -27870,7 +27831,7 @@ func rewriteValueAMD64_OpAMD64XORLconst(v *Value) bool {
// match: (XORLconst [1] (SETA x))
// result: (SETBE x)
for {
- if v.AuxInt != 1 || v_0.Op != OpAMD64SETA {
+ if auxIntToInt32(v.AuxInt) != 1 || v_0.Op != OpAMD64SETA {
break
}
x := v_0.Args[0]
@@ -27936,23 +27897,23 @@ func rewriteValueAMD64_OpAMD64XORLconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORLconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (XORLconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (XORLconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64XORLconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -27987,24 +27948,24 @@ func rewriteValueAMD64_OpAMD64XORLload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (XORLload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (XORLload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64XORLload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -28058,24 +28019,24 @@ func rewriteValueAMD64_OpAMD64XORLmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORLmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (XORLmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64XORLmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -28116,7 +28077,7 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool {
}
y := v_0.Args[1]
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpAMD64MOVQconst || v_0_0.AuxInt != 1 {
+ if v_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
continue
}
x := v_1
@@ -28128,19 +28089,19 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool {
}
// match: (XORQ (MOVQconst [c]) x)
// cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTCQconst [log2(c)] x)
+ // result: (BTCQconst [int8(log2(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 !(isUint64PowerOfTwo(c) && uint64(c) >= 128) {
continue
}
v.reset(OpAMD64BTCQconst)
- v.AuxInt = log2(c)
+ v.AuxInt = int8ToAuxInt(int8(log2(c)))
v.AddArg(x)
return true
}
@@ -28148,19 +28109,19 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool {
}
// match: (XORQ x (MOVQconst [c]))
// cond: is32Bit(c)
- // result: (XORQconst [c] x)
+ // result: (XORQconst [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 != OpAMD64MOVQconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpAMD64XORQconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -28174,17 +28135,17 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool {
if v_0.Op != OpAMD64SHLQconst {
continue
}
- c := v_0.AuxInt
+ c := auxIntToInt8(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpAMD64SHRQconst {
continue
}
- d := v_1.AuxInt
+ d := auxIntToInt8(v_1.AuxInt)
if x != v_1.Args[0] || !(d == 64-c) {
continue
}
v.reset(OpAMD64ROLQconst)
- v.AuxInt = c
+ v.AuxInt = int8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -28231,16 +28192,16 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value) bool {
func rewriteValueAMD64_OpAMD64XORQconst(v *Value) bool {
v_0 := v.Args[0]
// match: (XORQconst [c] x)
- // cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
- // result: (BTCQconst [log2(c)] x)
+ // cond: isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128
+ // result: (BTCQconst [int8(log32(c))] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(isUint64PowerOfTwo(c) && uint64(c) >= 128) {
+ if !(isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128) {
break
}
v.reset(OpAMD64BTCQconst)
- v.AuxInt = log2(c)
+ v.AuxInt = int8ToAuxInt(int8(log32(c)))
v.AddArg(x)
return true
}
@@ -28304,23 +28265,23 @@ func rewriteValueAMD64_OpAMD64XORQconstmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORQconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem)
- // cond: ValAndOff(valoff1).canAdd(off2)
- // result: (XORQconstmodify [ValAndOff(valoff1).add(off2)] {sym} base mem)
+ // cond: ValAndOff(valoff1).canAdd32(off2)
+ // result: (XORQconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
for {
- valoff1 := v.AuxInt
- sym := v.Aux
+ valoff1 := auxIntToValAndOff(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpAMD64ADDQconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
base := v_0.Args[0]
mem := v_1
- if !(ValAndOff(valoff1).canAdd(off2)) {
+ if !(ValAndOff(valoff1).canAdd32(off2)) {
break
}
v.reset(OpAMD64XORQconstmodify)
- v.AuxInt = ValAndOff(valoff1).add(off2)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(ValAndOff(valoff1).addOffset32(off2))
+ v.Aux = symToAux(sym)
v.AddArg2(base, mem)
return true
}
@@ -28355,24 +28316,24 @@ func rewriteValueAMD64_OpAMD64XORQload(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (XORQload [off1] {sym} val (ADDQconst [off2] base) mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (XORQload [off1+off2] {sym} val base 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)
base := v_1.Args[0]
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64XORQload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(val, base, mem)
return true
}
@@ -28426,24 +28387,24 @@ func rewriteValueAMD64_OpAMD64XORQmodify(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORQmodify [off1] {sym} (ADDQconst [off2] base) val mem)
- // cond: is32Bit(off1+off2)
+ // cond: is32Bit(int64(off1)+int64(off2))
// result: (XORQmodify [off1+off2] {sym} base val 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)
base := v_0.Args[0]
val := v_1
mem := v_2
- if !(is32Bit(off1 + off2)) {
+ if !(is32Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpAMD64XORQmodify)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(base, val, mem)
return true
}
@@ -30018,12 +29979,12 @@ func rewriteValueAMD64_OpHasCPUFeature(v *Value) bool {
// match: (HasCPUFeature {s})
// result: (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s})))
for {
- s := v.Aux
+ s := auxToSym(v.Aux)
v.reset(OpAMD64SETNE)
v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int32ToAuxInt(0)
v1 := b.NewValue0(v.Pos, OpAMD64LoweredHasCPUFeature, typ.UInt64)
- v1.Aux = s
+ v1.Aux = symToAux(s)
v0.AddArg(v1)
v.AddArg(v0)
return true
@@ -30489,10 +30450,10 @@ func rewriteValueAMD64_OpLocalAddr(v *Value) bool {
// match: (LocalAddr {sym} base _)
// result: (LEAQ {sym} base)
for {
- sym := v.Aux
+ sym := auxToSym(v.Aux)
base := v_0
v.reset(OpAMD64LEAQ)
- v.Aux = sym
+ v.Aux = symToAux(sym)
v.AddArg(base)
return true
}
@@ -31982,7 +31943,7 @@ func rewriteValueAMD64_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
@@ -31990,7 +31951,7 @@ func rewriteValueAMD64_OpPanicBounds(v *Value) bool {
break
}
v.reset(OpAMD64LoweredPanicBoundsA)
- v.AuxInt = kind
+ v.AuxInt = int64ToAuxInt(kind)
v.AddArg3(x, y, mem)
return true
}
@@ -31998,7 +31959,7 @@ func rewriteValueAMD64_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
@@ -32006,7 +31967,7 @@ func rewriteValueAMD64_OpPanicBounds(v *Value) bool {
break
}
v.reset(OpAMD64LoweredPanicBoundsB)
- v.AuxInt = kind
+ v.AuxInt = int64ToAuxInt(kind)
v.AddArg3(x, y, mem)
return true
}
@@ -32014,7 +31975,7 @@ func rewriteValueAMD64_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
@@ -32022,7 +31983,7 @@ func rewriteValueAMD64_OpPanicBounds(v *Value) bool {
break
}
v.reset(OpAMD64LoweredPanicBoundsC)
- v.AuxInt = kind
+ v.AuxInt = int64ToAuxInt(kind)
v.AddArg3(x, y, mem)
return true
}
@@ -34243,7 +34204,7 @@ func rewriteBlockAMD64(b *Block) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVLconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -34267,7 +34228,7 @@ func rewriteBlockAMD64(b *Block) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVQconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -34279,40 +34240,40 @@ func rewriteBlockAMD64(b *Block) bool {
break
}
// match: (EQ (TESTLconst [c] x))
- // cond: isUint32PowerOfTwo(c)
- // result: (UGE (BTLconst [log2uint32(c)] x))
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (UGE (BTLconst [int8(log32(c))] x))
for b.Controls[0].Op == OpAMD64TESTLconst {
v_0 := b.Controls[0]
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
}
// match: (EQ (TESTQconst [c] x))
- // cond: isUint64PowerOfTwo(c)
- // result: (UGE (BTQconst [log2(c)] x))
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (UGE (BTQconst [int8(log32(c))] x))
for b.Controls[0].Op == OpAMD64TESTQconst {
v_0 := b.Controls[0]
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
}
// match: (EQ (TESTQ (MOVQconst [c]) x))
// cond: isUint64PowerOfTwo(c)
- // result: (UGE (BTQconst [log2(c)] x))
+ // result: (UGE (BTQconst [int8(log2(c))] x))
for b.Controls[0].Op == OpAMD64TESTQ {
v_0 := b.Controls[0]
_ = v_0.Args[1]
@@ -34322,13 +34283,13 @@ func rewriteBlockAMD64(b *Block) bool {
if v_0_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_0_0.AuxInt
+ c := auxIntToInt64(v_0_0.AuxInt)
x := v_0_1
if !(isUint64PowerOfTwo(c)) {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34345,11 +34306,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -34358,7 +34319,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34375,11 +34336,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -34388,7 +34349,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34405,11 +34366,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -34418,7 +34379,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34435,11 +34396,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -34448,7 +34409,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34465,7 +34426,7 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -34474,7 +34435,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -34491,7 +34452,7 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -34500,7 +34461,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
b.resetWithControl(BlockAMD64UGE, v0)
return true
@@ -35046,7 +35007,7 @@ func rewriteBlockAMD64(b *Block) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVLconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -35070,7 +35031,7 @@ func rewriteBlockAMD64(b *Block) bool {
}
x := v_0_0.Args[1]
v_0_0_0 := v_0_0.Args[0]
- if v_0_0_0.Op != OpAMD64MOVQconst || v_0_0_0.AuxInt != 1 {
+ if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
continue
}
y := v_0_1
@@ -35082,40 +35043,40 @@ func rewriteBlockAMD64(b *Block) bool {
break
}
// match: (NE (TESTLconst [c] x))
- // cond: isUint32PowerOfTwo(c)
- // result: (ULT (BTLconst [log2uint32(c)] x))
+ // cond: isUint32PowerOfTwo(int64(c))
+ // result: (ULT (BTLconst [int8(log32(c))] x))
for b.Controls[0].Op == OpAMD64TESTLconst {
v_0 := b.Controls[0]
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint32PowerOfTwo(c)) {
+ if !(isUint32PowerOfTwo(int64(c))) {
break
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = log2uint32(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
}
// match: (NE (TESTQconst [c] x))
- // cond: isUint64PowerOfTwo(c)
- // result: (ULT (BTQconst [log2(c)] x))
+ // cond: isUint64PowerOfTwo(int64(c))
+ // result: (ULT (BTQconst [int8(log32(c))] x))
for b.Controls[0].Op == OpAMD64TESTQconst {
v_0 := b.Controls[0]
- c := v_0.AuxInt
+ c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(isUint64PowerOfTwo(c)) {
+ if !(isUint64PowerOfTwo(int64(c))) {
break
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log32(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
}
// match: (NE (TESTQ (MOVQconst [c]) x))
// cond: isUint64PowerOfTwo(c)
- // result: (ULT (BTQconst [log2(c)] x))
+ // result: (ULT (BTQconst [int8(log2(c))] x))
for b.Controls[0].Op == OpAMD64TESTQ {
v_0 := b.Controls[0]
_ = v_0.Args[1]
@@ -35125,13 +35086,13 @@ func rewriteBlockAMD64(b *Block) bool {
if v_0_0.Op != OpAMD64MOVQconst {
continue
}
- c := v_0_0.AuxInt
+ c := auxIntToInt64(v_0_0.AuxInt)
x := v_0_1
if !(isUint64PowerOfTwo(c)) {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = log2(c)
+ v0.AuxInt = int8ToAuxInt(int8(log2(c)))
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35148,11 +35109,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHLQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -35161,7 +35122,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35178,11 +35139,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHLLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHLLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHRQconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHRQconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -35191,7 +35152,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35208,11 +35169,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLQconst || z1_0.AuxInt != 63 {
+ if z1_0.Op != OpAMD64SHLQconst || auxIntToInt8(z1_0.AuxInt) != 63 {
continue
}
x := z1_0.Args[0]
@@ -35221,7 +35182,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35238,11 +35199,11 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
z1_0 := z1.Args[0]
- if z1_0.Op != OpAMD64SHLLconst || z1_0.AuxInt != 31 {
+ if z1_0.Op != OpAMD64SHLLconst || auxIntToInt8(z1_0.AuxInt) != 31 {
continue
}
x := z1_0.Args[0]
@@ -35251,7 +35212,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 0
+ v0.AuxInt = int8ToAuxInt(0)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35268,7 +35229,7 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRQconst || z1.AuxInt != 63 {
+ if z1.Op != OpAMD64SHRQconst || auxIntToInt8(z1.AuxInt) != 63 {
continue
}
x := z1.Args[0]
@@ -35277,7 +35238,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTQconst, types.TypeFlags)
- v0.AuxInt = 63
+ v0.AuxInt = int8ToAuxInt(63)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
@@ -35294,7 +35255,7 @@ func rewriteBlockAMD64(b *Block) bool {
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 {
z1 := v_0_0
- if z1.Op != OpAMD64SHRLconst || z1.AuxInt != 31 {
+ if z1.Op != OpAMD64SHRLconst || auxIntToInt8(z1.AuxInt) != 31 {
continue
}
x := z1.Args[0]
@@ -35303,7 +35264,7 @@ func rewriteBlockAMD64(b *Block) bool {
continue
}
v0 := b.NewValue0(v_0.Pos, OpAMD64BTLconst, types.TypeFlags)
- v0.AuxInt = 31
+ v0.AuxInt = int8ToAuxInt(31)
v0.AddArg(x)
b.resetWithControl(BlockAMD64ULT, v0)
return true
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index 453578aa9a..0fb86b6bdd 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -1285,7 +1285,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
- // match: (ADD (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (ADD (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x (NEG <t> y))
for {
@@ -1307,7 +1307,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
@@ -1355,7 +1355,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
- // match: (ADD (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (ADD (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x y)
for {
@@ -1377,7 +1377,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -1423,7 +1423,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
- // match: (ADD (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (ADD (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x (NEG <t> y))
for {
@@ -1445,7 +1445,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
@@ -1494,7 +1494,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
- // match: (ADD (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (ADD (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x y)
for {
@@ -1520,7 +1520,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -3178,38 +3178,38 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (CSEL {cc} x (MOVDconst [0]) flag)
- // result: (CSEL0 {cc} x flag)
+ // match: (CSEL [cc] x (MOVDconst [0]) flag)
+ // result: (CSEL0 [cc] x flag)
for {
- cc := v.Aux
+ cc := auxIntToOp(v.AuxInt)
x := v_0
- if v_1.Op != OpARM64MOVDconst || v_1.AuxInt != 0 {
+ if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
flag := v_2
v.reset(OpARM64CSEL0)
- v.Aux = cc
+ v.AuxInt = opToAuxInt(cc)
v.AddArg2(x, flag)
return true
}
- // match: (CSEL {cc} (MOVDconst [0]) y flag)
- // result: (CSEL0 {arm64Negate(cc.(Op))} y flag)
+ // match: (CSEL [cc] (MOVDconst [0]) y flag)
+ // result: (CSEL0 [arm64Negate(cc)] y flag)
for {
- cc := v.Aux
- if v_0.Op != OpARM64MOVDconst || v_0.AuxInt != 0 {
+ cc := auxIntToOp(v.AuxInt)
+ if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
y := v_1
flag := v_2
v.reset(OpARM64CSEL0)
- v.Aux = arm64Negate(cc.(Op))
+ v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg2(y, flag)
return true
}
- // match: (CSEL {cc} x y (InvertFlags cmp))
- // result: (CSEL {arm64Invert(cc)} x y cmp)
+ // match: (CSEL [cc] x y (InvertFlags cmp))
+ // result: (CSEL [arm64Invert(cc)] x y cmp)
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64InvertFlags {
@@ -3217,15 +3217,15 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
}
cmp := v_2.Args[0]
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(arm64Invert(cc))
+ v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg3(x, y, cmp)
return true
}
- // match: (CSEL {cc} x _ flag)
+ // match: (CSEL [cc] x _ flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_2
if !(ccARM64Eval(cc, flag) > 0) {
@@ -3234,11 +3234,11 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (CSEL {cc} _ y flag)
+ // match: (CSEL [cc] _ y flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: y
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
y := v_1
flag := v_2
if !(ccARM64Eval(cc, flag) < 0) {
@@ -3247,11 +3247,11 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
v.copyOf(y)
return true
}
- // match: (CSEL {cc} x y (CMPWconst [0] boolval))
+ // match: (CSEL [cc] x y (CMPWconst [0] boolval))
// cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
- // result: (CSEL {boolval.Op} x y flagArg(boolval))
+ // result: (CSEL [boolval.Op] x y flagArg(boolval))
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
@@ -3262,15 +3262,15 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
break
}
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(boolval.Op)
+ v.AuxInt = opToAuxInt(boolval.Op)
v.AddArg3(x, y, flagArg(boolval))
return true
}
- // match: (CSEL {cc} x y (CMPWconst [0] boolval))
+ // match: (CSEL [cc] x y (CMPWconst [0] boolval))
// cond: cc == OpARM64Equal && flagArg(boolval) != nil
- // result: (CSEL {arm64Negate(boolval.Op)} x y flagArg(boolval))
+ // result: (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
@@ -3281,7 +3281,7 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
break
}
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(arm64Negate(boolval.Op))
+ v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
v.AddArg3(x, y, flagArg(boolval))
return true
}
@@ -3290,25 +3290,25 @@ func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (CSEL0 {cc} x (InvertFlags cmp))
- // result: (CSEL0 {arm64Invert(cc)} x cmp)
+ // match: (CSEL0 [cc] x (InvertFlags cmp))
+ // result: (CSEL0 [arm64Invert(cc)] x cmp)
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64InvertFlags {
break
}
cmp := v_1.Args[0]
v.reset(OpARM64CSEL0)
- v.Aux = cCopToAux(arm64Invert(cc))
+ v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg2(x, cmp)
return true
}
- // match: (CSEL0 {cc} x flag)
+ // match: (CSEL0 [cc] x flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_1
if !(ccARM64Eval(cc, flag) > 0) {
@@ -3317,11 +3317,11 @@ func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (CSEL0 {cc} _ flag)
+ // match: (CSEL0 [cc] _ flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (MOVDconst [0])
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
flag := v_1
if !(ccARM64Eval(cc, flag) < 0) {
break
@@ -3330,11 +3330,11 @@ func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
v.AuxInt = int64ToAuxInt(0)
return true
}
- // match: (CSEL0 {cc} x (CMPWconst [0] boolval))
+ // match: (CSEL0 [cc] x (CMPWconst [0] boolval))
// cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
- // result: (CSEL0 {boolval.Op} x flagArg(boolval))
+ // result: (CSEL0 [boolval.Op] x flagArg(boolval))
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
break
@@ -3344,15 +3344,15 @@ func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
break
}
v.reset(OpARM64CSEL0)
- v.Aux = cCopToAux(boolval.Op)
+ v.AuxInt = opToAuxInt(boolval.Op)
v.AddArg2(x, flagArg(boolval))
return true
}
- // match: (CSEL0 {cc} x (CMPWconst [0] boolval))
+ // match: (CSEL0 [cc] x (CMPWconst [0] boolval))
// cond: cc == OpARM64Equal && flagArg(boolval) != nil
- // result: (CSEL0 {arm64Negate(boolval.Op)} x flagArg(boolval))
+ // result: (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
for {
- cc := auxToCCop(v.Aux)
+ cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
break
@@ -3362,7 +3362,7 @@ func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
break
}
v.reset(OpARM64CSEL0)
- v.Aux = cCopToAux(arm64Negate(boolval.Op))
+ v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
v.AddArg2(x, flagArg(boolval))
return true
}
@@ -15043,7 +15043,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
}
break
}
- // match: (OR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (OR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x (NEG <t> y))
for {
@@ -15065,7 +15065,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
@@ -15113,7 +15113,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
}
break
}
- // match: (OR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (OR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x y)
for {
@@ -15135,7 +15135,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -15181,7 +15181,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
}
break
}
- // match: (OR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (OR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x (NEG <t> y))
for {
@@ -15203,7 +15203,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
@@ -15252,7 +15252,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
}
break
}
- // match: (OR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (OR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x y)
for {
@@ -15278,7 +15278,7 @@ func rewriteValueARM64_OpARM64OR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -20713,7 +20713,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
}
break
}
- // match: (XOR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (XOR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x (NEG <t> y))
for {
@@ -20735,7 +20735,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
@@ -20783,7 +20783,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
}
break
}
- // match: (XOR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> {cc} (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
+ // match: (XOR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
// cond: cc == OpARM64LessThanU
// result: (ROR x y)
for {
@@ -20805,7 +20805,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -20851,7 +20851,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
}
break
}
- // match: (XOR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (XOR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x (NEG <t> y))
for {
@@ -20873,7 +20873,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
@@ -20922,7 +20922,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
}
break
}
- // match: (XOR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> {cc} (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
+ // match: (XOR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
// cond: cc == OpARM64LessThanU
// result: (RORW x y)
for {
@@ -20948,7 +20948,7 @@ func rewriteValueARM64_OpARM64XOR(v *Value) bool {
if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
continue
}
- cc := auxToCCop(v_1.Aux)
+ cc := auxIntToOp(v_1.AuxInt)
_ = v_1.Args[1]
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64SLL {
@@ -21471,7 +21471,7 @@ func rewriteValueARM64_OpCondSelect(v *Value) bool {
b := v.Block
// match: (CondSelect x y boolval)
// cond: flagArg(boolval) != nil
- // result: (CSEL {boolval.Op} x y flagArg(boolval))
+ // result: (CSEL [boolval.Op] x y flagArg(boolval))
for {
x := v_0
y := v_1
@@ -21480,13 +21480,13 @@ func rewriteValueARM64_OpCondSelect(v *Value) bool {
break
}
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(boolval.Op)
+ v.AuxInt = opToAuxInt(boolval.Op)
v.AddArg3(x, y, flagArg(boolval))
return true
}
// match: (CondSelect x y boolval)
// cond: flagArg(boolval) == nil
- // result: (CSEL {OpARM64NotEqual} x y (CMPWconst [0] boolval))
+ // result: (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
for {
x := v_0
y := v_1
@@ -21495,7 +21495,7 @@ func rewriteValueARM64_OpCondSelect(v *Value) bool {
break
}
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64NotEqual)
+ v.AuxInt = opToAuxInt(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(0)
v0.AddArg(boolval)
@@ -22734,13 +22734,13 @@ func rewriteValueARM64_OpLsh16x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh16x16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
@@ -22760,13 +22760,13 @@ func rewriteValueARM64_OpLsh16x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh16x32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
@@ -22785,13 +22785,13 @@ func rewriteValueARM64_OpLsh16x64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Lsh16x64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v0.AddArg2(x, y)
v1 := b.NewValue0(v.Pos, OpConst64, t)
@@ -22809,13 +22809,13 @@ func rewriteValueARM64_OpLsh16x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh16x8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
@@ -22835,13 +22835,13 @@ func rewriteValueARM64_OpLsh32x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh32x16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
@@ -22861,13 +22861,13 @@ func rewriteValueARM64_OpLsh32x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh32x32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
@@ -22886,13 +22886,13 @@ func rewriteValueARM64_OpLsh32x64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Lsh32x64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v0.AddArg2(x, y)
v1 := b.NewValue0(v.Pos, OpConst64, t)
@@ -22910,13 +22910,13 @@ func rewriteValueARM64_OpLsh32x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh32x8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
@@ -22936,13 +22936,13 @@ func rewriteValueARM64_OpLsh64x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh64x16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
@@ -22962,13 +22962,13 @@ func rewriteValueARM64_OpLsh64x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh64x32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
@@ -22987,13 +22987,13 @@ func rewriteValueARM64_OpLsh64x64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Lsh64x64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v0.AddArg2(x, y)
v1 := b.NewValue0(v.Pos, OpConst64, t)
@@ -23011,13 +23011,13 @@ func rewriteValueARM64_OpLsh64x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh64x8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
@@ -23037,13 +23037,13 @@ func rewriteValueARM64_OpLsh8x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh8x16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
@@ -23063,13 +23063,13 @@ func rewriteValueARM64_OpLsh8x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh8x32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
@@ -23088,13 +23088,13 @@ func rewriteValueARM64_OpLsh8x64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Lsh8x64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v0.AddArg2(x, y)
v1 := b.NewValue0(v.Pos, OpConst64, t)
@@ -23112,13 +23112,13 @@ func rewriteValueARM64_OpLsh8x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Lsh8x8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
@@ -23932,13 +23932,13 @@ func rewriteValueARM64_OpRsh16Ux16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16Ux16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(x)
@@ -23960,13 +23960,13 @@ func rewriteValueARM64_OpRsh16Ux32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16Ux32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(x)
@@ -23988,13 +23988,13 @@ func rewriteValueARM64_OpRsh16Ux64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16Ux64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(x)
@@ -24014,13 +24014,13 @@ func rewriteValueARM64_OpRsh16Ux8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16Ux8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(x)
@@ -24042,7 +24042,7 @@ func rewriteValueARM64_OpRsh16x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16x16 x y)
- // result: (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+ // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
for {
x := v_0
y := v_1
@@ -24050,7 +24050,7 @@ func rewriteValueARM64_OpRsh16x16(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24069,7 +24069,7 @@ func rewriteValueARM64_OpRsh16x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16x32 x y)
- // result: (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+ // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
for {
x := v_0
y := v_1
@@ -24077,7 +24077,7 @@ func rewriteValueARM64_OpRsh16x32(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24096,7 +24096,7 @@ func rewriteValueARM64_OpRsh16x64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16x64 x y)
- // result: (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+ // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
for {
x := v_0
y := v_1
@@ -24104,7 +24104,7 @@ func rewriteValueARM64_OpRsh16x64(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
v2.AuxInt = int64ToAuxInt(63)
v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -24121,7 +24121,7 @@ func rewriteValueARM64_OpRsh16x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh16x8 x y)
- // result: (SRA (SignExt16to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+ // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
for {
x := v_0
y := v_1
@@ -24129,7 +24129,7 @@ func rewriteValueARM64_OpRsh16x8(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24148,13 +24148,13 @@ func rewriteValueARM64_OpRsh32Ux16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32Ux16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(x)
@@ -24176,13 +24176,13 @@ func rewriteValueARM64_OpRsh32Ux32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32Ux32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(x)
@@ -24204,13 +24204,13 @@ func rewriteValueARM64_OpRsh32Ux64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32Ux64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(x)
@@ -24230,13 +24230,13 @@ func rewriteValueARM64_OpRsh32Ux8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32Ux8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(x)
@@ -24258,7 +24258,7 @@ func rewriteValueARM64_OpRsh32x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32x16 x y)
- // result: (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+ // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
for {
x := v_0
y := v_1
@@ -24266,7 +24266,7 @@ func rewriteValueARM64_OpRsh32x16(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24285,7 +24285,7 @@ func rewriteValueARM64_OpRsh32x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32x32 x y)
- // result: (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+ // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
for {
x := v_0
y := v_1
@@ -24293,7 +24293,7 @@ func rewriteValueARM64_OpRsh32x32(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24312,7 +24312,7 @@ func rewriteValueARM64_OpRsh32x64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32x64 x y)
- // result: (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+ // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
for {
x := v_0
y := v_1
@@ -24320,7 +24320,7 @@ func rewriteValueARM64_OpRsh32x64(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
v2.AuxInt = int64ToAuxInt(63)
v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -24337,7 +24337,7 @@ func rewriteValueARM64_OpRsh32x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh32x8 x y)
- // result: (SRA (SignExt32to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+ // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
for {
x := v_0
y := v_1
@@ -24345,7 +24345,7 @@ func rewriteValueARM64_OpRsh32x8(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24364,13 +24364,13 @@ func rewriteValueARM64_OpRsh64Ux16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64Ux16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
@@ -24390,13 +24390,13 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64Ux32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
@@ -24415,13 +24415,13 @@ func rewriteValueARM64_OpRsh64Ux64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Rsh64Ux64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v0.AddArg2(x, y)
v1 := b.NewValue0(v.Pos, OpConst64, t)
@@ -24439,13 +24439,13 @@ func rewriteValueARM64_OpRsh64Ux8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64Ux8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
@@ -24465,13 +24465,13 @@ func rewriteValueARM64_OpRsh64x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64x16 x y)
- // result: (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+ // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
for {
x := v_0
y := v_1
v.reset(OpARM64SRA)
v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v0.Aux = cCopToAux(OpARM64LessThanU)
+ v0.AuxInt = opToAuxInt(OpARM64LessThanU)
v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v1.AddArg(y)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24490,13 +24490,13 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64x32 x y)
- // result: (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+ // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
for {
x := v_0
y := v_1
v.reset(OpARM64SRA)
v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v0.Aux = cCopToAux(OpARM64LessThanU)
+ v0.AuxInt = opToAuxInt(OpARM64LessThanU)
v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v1.AddArg(y)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24514,13 +24514,13 @@ func rewriteValueARM64_OpRsh64x64(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Rsh64x64 x y)
- // result: (SRA x (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+ // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
for {
x := v_0
y := v_1
v.reset(OpARM64SRA)
v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v0.Aux = cCopToAux(OpARM64LessThanU)
+ v0.AuxInt = opToAuxInt(OpARM64LessThanU)
v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
v1.AuxInt = int64ToAuxInt(63)
v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -24537,13 +24537,13 @@ func rewriteValueARM64_OpRsh64x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh64x8 x y)
- // result: (SRA x (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+ // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
for {
x := v_0
y := v_1
v.reset(OpARM64SRA)
v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v0.Aux = cCopToAux(OpARM64LessThanU)
+ v0.AuxInt = opToAuxInt(OpARM64LessThanU)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(y)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24562,13 +24562,13 @@ func rewriteValueARM64_OpRsh8Ux16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8Ux16 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(x)
@@ -24590,13 +24590,13 @@ func rewriteValueARM64_OpRsh8Ux32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8Ux32 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(x)
@@ -24618,13 +24618,13 @@ func rewriteValueARM64_OpRsh8Ux64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8Ux64 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(x)
@@ -24644,13 +24644,13 @@ func rewriteValueARM64_OpRsh8Ux8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8Ux8 <t> x y)
- // result: (CSEL {OpARM64LessThanU} (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+ // result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
for {
t := v.Type
x := v_0
y := v_1
v.reset(OpARM64CSEL)
- v.Aux = cCopToAux(OpARM64LessThanU)
+ v.AuxInt = opToAuxInt(OpARM64LessThanU)
v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v1.AddArg(x)
@@ -24672,7 +24672,7 @@ func rewriteValueARM64_OpRsh8x16(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8x16 x y)
- // result: (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+ // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
for {
x := v_0
y := v_1
@@ -24680,7 +24680,7 @@ func rewriteValueARM64_OpRsh8x16(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24699,7 +24699,7 @@ func rewriteValueARM64_OpRsh8x32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8x32 x y)
- // result: (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+ // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
for {
x := v_0
y := v_1
@@ -24707,7 +24707,7 @@ func rewriteValueARM64_OpRsh8x32(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
@@ -24726,7 +24726,7 @@ func rewriteValueARM64_OpRsh8x64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8x64 x y)
- // result: (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+ // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
for {
x := v_0
y := v_1
@@ -24734,7 +24734,7 @@ func rewriteValueARM64_OpRsh8x64(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
v2.AuxInt = int64ToAuxInt(63)
v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
@@ -24751,7 +24751,7 @@ func rewriteValueARM64_OpRsh8x8(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (Rsh8x8 x y)
- // result: (SRA (SignExt8to64 x) (CSEL {OpARM64LessThanU} <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+ // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
for {
x := v_0
y := v_1
@@ -24759,7 +24759,7 @@ func rewriteValueARM64_OpRsh8x8(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
- v1.Aux = cCopToAux(OpARM64LessThanU)
+ v1.AuxInt = opToAuxInt(OpARM64LessThanU)
v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
v2.AddArg(y)
v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 7704b80dc6..152cdfdf4d 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -428,8 +428,6 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPPC64ADD(v)
case OpPPC64ADDconst:
return rewriteValuePPC64_OpPPC64ADDconst(v)
- case OpPPC64ADDconstForCarry:
- return rewriteValuePPC64_OpPPC64ADDconstForCarry(v)
case OpPPC64AND:
return rewriteValuePPC64_OpPPC64AND(v)
case OpPPC64ANDN:
@@ -570,8 +568,8 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPPC64MOVWstorezero(v)
case OpPPC64MTVSRD:
return rewriteValuePPC64_OpPPC64MTVSRD(v)
- case OpPPC64MaskIfNotCarry:
- return rewriteValuePPC64_OpPPC64MaskIfNotCarry(v)
+ case OpPPC64NEG:
+ return rewriteValuePPC64_OpPPC64NEG(v)
case OpPPC64NOR:
return rewriteValuePPC64_OpPPC64NOR(v)
case OpPPC64NotEqual:
@@ -600,6 +598,8 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPPC64SRW(v)
case OpPPC64SUB:
return rewriteValuePPC64_OpPPC64SUB(v)
+ case OpPPC64SUBFCconst:
+ return rewriteValuePPC64_OpPPC64SUBFCconst(v)
case OpPPC64XOR:
return rewriteValuePPC64_OpPPC64XOR(v)
case OpPPC64XORconst:
@@ -1025,15 +1025,14 @@ func rewriteValuePPC64_OpBitLen32(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (BitLen32 x)
- // result: (SUB (MOVDconst [32]) (CNTLZW <typ.Int> x))
+ // result: (SUBFCconst [32] (CNTLZW <typ.Int> x))
for {
x := v_0
- v.reset(OpPPC64SUB)
- v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
- v0.AuxInt = int64ToAuxInt(32)
- v1 := b.NewValue0(v.Pos, OpPPC64CNTLZW, typ.Int)
- v1.AddArg(x)
- v.AddArg2(v0, v1)
+ v.reset(OpPPC64SUBFCconst)
+ v.AuxInt = int64ToAuxInt(32)
+ v0 := b.NewValue0(v.Pos, OpPPC64CNTLZW, typ.Int)
+ v0.AddArg(x)
+ v.AddArg(v0)
return true
}
}
@@ -1042,15 +1041,14 @@ func rewriteValuePPC64_OpBitLen64(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (BitLen64 x)
- // result: (SUB (MOVDconst [64]) (CNTLZD <typ.Int> x))
+ // result: (SUBFCconst [64] (CNTLZD <typ.Int> x))
for {
x := v_0
- v.reset(OpPPC64SUB)
- v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
- v0.AuxInt = int64ToAuxInt(64)
- v1 := b.NewValue0(v.Pos, OpPPC64CNTLZD, typ.Int)
- v1.AddArg(x)
- v.AddArg2(v0, v1)
+ v.reset(OpPPC64SUBFCconst)
+ v.AuxInt = int64ToAuxInt(64)
+ v0 := b.NewValue0(v.Pos, OpPPC64CNTLZD, typ.Int)
+ v0.AddArg(x)
+ v.AddArg(v0)
return true
}
}
@@ -3961,6 +3959,76 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
}
break
}
+ // match: (ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+ // result: (ROTL x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLD {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRD {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTL)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
+ // match: (ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+ // result: (ROTLW x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLW {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRW {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTLW)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
// match: (ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
// result: (ROTLW x y)
for {
@@ -4073,38 +4141,22 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool {
v.AddArg(x)
return true
}
- return false
-}
-func rewriteValuePPC64_OpPPC64ADDconstForCarry(v *Value) bool {
- v_0 := v.Args[0]
- // match: (ADDconstForCarry [c] (MOVDconst [d]))
- // cond: c < 0 && (c < 0 || int64(c) + d >= 0)
- // result: (FlagCarryClear)
- for {
- c := auxIntToInt16(v.AuxInt)
- if v_0.Op != OpPPC64MOVDconst {
- break
- }
- d := auxIntToInt64(v_0.AuxInt)
- if !(c < 0 && (c < 0 || int64(c)+d >= 0)) {
- break
- }
- v.reset(OpPPC64FlagCarryClear)
- return true
- }
- // match: (ADDconstForCarry [c] (MOVDconst [d]))
- // cond: c < 0 && c >= 0 && int64(c) + d < 0
- // result: (FlagCarrySet)
+ // match: (ADDconst [c] (SUBFCconst [d] x))
+ // cond: is32Bit(c+d)
+ // result: (SUBFCconst [c+d] x)
for {
- c := auxIntToInt16(v.AuxInt)
- if v_0.Op != OpPPC64MOVDconst {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpPPC64SUBFCconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
- if !(c < 0 && c >= 0 && int64(c)+d < 0) {
+ x := v_0.Args[0]
+ if !(is32Bit(c + d)) {
break
}
- v.reset(OpPPC64FlagCarrySet)
+ v.reset(OpPPC64SUBFCconst)
+ v.AuxInt = int64ToAuxInt(c + d)
+ v.AddArg(x)
return true
}
return false
@@ -10374,46 +10426,40 @@ func rewriteValuePPC64_OpPPC64MTVSRD(v *Value) bool {
}
return false
}
-func rewriteValuePPC64_OpPPC64MaskIfNotCarry(v *Value) bool {
+func rewriteValuePPC64_OpPPC64NEG(v *Value) bool {
v_0 := v.Args[0]
- // match: (MaskIfNotCarry (ADDconstForCarry [c] (ANDconst [d] _)))
- // cond: c < 0 && d > 0 && int64(c) + d < 0
- // result: (MOVDconst [-1])
+ // match: (NEG (ADDconst [c] x))
+ // cond: is32Bit(-c)
+ // result: (SUBFCconst [-c] x)
for {
- if v_0.Op != OpPPC64ADDconstForCarry {
- break
- }
- c := auxIntToInt16(v_0.AuxInt)
- v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpPPC64ANDconst {
+ if v_0.Op != OpPPC64ADDconst {
break
}
- d := auxIntToInt64(v_0_0.AuxInt)
- if !(c < 0 && d > 0 && int64(c)+d < 0) {
+ c := auxIntToInt64(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(is32Bit(-c)) {
break
}
- v.reset(OpPPC64MOVDconst)
- v.AuxInt = int64ToAuxInt(-1)
+ v.reset(OpPPC64SUBFCconst)
+ v.AuxInt = int64ToAuxInt(-c)
+ v.AddArg(x)
return true
}
- // match: (MaskIfNotCarry (FlagCarrySet))
- // result: (MOVDconst [0])
+ // match: (NEG (SUBFCconst [c] x))
+ // cond: is32Bit(-c)
+ // result: (ADDconst [-c] x)
for {
- if v_0.Op != OpPPC64FlagCarrySet {
+ if v_0.Op != OpPPC64SUBFCconst {
break
}
- v.reset(OpPPC64MOVDconst)
- v.AuxInt = int64ToAuxInt(0)
- return true
- }
- // match: (MaskIfNotCarry (FlagCarryClear))
- // result: (MOVDconst [-1])
- for {
- if v_0.Op != OpPPC64FlagCarryClear {
+ c := auxIntToInt64(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(is32Bit(-c)) {
break
}
- v.reset(OpPPC64MOVDconst)
- v.AuxInt = int64ToAuxInt(-1)
+ v.reset(OpPPC64ADDconst)
+ v.AuxInt = int64ToAuxInt(-c)
+ v.AddArg(x)
return true
}
return false
@@ -10592,6 +10638,76 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
}
break
}
+ // match: ( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+ // result: (ROTL x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLD {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRD {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTL)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
+ // match: ( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+ // result: (ROTLW x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLW {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRW {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTLW)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
// match: ( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
// result: (ROTLW x y)
for {
@@ -12191,6 +12307,69 @@ func rewriteValuePPC64_OpPPC64SUB(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (SUB (MOVDconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (SUBFCconst [c] x)
+ for {
+ if v_0.Op != OpPPC64MOVDconst {
+ break
+ }
+ c := auxIntToInt64(v_0.AuxInt)
+ x := v_1
+ if !(is32Bit(c)) {
+ break
+ }
+ v.reset(OpPPC64SUBFCconst)
+ v.AuxInt = int64ToAuxInt(c)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64SUBFCconst(v *Value) bool {
+ v_0 := v.Args[0]
+ // match: (SUBFCconst [c] (NEG x))
+ // result: (ADDconst [c] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpPPC64NEG {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpPPC64ADDconst)
+ v.AuxInt = int64ToAuxInt(c)
+ v.AddArg(x)
+ return true
+ }
+ // match: (SUBFCconst [c] (SUBFCconst [d] x))
+ // cond: is32Bit(c-d)
+ // result: (ADDconst [c-d] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpPPC64SUBFCconst {
+ break
+ }
+ d := auxIntToInt64(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(is32Bit(c - d)) {
+ break
+ }
+ v.reset(OpPPC64ADDconst)
+ v.AuxInt = int64ToAuxInt(c - d)
+ v.AddArg(x)
+ return true
+ }
+ // match: (SUBFCconst [0] x)
+ // result: (NEG x)
+ for {
+ if auxIntToInt64(v.AuxInt) != 0 {
+ break
+ }
+ x := v_0
+ v.reset(OpPPC64NEG)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
@@ -12286,6 +12465,76 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
}
break
}
+ // match: (XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+ // result: (ROTL x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLD {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRD {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTL)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
+ // match: (XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+ // result: (ROTLW x y)
+ for {
+ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+ if v_0.Op != OpPPC64SLW {
+ continue
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ v_0_1 := v_0.Args[1]
+ if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+ continue
+ }
+ y := v_0_1.Args[0]
+ if v_1.Op != OpPPC64SRW {
+ continue
+ }
+ _ = v_1.Args[1]
+ if x != v_1.Args[0] {
+ continue
+ }
+ v_1_1 := v_1.Args[1]
+ if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
+ continue
+ }
+ v_1_1_0 := v_1_1.Args[0]
+ if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
+ continue
+ }
+ v.reset(OpPPC64ROTLW)
+ v.AddArg2(x, y)
+ return true
+ }
+ break
+ }
// match: (XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
// result: (ROTLW x y)
for {
@@ -13257,6 +13506,28 @@ func rewriteValuePPC64_OpRsh32Ux64(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ // result: (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 31 {
+ break
+ }
+ y := v_1_0.Args[0]
+ v.reset(OpPPC64SRW)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(32)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(31)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
for {
@@ -13294,6 +13565,37 @@ func rewriteValuePPC64_OpRsh32Ux64(v *Value) bool {
}
break
}
+ // match: (Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31]))))
+ // result: (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
+ break
+ }
+ _ = v_1_0.Args[1]
+ v_1_0_0 := v_1_0.Args[0]
+ v_1_0_1 := v_1_0.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+ y := v_1_0_0
+ if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 31 {
+ continue
+ }
+ v.reset(OpPPC64SRW)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(32)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(31)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (Rsh32Ux64 x y)
// result: (SRW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
for {
@@ -13564,6 +13866,28 @@ func rewriteValuePPC64_OpRsh32x64(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (Rsh32x64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ // result: (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 31 {
+ break
+ }
+ y := v_1_0.Args[0]
+ v.reset(OpPPC64SRAW)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(32)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(31)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
for {
@@ -13601,6 +13925,37 @@ func rewriteValuePPC64_OpRsh32x64(v *Value) bool {
}
break
}
+ // match: (Rsh32x64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31]))))
+ // result: (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
+ break
+ }
+ _ = v_1_0.Args[1]
+ v_1_0_0 := v_1_0.Args[0]
+ v_1_0_1 := v_1_0.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+ y := v_1_0_0
+ if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 31 {
+ continue
+ }
+ v.reset(OpPPC64SRAW)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(32)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(31)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (Rsh32x64 x y)
// result: (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
for {
@@ -13869,6 +14224,28 @@ func rewriteValuePPC64_OpRsh64Ux64(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ // result: (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 63 {
+ break
+ }
+ y := v_1_0.Args[0]
+ v.reset(OpPPC64SRD)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(64)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(63)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
for {
@@ -13906,6 +14283,37 @@ func rewriteValuePPC64_OpRsh64Ux64(v *Value) bool {
}
break
}
+ // match: (Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63]))))
+ // result: (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
+ break
+ }
+ _ = v_1_0.Args[1]
+ v_1_0_0 := v_1_0.Args[0]
+ v_1_0_1 := v_1_0.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+ y := v_1_0_0
+ if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 63 {
+ continue
+ }
+ v.reset(OpPPC64SRD)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(64)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(63)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (Rsh64Ux64 x y)
// result: (SRD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
for {
@@ -14176,6 +14584,28 @@ func rewriteValuePPC64_OpRsh64x64(v *Value) bool {
v.AddArg2(x, v0)
return true
}
+ // match: (Rsh64x64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ // result: (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 63 {
+ break
+ }
+ y := v_1_0.Args[0]
+ v.reset(OpPPC64SRAD)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(64)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(63)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
for {
@@ -14213,6 +14643,37 @@ func rewriteValuePPC64_OpRsh64x64(v *Value) bool {
}
break
}
+ // match: (Rsh64x64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63]))))
+ // result: (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
+ for {
+ x := v_0
+ if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
+ break
+ }
+ v_1_0 := v_1.Args[0]
+ if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
+ break
+ }
+ _ = v_1_0.Args[1]
+ v_1_0_0 := v_1_0.Args[0]
+ v_1_0_1 := v_1_0.Args[1]
+ for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+ y := v_1_0_0
+ if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 63 {
+ continue
+ }
+ v.reset(OpPPC64SRAD)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
+ v0.AuxInt = int64ToAuxInt(64)
+ v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
+ v1.AuxInt = int64ToAuxInt(63)
+ v1.AddArg(y)
+ v0.AddArg(v1)
+ v.AddArg2(x, v0)
+ return true
+ }
+ break
+ }
// match: (Rsh64x64 x y)
// result: (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
for {
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index 536f8db320..78a57c2388 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -3,6 +3,7 @@
package ssa
+import "math"
import "cmd/compile/internal/types"
import "cmd/internal/obj/s390x"
@@ -586,20 +587,12 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XFCMPS(v)
case OpS390XFMOVDload:
return rewriteValueS390X_OpS390XFMOVDload(v)
- case OpS390XFMOVDloadidx:
- return rewriteValueS390X_OpS390XFMOVDloadidx(v)
case OpS390XFMOVDstore:
return rewriteValueS390X_OpS390XFMOVDstore(v)
- case OpS390XFMOVDstoreidx:
- return rewriteValueS390X_OpS390XFMOVDstoreidx(v)
case OpS390XFMOVSload:
return rewriteValueS390X_OpS390XFMOVSload(v)
- case OpS390XFMOVSloadidx:
- return rewriteValueS390X_OpS390XFMOVSloadidx(v)
case OpS390XFMOVSstore:
return rewriteValueS390X_OpS390XFMOVSstore(v)
- case OpS390XFMOVSstoreidx:
- return rewriteValueS390X_OpS390XFMOVSstoreidx(v)
case OpS390XFNEG:
return rewriteValueS390X_OpS390XFNEG(v)
case OpS390XFNEGS:
@@ -622,78 +615,52 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpS390XLoweredRound64F(v)
case OpS390XMOVBZload:
return rewriteValueS390X_OpS390XMOVBZload(v)
- case OpS390XMOVBZloadidx:
- return rewriteValueS390X_OpS390XMOVBZloadidx(v)
case OpS390XMOVBZreg:
return rewriteValueS390X_OpS390XMOVBZreg(v)
case OpS390XMOVBload:
return rewriteValueS390X_OpS390XMOVBload(v)
- case OpS390XMOVBloadidx:
- return rewriteValueS390X_OpS390XMOVBloadidx(v)
case OpS390XMOVBreg:
return rewriteValueS390X_OpS390XMOVBreg(v)
case OpS390XMOVBstore:
return rewriteValueS390X_OpS390XMOVBstore(v)
case OpS390XMOVBstoreconst:
return rewriteValueS390X_OpS390XMOVBstoreconst(v)
- case OpS390XMOVBstoreidx:
- return rewriteValueS390X_OpS390XMOVBstoreidx(v)
case OpS390XMOVDaddridx:
return rewriteValueS390X_OpS390XMOVDaddridx(v)
case OpS390XMOVDload:
return rewriteValueS390X_OpS390XMOVDload(v)
- case OpS390XMOVDloadidx:
- return rewriteValueS390X_OpS390XMOVDloadidx(v)
case OpS390XMOVDstore:
return rewriteValueS390X_OpS390XMOVDstore(v)
case OpS390XMOVDstoreconst:
return rewriteValueS390X_OpS390XMOVDstoreconst(v)
- case OpS390XMOVDstoreidx:
- return rewriteValueS390X_OpS390XMOVDstoreidx(v)
case OpS390XMOVHBRstore:
return rewriteValueS390X_OpS390XMOVHBRstore(v)
- case OpS390XMOVHBRstoreidx:
- return rewriteValueS390X_OpS390XMOVHBRstoreidx(v)
case OpS390XMOVHZload:
return rewriteValueS390X_OpS390XMOVHZload(v)
- case OpS390XMOVHZloadidx:
- return rewriteValueS390X_OpS390XMOVHZloadidx(v)
case OpS390XMOVHZreg:
return rewriteValueS390X_OpS390XMOVHZreg(v)
case OpS390XMOVHload:
return rewriteValueS390X_OpS390XMOVHload(v)
- case OpS390XMOVHloadidx:
- return rewriteValueS390X_OpS390XMOVHloadidx(v)
case OpS390XMOVHreg:
return rewriteValueS390X_OpS390XMOVHreg(v)
case OpS390XMOVHstore:
return rewriteValueS390X_OpS390XMOVHstore(v)
case OpS390XMOVHstoreconst:
return rewriteValueS390X_OpS390XMOVHstoreconst(v)
- case OpS390XMOVHstoreidx:
- return rewriteValueS390X_OpS390XMOVHstoreidx(v)
case OpS390XMOVWBRstore:
return rewriteValueS390X_OpS390XMOVWBRstore(v)
- case OpS390XMOVWBRstoreidx:
- return rewriteValueS390X_OpS390XMOVWBRstoreidx(v)
case OpS390XMOVWZload:
return rewriteValueS390X_OpS390XMOVWZload(v)
- case OpS390XMOVWZloadidx:
- return rewriteValueS390X_OpS390XMOVWZloadidx(v)
case OpS390XMOVWZreg:
return rewriteValueS390X_OpS390XMOVWZreg(v)
case OpS390XMOVWload:
return rewriteValueS390X_OpS390XMOVWload(v)
- case OpS390XMOVWloadidx:
- return rewriteValueS390X_OpS390XMOVWloadidx(v)
case OpS390XMOVWreg:
return rewriteValueS390X_OpS390XMOVWreg(v)
case OpS390XMOVWstore:
return rewriteValueS390X_OpS390XMOVWstore(v)
case OpS390XMOVWstoreconst:
return rewriteValueS390X_OpS390XMOVWstoreconst(v)
- case OpS390XMOVWstoreidx:
- return rewriteValueS390X_OpS390XMOVWstoreidx(v)
case OpS390XMULLD:
return rewriteValueS390X_OpS390XMULLD(v)
case OpS390XMULLDconst:
@@ -5281,19 +5248,19 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
v_0 := v.Args[0]
// match: (ADD x (MOVDconst [c]))
// cond: is32Bit(c)
- // result: (ADDconst [c] x)
+ // result: (ADDconst [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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpS390XADDconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -5324,7 +5291,7 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
break
}
// match: (ADD idx (MOVDaddr [c] {s} ptr))
- // cond: ptr.Op != OpSB && idx.Op != OpSB
+ // cond: ptr.Op != OpSB
// result: (MOVDaddridx [c] {s} ptr idx)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -5335,7 +5302,7 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
c := auxIntToInt32(v_1.AuxInt)
s := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
- if !(ptr.Op != OpSB && idx.Op != OpSB) {
+ if !(ptr.Op != OpSB) {
continue
}
v.reset(OpS390XMOVDaddridx)
@@ -5362,7 +5329,7 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
break
}
// match: (ADD <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ADDload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -5372,17 +5339,17 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
if g.Op != OpS390XMOVDload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XADDload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -5395,19 +5362,19 @@ func rewriteValueS390X_OpS390XADDC(v *Value) bool {
v_0 := v.Args[0]
// match: (ADDC x (MOVDconst [c]))
// cond: is16Bit(c)
- // result: (ADDCconst x [c])
+ // result: (ADDCconst x [int16(c)])
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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is16Bit(c)) {
continue
}
v.reset(OpS390XADDCconst)
- v.AuxInt = c
+ v.AuxInt = int16ToAuxInt(int16(c))
v.AddArg(x)
return true
}
@@ -5482,16 +5449,16 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDW x (MOVDconst [c]))
- // result: (ADDWconst [int64(int32(c))] x)
+ // result: (ADDWconst [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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XADDWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -5537,7 +5504,7 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool {
break
}
// match: (ADDW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ADDWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -5547,24 +5514,24 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool {
if g.Op != OpS390XMOVWload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XADDWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
break
}
// match: (ADDW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ADDWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -5574,17 +5541,17 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XADDWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -5607,28 +5574,28 @@ func rewriteValueS390X_OpS390XADDWconst(v *Value) bool {
return true
}
// match: (ADDWconst [c] (MOVDconst [d]))
- // result: (MOVDconst [int64(int32(c+d))])
+ // result: (MOVDconst [int64(c)+d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(int32(c + d))
+ v.AuxInt = int64ToAuxInt(int64(c) + d)
return true
}
// match: (ADDWconst [c] (ADDWconst [d] x))
- // result: (ADDWconst [int64(int32(c+d))] x)
+ // result: (ADDWconst [int32(c+d)] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XADDWconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpS390XADDWconst)
- v.AuxInt = int64(int32(c + d))
+ v.AuxInt = int32ToAuxInt(int32(c + d))
v.AddArg(x)
return true
}
@@ -5639,47 +5606,47 @@ func rewriteValueS390X_OpS390XADDWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ADDWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XADDWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ADDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ADDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ADDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XADDWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -5688,63 +5655,63 @@ func rewriteValueS390X_OpS390XADDWload(v *Value) bool {
func rewriteValueS390X_OpS390XADDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ADDconst [c] (MOVDaddr [d] {s} x:(SB)))
- // cond: ((c+d)&1 == 0) && is32Bit(c+d)
+ // cond: ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d))
// result: (MOVDaddr [c+d] {s} x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDaddr {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
x := v_0.Args[0]
- if x.Op != OpSB || !(((c+d)&1 == 0) && is32Bit(c+d)) {
+ if x.Op != OpSB || !(((c+d)&1 == 0) && is32Bit(int64(c)+int64(d))) {
break
}
v.reset(OpS390XMOVDaddr)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
// match: (ADDconst [c] (MOVDaddr [d] {s} x))
- // cond: x.Op != OpSB && is20Bit(c+d)
+ // cond: x.Op != OpSB && is20Bit(int64(c)+int64(d))
// result: (MOVDaddr [c+d] {s} x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDaddr {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
x := v_0.Args[0]
- if !(x.Op != OpSB && is20Bit(c+d)) {
+ if !(x.Op != OpSB && is20Bit(int64(c)+int64(d))) {
break
}
v.reset(OpS390XMOVDaddr)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg(x)
return true
}
// match: (ADDconst [c] (MOVDaddridx [d] {s} x y))
- // cond: is20Bit(c+d)
+ // cond: is20Bit(int64(c)+int64(d))
// result: (MOVDaddridx [c+d] {s} x y)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDaddridx {
break
}
- d := v_0.AuxInt
- s := v_0.Aux
+ d := auxIntToInt32(v_0.AuxInt)
+ s := auxToSym(v_0.Aux)
y := v_0.Args[1]
x := v_0.Args[0]
- if !(is20Bit(c + d)) {
+ if !(is20Bit(int64(c) + int64(d))) {
break
}
v.reset(OpS390XMOVDaddridx)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
@@ -5759,32 +5726,32 @@ func rewriteValueS390X_OpS390XADDconst(v *Value) bool {
return true
}
// match: (ADDconst [c] (MOVDconst [d]))
- // result: (MOVDconst [c+d])
+ // result: (MOVDconst [int64(c)+d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c + d
+ v.AuxInt = int64ToAuxInt(int64(c) + d)
return true
}
// match: (ADDconst [c] (ADDconst [d] x))
- // cond: is32Bit(c+d)
+ // cond: is32Bit(int64(c)+int64(d))
// result: (ADDconst [c+d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XADDconst {
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(OpS390XADDconst)
- v.AuxInt = c + d
+ v.AuxInt = int32ToAuxInt(c + d)
v.AddArg(x)
return true
}
@@ -5819,47 +5786,47 @@ func rewriteValueS390X_OpS390XADDload(v *Value) bool {
return true
}
// match: (ADDload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ADDload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XADDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ADDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ADDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ADDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XADDload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -5892,20 +5859,20 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool {
}
// match: (AND x (MOVDconst [c]))
// cond: is32Bit(c) && c >= 0
- // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(int32(c))] x))
+ // 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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c) && c >= 0) {
continue
}
v.reset(OpS390XMOVWZreg)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = int64(int32(c))
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -6001,7 +5968,7 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool {
return true
}
// match: (AND <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ANDload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -6011,17 +5978,17 @@ func rewriteValueS390X_OpS390XAND(v *Value) bool {
if g.Op != OpS390XMOVDload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XANDload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -6033,16 +6000,16 @@ func rewriteValueS390X_OpS390XANDW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDW x (MOVDconst [c]))
- // result: (ANDWconst [int64(int32(c))] x)
+ // result: (ANDWconst [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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XANDWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -6059,7 +6026,7 @@ func rewriteValueS390X_OpS390XANDW(v *Value) bool {
return true
}
// match: (ANDW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ANDWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -6069,24 +6036,24 @@ func rewriteValueS390X_OpS390XANDW(v *Value) bool {
if g.Op != OpS390XMOVWload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XANDWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
break
}
// match: (ANDW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ANDWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -6096,17 +6063,17 @@ func rewriteValueS390X_OpS390XANDW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XANDWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -6117,7 +6084,7 @@ func rewriteValueS390X_OpS390XANDW(v *Value) bool {
func rewriteValueS390X_OpS390XANDWconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ANDWconst [c] (ANDWconst [d] x))
- // result: (ANDWconst [c & d] x)
+ // result: (ANDWconst [c&d] x)
for {
c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XANDWconst {
@@ -6177,15 +6144,15 @@ func rewriteValueS390X_OpS390XANDWconst(v *Value) bool {
return true
}
// match: (ANDWconst [c] (MOVDconst [d]))
- // result: (MOVDconst [c&d])
+ // result: (MOVDconst [int64(c)&d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c & d
+ v.AuxInt = int64ToAuxInt(int64(c) & d)
return true
}
return false
@@ -6195,47 +6162,47 @@ func rewriteValueS390X_OpS390XANDWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ANDWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ANDWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XANDWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ANDWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ANDWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ANDWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XANDWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -6244,7 +6211,7 @@ func rewriteValueS390X_OpS390XANDWload(v *Value) bool {
func rewriteValueS390X_OpS390XANDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ANDconst [c] (ANDconst [d] x))
- // result: (ANDconst [c & d] x)
+ // result: (ANDconst [c&d] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpS390XANDconst {
@@ -6320,47 +6287,47 @@ func rewriteValueS390X_OpS390XANDload(v *Value) bool {
return true
}
// match: (ANDload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ANDload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XANDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ANDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ANDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ANDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XANDload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -6372,36 +6339,36 @@ func rewriteValueS390X_OpS390XCMP(v *Value) bool {
b := v.Block
// match: (CMP x (MOVDconst [c]))
// cond: is32Bit(c)
- // result: (CMPconst x [c])
+ // result: (CMPconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
break
}
v.reset(OpS390XCMPconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMP (MOVDconst [c]) x)
// cond: is32Bit(c)
- // result: (InvertFlags (CMPconst x [c]))
+ // result: (InvertFlags (CMPconst x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
if !(is32Bit(c)) {
break
}
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XCMPconst, types.TypeFlags)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -6429,36 +6396,36 @@ func rewriteValueS390X_OpS390XCMPU(v *Value) bool {
b := v.Block
// match: (CMPU x (MOVDconst [c]))
// cond: isU32Bit(c)
- // result: (CMPUconst x [int64(int32(c))])
+ // result: (CMPUconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(isU32Bit(c)) {
break
}
v.reset(OpS390XCMPUconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMPU (MOVDconst [c]) x)
// cond: isU32Bit(c)
- // result: (InvertFlags (CMPUconst x [int64(int32(c))]))
+ // result: (InvertFlags (CMPUconst x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
if !(isU32Bit(c)) {
break
}
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
- v0.AuxInt = int64(int32(c))
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -6656,29 +6623,29 @@ func rewriteValueS390X_OpS390XCMPW(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (CMPW x (MOVDconst [c]))
- // result: (CMPWconst x [int64(int32(c))])
+ // result: (CMPWconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XCMPWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMPW (MOVDconst [c]) x)
- // result: (InvertFlags (CMPWconst x [int64(int32(c))]))
+ // result: (InvertFlags (CMPWconst x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XCMPWconst, types.TypeFlags)
- v0.AuxInt = int64(int32(c))
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -6753,29 +6720,29 @@ func rewriteValueS390X_OpS390XCMPWU(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (CMPWU x (MOVDconst [c]))
- // result: (CMPWUconst x [int64(int32(c))])
+ // result: (CMPWUconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XCMPWUconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMPWU (MOVDconst [c]) x)
- // result: (InvertFlags (CMPWUconst x [int64(int32(c))]))
+ // result: (InvertFlags (CMPWUconst x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
- v0.AuxInt = int64(int32(c))
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -7120,45 +7087,45 @@ func rewriteValueS390X_OpS390XCMPWconst(v *Value) bool {
func rewriteValueS390X_OpS390XCMPconst(v *Value) bool {
v_0 := v.Args[0]
// match: (CMPconst (MOVDconst [x]) [y])
- // cond: x==y
+ // cond: x==int64(y)
// result: (FlagEQ)
for {
- y := v.AuxInt
+ y := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- x := v_0.AuxInt
- if !(x == y) {
+ x := auxIntToInt64(v_0.AuxInt)
+ if !(x == int64(y)) {
break
}
v.reset(OpS390XFlagEQ)
return true
}
// match: (CMPconst (MOVDconst [x]) [y])
- // cond: x<y
+ // cond: x<int64(y)
// result: (FlagLT)
for {
- y := v.AuxInt
+ y := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- x := v_0.AuxInt
- if !(x < y) {
+ x := auxIntToInt64(v_0.AuxInt)
+ if !(x < int64(y)) {
break
}
v.reset(OpS390XFlagLT)
return true
}
// match: (CMPconst (MOVDconst [x]) [y])
- // cond: x>y
+ // cond: x>int64(y)
// result: (FlagGT)
for {
- y := v.AuxInt
+ y := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- x := v_0.AuxInt
- if !(x > y) {
+ x := auxIntToInt64(v_0.AuxInt)
+ if !(x > int64(y)) {
break
}
v.reset(OpS390XFlagGT)
@@ -7310,15 +7277,15 @@ func rewriteValueS390X_OpS390XCPSDR(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CPSDR y (FMOVDconst [c]))
- // cond: c & -1<<63 == 0
+ // cond: !math.Signbit(c)
// result: (LPDFR y)
for {
y := v_0
if v_1.Op != OpS390XFMOVDconst {
break
}
- c := v_1.AuxInt
- if !(c&-1<<63 == 0) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(!math.Signbit(c)) {
break
}
v.reset(OpS390XLPDFR)
@@ -7326,15 +7293,15 @@ func rewriteValueS390X_OpS390XCPSDR(v *Value) bool {
return true
}
// match: (CPSDR y (FMOVDconst [c]))
- // cond: c & -1<<63 != 0
+ // cond: math.Signbit(c)
// result: (LNDFR y)
for {
y := v_0
if v_1.Op != OpS390XFMOVDconst {
break
}
- c := v_1.AuxInt
- if !(c&-1<<63 != 0) {
+ c := auxIntToFloat64(v_1.AuxInt)
+ if !(math.Signbit(c)) {
break
}
v.reset(OpS390XLNDFR)
@@ -7347,34 +7314,24 @@ func rewriteValueS390X_OpS390XFCMP(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- // match: (FCMP x (FMOVDconst [c]))
- // cond: auxTo64F(c) == 0
+ // match: (FCMP x (FMOVDconst [0.0]))
// result: (LTDBR x)
for {
x := v_0
- if v_1.Op != OpS390XFMOVDconst {
- break
- }
- c := v_1.AuxInt
- if !(auxTo64F(c) == 0) {
+ if v_1.Op != OpS390XFMOVDconst || auxIntToFloat64(v_1.AuxInt) != 0.0 {
break
}
v.reset(OpS390XLTDBR)
v.AddArg(x)
return true
}
- // match: (FCMP (FMOVDconst [c]) x)
- // cond: auxTo64F(c) == 0
+ // match: (FCMP (FMOVDconst [0.0]) x)
// result: (InvertFlags (LTDBR <v.Type> x))
for {
- if v_0.Op != OpS390XFMOVDconst {
+ if v_0.Op != OpS390XFMOVDconst || auxIntToFloat64(v_0.AuxInt) != 0.0 {
break
}
- c := v_0.AuxInt
x := v_1
- if !(auxTo64F(c) == 0) {
- break
- }
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XLTDBR, v.Type)
v0.AddArg(x)
@@ -7387,34 +7344,24 @@ func rewriteValueS390X_OpS390XFCMPS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
- // match: (FCMPS x (FMOVSconst [c]))
- // cond: auxTo32F(c) == 0
+ // match: (FCMPS x (FMOVSconst [0.0]))
// result: (LTEBR x)
for {
x := v_0
- if v_1.Op != OpS390XFMOVSconst {
- break
- }
- c := v_1.AuxInt
- if !(auxTo32F(c) == 0) {
+ if v_1.Op != OpS390XFMOVSconst || auxIntToFloat32(v_1.AuxInt) != 0.0 {
break
}
v.reset(OpS390XLTEBR)
v.AddArg(x)
return true
}
- // match: (FCMPS (FMOVSconst [c]) x)
- // cond: auxTo32F(c) == 0
+ // match: (FCMPS (FMOVSconst [0.0]) x)
// result: (InvertFlags (LTEBR <v.Type> x))
for {
- if v_0.Op != OpS390XFMOVSconst {
+ if v_0.Op != OpS390XFMOVSconst || auxIntToFloat32(v_0.AuxInt) != 0.0 {
break
}
- c := v_0.AuxInt
x := v_1
- if !(auxTo32F(c) == 0) {
- break
- }
v.reset(OpS390XInvertFlags)
v0 := b.NewValue0(v.Pos, OpS390XLTEBR, v.Type)
v0.AddArg(x)
@@ -7464,148 +7411,48 @@ func rewriteValueS390X_OpS390XFMOVDload(v *Value) bool {
return true
}
// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (FMOVDload [off1+off2] {sym} ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XFMOVDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (FMOVDload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XFMOVDload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (FMOVDload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVDloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XFMOVDloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (FMOVDload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (FMOVDloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XFMOVDloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XFMOVDloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (FMOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (FMOVDloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- if v_0.Op != OpS390XADDconst {
- break
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVDloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (FMOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (FMOVDloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- break
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVDloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
return false
}
func rewriteValueS390X_OpS390XFMOVDstore(v *Value) bool {
@@ -7613,155 +7460,50 @@ func rewriteValueS390X_OpS390XFMOVDstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (FMOVDstore [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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XFMOVDstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (FMOVDstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XFMOVDstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (FMOVDstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVDstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XFMOVDstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (FMOVDstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (FMOVDstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XFMOVDstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XFMOVDstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (FMOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- if v_0.Op != OpS390XADDconst {
- break
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVDstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (FMOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (FMOVDstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- break
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVDstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
return false
}
func rewriteValueS390X_OpS390XFMOVSload(v *Value) bool {
@@ -7786,148 +7528,48 @@ func rewriteValueS390X_OpS390XFMOVSload(v *Value) bool {
return true
}
// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (FMOVSload [off1+off2] {sym} ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XFMOVSload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (FMOVSload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XFMOVSload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (FMOVSload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVSloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XFMOVSloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (FMOVSload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (FMOVSloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XFMOVSloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XFMOVSloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (FMOVSloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (FMOVSloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- if v_0.Op != OpS390XADDconst {
- break
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVSloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (FMOVSloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (FMOVSloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- break
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVSloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
return false
}
func rewriteValueS390X_OpS390XFMOVSstore(v *Value) bool {
@@ -7935,155 +7577,50 @@ func rewriteValueS390X_OpS390XFMOVSstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (FMOVSstore [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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XFMOVSstore)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (FMOVSstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XFMOVSstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (FMOVSstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (FMOVSstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XFMOVSstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (FMOVSstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (FMOVSstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XFMOVSstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XFMOVSstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (FMOVSstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- if v_0.Op != OpS390XADDconst {
- break
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVSstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (FMOVSstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (FMOVSstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- break
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- break
- }
- v.reset(OpS390XFMOVSstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
return false
}
func rewriteValueS390X_OpS390XFNEG(v *Value) bool {
@@ -8536,154 +8073,48 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value) bool {
return true
}
// match: (MOVBZload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (MOVBZload [off1+off2] {sym} ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVBZload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (MOVBZload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XMOVBZload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVBZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVBZloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVBZload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVBZloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVBZloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVBZloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVBZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVBZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVBZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVBZreg(v *Value) bool {
@@ -8797,17 +8228,6 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVBZreg x:(MOVBZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 1) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVBZreg <t> x:(MOVBload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVBZload <t> [o] {s} p mem)
@@ -8832,31 +8252,6 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVBZreg <t> x:(MOVBloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVBloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVBZreg x:(Arg <t>))
// cond: !t.IsSigned() && t.Size() == 1
// result: x
@@ -8909,16 +8304,16 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value) bool {
return true
}
// match: (MOVBZreg (ANDWconst [m] x))
- // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+ // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
for {
if v_0.Op != OpS390XANDWconst {
break
}
- m := v_0.AuxInt
+ m := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpS390XMOVWZreg)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = int64(uint8(m))
+ v0.AuxInt = int32ToAuxInt(int32(uint8(m)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -8948,154 +8343,48 @@ func rewriteValueS390X_OpS390XMOVBload(v *Value) bool {
return true
}
// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVBload)
- 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] {sym1} (MOVDaddr [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (MOVBload [off1+off2] {mergeSymTyped(sym1,sym2)} base mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XMOVBload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVBload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVBloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVBload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVBloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVBloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVBloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVBloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVBloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVBloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVBloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVBreg(v *Value) bool {
@@ -9209,17 +8498,6 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVBreg x:(MOVBloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVBreg <t> x:(MOVBZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVBload <t> [o] {s} p mem)
@@ -9244,31 +8522,6 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVBreg <t> x:(MOVBZloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVBZloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVBreg x:(Arg <t>))
// cond: t.IsSigned() && t.Size() == 1
// result: x
@@ -9297,19 +8550,19 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value) bool {
}
// match: (MOVBreg (ANDWconst [m] x))
// cond: int8(m) >= 0
- // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+ // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
for {
if v_0.Op != OpS390XANDWconst {
break
}
- m := v_0.AuxInt
+ m := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
if !(int8(m) >= 0) {
break
}
v.reset(OpS390XMOVWZreg)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = int64(uint8(m))
+ v0.AuxInt = int32ToAuxInt(int32(uint8(m)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -9355,133 +8608,81 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
return true
}
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVBstore)
- 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 [off] {sym} ptr (MOVDconst [c]) mem)
- // cond: is20Bit(off) && ptr.Op != OpSB
- // result: (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
+ // cond: is20Bit(int64(off)) && ptr.Op != OpSB
+ // result: (MOVBstoreconst [makeValAndOff32(int32(int8(c)),off)] {sym} ptr mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
mem := v_2
- if !(is20Bit(off) && ptr.Op != OpSB) {
+ if !(is20Bit(int64(off)) && ptr.Op != OpSB) {
break
}
v.reset(OpS390XMOVBstoreconst)
- 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
}
// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+ // result: (MOVBstore [off1+off2] {mergeSymTyped(sym1,sym2)} base val mem)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XMOVBstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVBstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVBstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVBstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (MOVBstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (MOVBstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVBstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
// match: (MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem))
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {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 != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9489,12 +8690,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -9502,17 +8703,17 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} p w0 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w0 := v_1
if w0.Op != OpS390XSRDconst {
break
}
- j := w0.AuxInt
+ j := auxIntToInt8(w0.AuxInt)
w := w0.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9520,12 +8721,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || x_1.AuxInt != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -9533,12 +8734,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {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 != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9546,12 +8747,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || x_1.AuxInt != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -9559,17 +8760,17 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} p w0 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w0 := v_1
if w0.Op != OpS390XSRWconst {
break
}
- j := w0.AuxInt
+ j := auxIntToInt8(w0.AuxInt)
w := w0.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9577,12 +8778,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || x_1.AuxInt != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -9590,15 +8791,15 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHBRstore [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 != OpS390XSRDconst || v_1.AuxInt != 8 {
+ if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 8 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9606,8 +8807,8 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
v.reset(OpS390XMOVHBRstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -9615,16 +8816,16 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHBRstore [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 != OpS390XSRDconst {
break
}
- j := v_1.AuxInt
+ j := auxIntToInt8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9632,12 +8833,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHBRstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -9645,15 +8846,15 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHBRstore [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 != OpS390XSRWconst || v_1.AuxInt != 8 {
+ if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 8 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9661,8 +8862,8 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
v.reset(OpS390XMOVHBRstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -9670,16 +8871,16 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVHBRstore [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 != OpS390XSRWconst {
break
}
- j := v_1.AuxInt
+ j := auxIntToInt8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVBstore || x.AuxInt != i-1 || x.Aux != s {
+ if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -9687,12 +8888,12 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRWconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHBRstore)
- v.AuxInt = i - 1
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 1)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -9702,508 +8903,161 @@ func rewriteValueS390X_OpS390XMOVBstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem)
- // cond: is20Bit(ValAndOff(sc).Off()+off)
- // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: is20Bit(sc.Off()+int64(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 != OpS390XADDconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(ValAndOff(sc).Off() + off)) {
+ if !(is20Bit(sc.Off() + int64(off))) {
break
}
v.reset(OpS390XMOVBstoreconst)
- 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
}
// match: (MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem)
- // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)
- // result: (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
+ // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)
+ // result: (MOVBstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem)
for {
- sc := v.AuxInt
- sym1 := v.Aux
+ sc := auxIntToValAndOff(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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 !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) {
+ if !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)) {
break
}
v.reset(OpS390XMOVBstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off))
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off() + 1 == ValAndOff(c).Off() && clobber(x)
- // result: (MOVHstoreconst [makeValAndOff(ValAndOff(c).Val()&0xff | ValAndOff(a).Val()<<8, ValAndOff(a).Off())] {s} p mem)
+ // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
+ // result: (MOVHstoreconst [makeValAndOff32(c.Val32()&0xff | a.Val32()<<8, a.Off32())] {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 != OpS390XMOVBstoreconst {
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] || !(p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off()+1 == ValAndOff(c).Off() && clobber(x)) {
+ if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
break
}
v.reset(OpS390XMOVHstoreconst)
- v.AuxInt = makeValAndOff(ValAndOff(c).Val()&0xff|ValAndOff(a).Val()<<8, ValAndOff(a).Off())
- v.Aux = s
+ v.AuxInt = valAndOffToAuxInt(makeValAndOff32(c.Val32()&0xff|a.Val32()<<8, a.Off32()))
+ v.Aux = symToAux(s)
v.AddArg2(p, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVBstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVBstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVBstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (MOVBstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVBstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx w x:(MOVBstoreidx [i-1] {s} p idx (SRDconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx [i-1] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != 8 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx (SRDconst [j+8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx [i-1] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w0 := v_2
- if w0.Op != OpS390XSRDconst {
- continue
- }
- j := w0.AuxInt
- w := w0.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != j+8 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx w x:(MOVBstoreidx [i-1] {s} p idx (SRWconst [8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx [i-1] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRWconst || x_2.AuxInt != 8 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx w0:(SRWconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx (SRWconst [j+8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHstoreidx [i-1] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w0 := v_2
- if w0.Op != OpS390XSRWconst {
- continue
- }
- j := w0.AuxInt
- w := w0.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRWconst || x_2.AuxInt != j+8 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx (SRDconst [8] w) x:(MOVBstoreidx [i-1] {s} p idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHBRstoreidx [i-1] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst || v_2.AuxInt != 8 {
- continue
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHBRstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx w0:(SRDconst [j-8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHBRstoreidx [i-1] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst {
- continue
- }
- j := v_2.AuxInt
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- w0 := x.Args[2]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHBRstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx (SRWconst [8] w) x:(MOVBstoreidx [i-1] {s} p idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHBRstoreidx [i-1] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRWconst || v_2.AuxInt != 8 {
- continue
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHBRstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVBstoreidx [i] {s} p idx (SRWconst [j] w) x:(MOVBstoreidx [i-1] {s} p idx w0:(SRWconst [j-8] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVHBRstoreidx [i-1] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRWconst {
- continue
- }
- j := v_2.AuxInt
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVBstoreidx || x.AuxInt != i-1 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- w0 := x.Args[2]
- if w0.Op != OpS390XSRWconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVHBRstoreidx)
- v.AuxInt = i - 1
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVDaddridx(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDaddridx [c] {s} (ADDconst [d] x) y)
- // cond: is20Bit(c+d) && x.Op != OpSB
+ // cond: is20Bit(int64(c)+int64(d))
// result: (MOVDaddridx [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
y := v_1
- if !(is20Bit(c+d) && x.Op != OpSB) {
+ if !(is20Bit(int64(c) + int64(d))) {
break
}
v.reset(OpS390XMOVDaddridx)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (MOVDaddridx [c] {s} x (ADDconst [d] y))
- // cond: is20Bit(c+d) && y.Op != OpSB
+ // cond: is20Bit(int64(c)+int64(d))
// result: (MOVDaddridx [c+d] {s} x y)
for {
- c := v.AuxInt
- s := v.Aux
+ c := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- d := v_1.AuxInt
+ d := auxIntToInt32(v_1.AuxInt)
y := v_1.Args[0]
- if !(is20Bit(c+d) && y.Op != OpSB) {
+ if !(is20Bit(int64(c) + int64(d))) {
break
}
v.reset(OpS390XMOVDaddridx)
- v.AuxInt = c + d
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(c + d)
+ v.Aux = symToAux(s)
v.AddArg2(x, y)
return true
}
// match: (MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && x.Op != OpSB
- // result: (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB
+ // result: (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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(OpS390XMOVDaddridx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(x, y)
return true
}
// match: (MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y))
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && y.Op != OpSB
- // result: (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
+ // cond: is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB
+ // result: (MOVDaddridx [off1+off2] {mergeSymTyped(sym1,sym2)} x y)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- off2 := v_1.AuxInt
- sym2 := v_1.Aux
+ off2 := auxIntToInt32(v_1.AuxInt)
+ sym2 := auxToSym(v_1.Aux)
y := v_1.Args[0]
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2) && y.Op != OpSB) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB) {
break
}
v.reset(OpS390XMOVDaddridx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(x, y)
return true
}
@@ -10250,155 +9104,49 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value) bool {
return true
}
// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// 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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVDload)
- 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] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))
- // result: (MOVDload [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))) {
break
}
v.reset(OpS390XMOVDload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVDload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVDloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVDloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVDload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVDloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVDloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVDloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVDloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVDloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVDloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVDloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVDloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVDloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
@@ -10406,134 +9154,82 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// 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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVDstore)
- 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 [off] {sym} ptr (MOVDconst [c]) mem)
- // cond: is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB
- // result: (MOVDstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+ // cond: is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB
+ // result: (MOVDstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
mem := v_2
- if !(is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB) {
+ if !(is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB) {
break
}
v.reset(OpS390XMOVDstoreconst)
- 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: (MOVDstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))
- // result: (MOVDstore [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0))) {
break
}
v.reset(OpS390XMOVDstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVDstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVDstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (MOVDstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (MOVDstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
// match: (MOVDstore [i] {s} p w1 x:(MOVDstore [i-8] {s} p w0 mem))
- // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(i-8) && clobber(x)
+ // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)
// result: (STMG2 [i-8] {s} p w0 w1 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w1 := v_1
x := v_2
- if x.Op != OpS390XMOVDstore || x.AuxInt != i-8 || x.Aux != s {
+ if x.Op != OpS390XMOVDstore || auxIntToInt32(x.AuxInt) != i-8 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -10541,25 +9237,25 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if !(p.Op != OpSB && x.Uses == 1 && is20Bit(i-8) && clobber(x)) {
+ if !(p.Op != OpSB && x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)) {
break
}
v.reset(OpS390XSTMG2)
- v.AuxInt = i - 8
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 8)
+ v.Aux = symToAux(s)
v.AddArg4(p, w0, w1, mem)
return true
}
// match: (MOVDstore [i] {s} p w2 x:(STMG2 [i-16] {s} p w0 w1 mem))
- // cond: x.Uses == 1 && is20Bit(i-16) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-16) && clobber(x)
// result: (STMG3 [i-16] {s} p w0 w1 w2 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w2 := v_1
x := v_2
- if x.Op != OpS390XSTMG2 || x.AuxInt != i-16 || x.Aux != s {
+ if x.Op != OpS390XSTMG2 || auxIntToInt32(x.AuxInt) != i-16 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[3]
@@ -10568,25 +9264,25 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
}
w0 := x.Args[1]
w1 := x.Args[2]
- if !(x.Uses == 1 && is20Bit(i-16) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-16) && clobber(x)) {
break
}
v.reset(OpS390XSTMG3)
- v.AuxInt = i - 16
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 16)
+ v.Aux = symToAux(s)
v.AddArg5(p, w0, w1, w2, mem)
return true
}
// match: (MOVDstore [i] {s} p w3 x:(STMG3 [i-24] {s} p w0 w1 w2 mem))
- // cond: x.Uses == 1 && is20Bit(i-24) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-24) && clobber(x)
// result: (STMG4 [i-24] {s} p w0 w1 w2 w3 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w3 := v_1
x := v_2
- if x.Op != OpS390XSTMG3 || x.AuxInt != i-24 || x.Aux != s {
+ if x.Op != OpS390XSTMG3 || auxIntToInt32(x.AuxInt) != i-24 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[4]
@@ -10596,12 +9292,12 @@ func rewriteValueS390X_OpS390XMOVDstore(v *Value) bool {
w0 := x.Args[1]
w1 := x.Args[2]
w2 := x.Args[3]
- if !(x.Uses == 1 && is20Bit(i-24) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-24) && clobber(x)) {
break
}
v.reset(OpS390XSTMG4)
- v.AuxInt = i - 24
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 24)
+ v.Aux = symToAux(s)
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
@@ -10611,109 +9307,50 @@ func rewriteValueS390X_OpS390XMOVDstoreconst(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem)
- // cond: isU12Bit(ValAndOff(sc).Off()+off)
- // result: (MOVDstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: isU12Bit(sc.Off()+int64(off))
+ // result: (MOVDstoreconst [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 != OpS390XADDconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(isU12Bit(ValAndOff(sc).Off() + off)) {
+ if !(isU12Bit(sc.Off() + int64(off))) {
break
}
v.reset(OpS390XMOVDstoreconst)
- 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
}
// match: (MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem)
- // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)
- // result: (MOVDstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
+ // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)
+ // result: (MOVDstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem)
for {
- sc := v.AuxInt
- sym1 := v.Aux
+ sc := auxIntToValAndOff(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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 !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) {
+ if !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)) {
break
}
v.reset(OpS390XMOVDstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off))
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVDstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVDstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVDstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (MOVDstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
@@ -10722,15 +9359,15 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWBRstore [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 != OpS390XSRDconst || v_1.AuxInt != 16 {
+ if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVHBRstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -10738,8 +9375,8 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
v.reset(OpS390XMOVWBRstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -10747,16 +9384,16 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWBRstore [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 != OpS390XSRDconst {
break
}
- j := v_1.AuxInt
+ j := auxIntToInt8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVHBRstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -10764,12 +9401,12 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWBRstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -10777,15 +9414,15 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWBRstore [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 != OpS390XSRWconst || v_1.AuxInt != 16 {
+ if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVHBRstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -10793,8 +9430,8 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
v.reset(OpS390XMOVWBRstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -10802,16 +9439,16 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWBRstore [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 != OpS390XSRWconst {
break
}
- j := v_1.AuxInt
+ j := auxIntToInt8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVHBRstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -10819,166 +9456,17 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRWconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWBRstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVHBRstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVHBRstoreidx [i] {s} p idx (SRDconst [16] w) x:(MOVHBRstoreidx [i-2] {s} p idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstoreidx [i-2] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst || v_2.AuxInt != 16 {
- continue
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHBRstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWBRstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHBRstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVHBRstoreidx [i-2] {s} p idx w0:(SRDconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstoreidx [i-2] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst {
- continue
- }
- j := v_2.AuxInt
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHBRstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- w0 := x.Args[2]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWBRstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHBRstoreidx [i] {s} p idx (SRWconst [16] w) x:(MOVHBRstoreidx [i-2] {s} p idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstoreidx [i-2] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRWconst || v_2.AuxInt != 16 {
- continue
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHBRstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWBRstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHBRstoreidx [i] {s} p idx (SRWconst [j] w) x:(MOVHBRstoreidx [i-2] {s} p idx w0:(SRWconst [j-16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWBRstoreidx [i-2] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRWconst {
- continue
- }
- j := v_2.AuxInt
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHBRstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- w0 := x.Args[2]
- if w0.Op != OpS390XSRWconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWBRstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVHZload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
@@ -11002,155 +9490,49 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value) bool {
return true
}
// match: (MOVHZload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (MOVHZload [off1+off2] {sym} ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVHZload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))
- // result: (MOVHZload [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
break
}
v.reset(OpS390XMOVHZload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVHZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVHZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVHZloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVHZload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVHZloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVHZloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVHZloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVHZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVHZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVHZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool {
@@ -11248,17 +9630,6 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVHZreg x:(MOVBZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 1) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVHZreg x:(MOVHZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
// result: x
@@ -11270,17 +9641,6 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVHZreg x:(MOVHZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVHZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 2) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVHZreg <t> x:(MOVHload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVHZload <t> [o] {s} p mem)
@@ -11305,31 +9665,6 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVHZreg <t> x:(MOVHloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVHloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVHZreg x:(Arg <t>))
// cond: !t.IsSigned() && t.Size() <= 2
// result: x
@@ -11357,16 +9692,16 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value) bool {
return true
}
// match: (MOVHZreg (ANDWconst [m] x))
- // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+ // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
for {
if v_0.Op != OpS390XANDWconst {
break
}
- m := v_0.AuxInt
+ m := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpS390XMOVWZreg)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = int64(uint16(m))
+ v0.AuxInt = int32ToAuxInt(int32(uint16(m)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -11396,155 +9731,49 @@ func rewriteValueS390X_OpS390XMOVHload(v *Value) bool {
return true
}
// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// 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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVHload)
- 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] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))
- // result: (MOVHload [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
break
}
v.reset(OpS390XMOVHload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVHload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVHloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVHloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVHload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVHloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVHloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVHloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVHloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVHloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVHloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVHloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
@@ -11642,17 +9871,6 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVHreg x:(MOVBloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVHreg x:(MOVHload _ _))
// cond: (x.Type.IsSigned() || x.Type.Size() == 8)
// result: x
@@ -11664,17 +9882,6 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVHreg x:(MOVHloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVHloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVHreg x:(MOVBZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
// result: x
@@ -11686,17 +9893,6 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVHreg x:(MOVBZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 1) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVHreg <t> x:(MOVHZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVHload <t> [o] {s} p mem)
@@ -11721,31 +9917,6 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVHreg <t> x:(MOVHZloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVHZloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVHreg x:(Arg <t>))
// cond: t.IsSigned() && t.Size() <= 2
// result: x
@@ -11774,19 +9945,19 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value) bool {
}
// match: (MOVHreg (ANDWconst [m] x))
// cond: int16(m) >= 0
- // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+ // result: (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
for {
if v_0.Op != OpS390XANDWconst {
break
}
- m := v_0.AuxInt
+ m := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
if !(int16(m) >= 0) {
break
}
v.reset(OpS390XMOVWZreg)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = int64(uint16(m))
+ v0.AuxInt = int32ToAuxInt(int32(uint16(m)))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -11832,134 +10003,82 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
return true
}
// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// 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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVHstore)
- 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 [off] {sym} ptr (MOVDconst [c]) mem)
- // cond: isU12Bit(off) && ptr.Op != OpSB
- // result: (MOVHstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
+ // cond: isU12Bit(int64(off)) && ptr.Op != OpSB
+ // result: (MOVHstoreconst [makeValAndOff32(int32(int16(c)),off)] {sym} ptr mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
mem := v_2
- if !(isU12Bit(off) && ptr.Op != OpSB) {
+ if !(isU12Bit(int64(off)) && ptr.Op != OpSB) {
break
}
v.reset(OpS390XMOVHstoreconst)
- 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
}
// match: (MOVHstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))
- // result: (MOVHstore [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0))) {
break
}
v.reset(OpS390XMOVHstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVHstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVHstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (MOVHstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (MOVHstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
// match: (MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVWstore [i-2] {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 != OpS390XMOVHstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -11967,12 +10086,12 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || x_1.AuxInt != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -11980,17 +10099,17 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVWstore [i-2] {s} p w0 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w0 := v_1
if w0.Op != OpS390XSRDconst {
break
}
- j := w0.AuxInt
+ j := auxIntToInt8(w0.AuxInt)
w := w0.Args[0]
x := v_2
- if x.Op != OpS390XMOVHstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -11998,12 +10117,12 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || x_1.AuxInt != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -12011,12 +10130,12 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVWstore [i-2] {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 != OpS390XMOVHstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -12024,12 +10143,12 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || x_1.AuxInt != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -12037,17 +10156,17 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVWstore [i-2] {s} p w0 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w0 := v_1
if w0.Op != OpS390XSRWconst {
break
}
- j := w0.AuxInt
+ j := auxIntToInt8(w0.AuxInt)
w := w0.Args[0]
x := v_2
- if x.Op != OpS390XMOVHstore || x.AuxInt != i-2 || x.Aux != s {
+ if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -12055,12 +10174,12 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || x_1.AuxInt != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = i - 2
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 2)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
@@ -12072,282 +10191,77 @@ func rewriteValueS390X_OpS390XMOVHstoreconst(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem)
- // cond: isU12Bit(ValAndOff(sc).Off()+off)
- // result: (MOVHstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: isU12Bit(sc.Off()+int64(off))
+ // result: (MOVHstoreconst [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 != OpS390XADDconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(isU12Bit(ValAndOff(sc).Off() + off)) {
+ if !(isU12Bit(sc.Off() + int64(off))) {
break
}
v.reset(OpS390XMOVHstoreconst)
- 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
}
// match: (MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem)
- // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)
- // result: (MOVHstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
+ // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)
+ // result: (MOVHstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem)
for {
- sc := v.AuxInt
- sym1 := v.Aux
+ sc := auxIntToValAndOff(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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 !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) {
+ if !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)) {
break
}
v.reset(OpS390XMOVHstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off))
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off() + 2 == ValAndOff(c).Off() && clobber(x)
- // result: (MOVWstore [ValAndOff(a).Off()] {s} p (MOVDconst [int64(int32(ValAndOff(c).Val()&0xffff | ValAndOff(a).Val()<<16))]) mem)
+ // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
+ // result: (MOVWstore [a.Off32()] {s} p (MOVDconst [int64(c.Val32()&0xffff | a.Val32()<<16)]) 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 != OpS390XMOVHstoreconst {
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] || !(p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off()+2 == ValAndOff(c).Off() && clobber(x)) {
+ if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = ValAndOff(a).Off()
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(a.Off32())
+ v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
- v0.AuxInt = int64(int32(ValAndOff(c).Val()&0xffff | ValAndOff(a).Val()<<16))
+ v0.AuxInt = int64ToAuxInt(int64(c.Val32()&0xffff | a.Val32()<<16))
v.AddArg3(p, v0, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVHstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVHstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVHstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (MOVHstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVHstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVHstoreidx [i] {s} p idx w x:(MOVHstoreidx [i-2] {s} p idx (SRDconst [16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstoreidx [i-2] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpS390XMOVHstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != 16 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVHstoreidx [i-2] {s} p idx (SRDconst [j+16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstoreidx [i-2] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w0 := v_2
- if w0.Op != OpS390XSRDconst {
- continue
- }
- j := w0.AuxInt
- w := w0.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != j+16 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHstoreidx [i] {s} p idx w x:(MOVHstoreidx [i-2] {s} p idx (SRWconst [16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstoreidx [i-2] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpS390XMOVHstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRWconst || x_2.AuxInt != 16 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVHstoreidx [i] {s} p idx w0:(SRWconst [j] w) x:(MOVHstoreidx [i-2] {s} p idx (SRWconst [j+16] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVWstoreidx [i-2] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w0 := v_2
- if w0.Op != OpS390XSRWconst {
- continue
- }
- j := w0.AuxInt
- w := w0.Args[0]
- x := v_3
- if x.Op != OpS390XMOVHstoreidx || x.AuxInt != i-2 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRWconst || x_2.AuxInt != j+16 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = i - 2
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
@@ -12356,15 +10270,15 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVDBRstore [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 != OpS390XSRDconst || v_1.AuxInt != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVWBRstore || x.AuxInt != i-4 || x.Aux != s {
+ if x.Op != OpS390XMOVWBRstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -12372,8 +10286,8 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
break
}
v.reset(OpS390XMOVDBRstore)
- v.AuxInt = i - 4
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 4)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -12381,16 +10295,16 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
// cond: x.Uses == 1 && clobber(x)
// result: (MOVDBRstore [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 != OpS390XSRDconst {
break
}
- j := v_1.AuxInt
+ j := auxIntToInt8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVWBRstore || x.AuxInt != i-4 || x.Aux != s {
+ if x.Op != OpS390XMOVWBRstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -12398,95 +10312,17 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVDBRstore)
- v.AuxInt = i - 4
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 4)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVWBRstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVWBRstoreidx [i] {s} p idx (SRDconst [32] w) x:(MOVWBRstoreidx [i-4] {s} p idx w mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDBRstoreidx [i-4] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst || v_2.AuxInt != 32 {
- continue
- }
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVWBRstoreidx || x.AuxInt != i-4 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVDBRstoreidx)
- v.AuxInt = i - 4
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVWBRstoreidx [i] {s} p idx (SRDconst [j] w) x:(MOVWBRstoreidx [i-4] {s} p idx w0:(SRDconst [j-32] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDBRstoreidx [i-4] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- if v_2.Op != OpS390XSRDconst {
- continue
- }
- j := v_2.AuxInt
- w := v_2.Args[0]
- x := v_3
- if x.Op != OpS390XMOVWBRstoreidx || x.AuxInt != i-4 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- w0 := x.Args[2]
- if w0.Op != OpS390XSRDconst || w0.AuxInt != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVDBRstoreidx)
- v.AuxInt = i - 4
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVWZload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
@@ -12510,155 +10346,49 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value) bool {
return true
}
// match: (MOVWZload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(int64(off1)+int64(off2))
// result: (MOVWZload [off1+off2] {sym} ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
if v_0.Op != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVWZload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWZload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))
- // result: (MOVWZload [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
break
}
v.reset(OpS390XMOVWZload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVWZload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVWZloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVWZloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVWZload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVWZloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVWZloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVWZloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVWZloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVWZloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVWZloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWZloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool {
@@ -12739,17 +10469,6 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWZreg x:(MOVBZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 1) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWZreg x:(MOVHZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
// result: x
@@ -12761,17 +10480,6 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWZreg x:(MOVHZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVHZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 2) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWZreg x:(MOVWZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 4)
// result: x
@@ -12783,17 +10491,6 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWZreg x:(MOVWZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 4)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVWZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 4) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWZreg <t> x:(MOVWload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVWZload <t> [o] {s} p mem)
@@ -12818,31 +10515,6 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVWZreg <t> x:(MOVWloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVWloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVWZreg x:(Arg <t>))
// cond: !t.IsSigned() && t.Size() <= 4
// result: x
@@ -12894,155 +10566,49 @@ func rewriteValueS390X_OpS390XMOVWload(v *Value) bool {
return true
}
// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVWload)
- 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] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))
- // result: (MOVWload [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
break
}
v.reset(OpS390XMOVWload)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(base, mem)
return true
}
- // match: (MOVWload [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVWloadidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- mem := v_1
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVWloadidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- // match: (MOVWload [off] {sym} (ADD ptr idx) mem)
- // cond: ptr.Op != OpSB
- // result: (MOVWloadidx [off] {sym} ptr idx mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- mem := v_1
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVWloadidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVWloadidx(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVWloadidx [c] {sym} (ADDconst [d] ptr) idx mem)
- // cond: is20Bit(c+d)
- // result: (MOVWloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
- // match: (MOVWloadidx [c] {sym} ptr (ADDconst [d] idx) mem)
- // cond: is20Bit(c+d)
- // result: (MOVWloadidx [c+d] {sym} ptr idx mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- mem := v_2
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWloadidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg3(ptr, idx, mem)
- return true
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
@@ -13123,17 +10689,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWreg x:(MOVBloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWreg x:(MOVHload _ _))
// cond: (x.Type.IsSigned() || x.Type.Size() == 8)
// result: x
@@ -13145,17 +10700,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWreg x:(MOVHloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVHloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWreg x:(MOVWload _ _))
// cond: (x.Type.IsSigned() || x.Type.Size() == 8)
// result: x
@@ -13167,17 +10711,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWreg x:(MOVWloadidx _ _ _))
- // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVWloadidx || !(x.Type.IsSigned() || x.Type.Size() == 8) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWreg x:(MOVBZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
// result: x
@@ -13189,17 +10722,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWreg x:(MOVBZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVBZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 1) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWreg x:(MOVHZload _ _))
// cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
// result: x
@@ -13211,17 +10733,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v.copyOf(x)
return true
}
- // match: (MOVWreg x:(MOVHZloadidx _ _ _))
- // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
- // result: x
- for {
- x := v_0
- if x.Op != OpS390XMOVHZloadidx || !(!x.Type.IsSigned() || x.Type.Size() > 2) {
- break
- }
- v.copyOf(x)
- return true
- }
// match: (MOVWreg <t> x:(MOVWZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
// result: @x.Block (MOVWload <t> [o] {s} p mem)
@@ -13246,31 +10757,6 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value) bool {
v0.AddArg2(p, mem)
return true
}
- // match: (MOVWreg <t> x:(MOVWZloadidx [o] {s} p i mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWloadidx <t> [o] {s} p i mem)
- for {
- t := v.Type
- x := v_0
- if x.Op != OpS390XMOVWZloadidx {
- break
- }
- o := auxIntToInt32(x.AuxInt)
- s := auxToSym(x.Aux)
- mem := x.Args[2]
- p := x.Args[0]
- i := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
- v.copyOf(v0)
- v0.AuxInt = int32ToAuxInt(o)
- v0.Aux = symToAux(s)
- v0.AddArg3(p, i, mem)
- return true
- }
// match: (MOVWreg x:(Arg <t>))
// cond: t.IsSigned() && t.Size() <= 4
// result: x
@@ -13338,137 +10824,85 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
return true
}
// match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: is20Bit(off1+off2)
+ // cond: is20Bit(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 != OpS390XADDconst {
break
}
- off2 := v_0.AuxInt
+ off2 := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
- if !(is20Bit(off1 + off2)) {
+ if !(is20Bit(int64(off1) + int64(off2))) {
break
}
v.reset(OpS390XMOVWstore)
- 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 [off] {sym} ptr (MOVDconst [c]) mem)
- // cond: is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB
- // result: (MOVWstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
+ // cond: is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB
+ // result: (MOVWstoreconst [makeValAndOff32(int32(c),off)] {sym} ptr mem)
for {
- off := v.AuxInt
- sym := v.Aux
+ off := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
mem := v_2
- if !(is16Bit(c) && isU12Bit(off) && ptr.Op != OpSB) {
+ if !(is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB) {
break
}
v.reset(OpS390XMOVWstoreconst)
- v.AuxInt = makeValAndOff(int64(int32(c)), off)
- v.Aux = sym
+ v.AuxInt = valAndOffToAuxInt(makeValAndOff32(int32(c), off))
+ v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstore [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))
- // result: (MOVWstore [off1+off2] {mergeSym(sym1,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)
for {
- off1 := v.AuxInt
- sym1 := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
break
}
t := v_0.Type
- 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) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
+ if !(is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0))) {
break
}
v.reset(OpS390XMOVWstore)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg3(base, val, mem)
return true
}
- // match: (MOVWstore [off1] {sym1} (MOVDaddridx [off2] {sym2} ptr idx) val mem)
- // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2)
- // result: (MOVWstoreidx [off1+off2] {mergeSym(sym1,sym2)} ptr idx val mem)
- for {
- off1 := v.AuxInt
- sym1 := v.Aux
- if v_0.Op != OpS390XMOVDaddridx {
- break
- }
- off2 := v_0.AuxInt
- sym2 := v_0.Aux
- idx := v_0.Args[1]
- ptr := v_0.Args[0]
- val := v_1
- mem := v_2
- if !(is32Bit(off1+off2) && canMergeSym(sym1, sym2)) {
- break
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = off1 + off2
- v.Aux = mergeSym(sym1, sym2)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- // match: (MOVWstore [off] {sym} (ADD ptr idx) val mem)
- // cond: ptr.Op != OpSB
- // result: (MOVWstoreidx [off] {sym} ptr idx val mem)
- for {
- off := auxIntToInt32(v.AuxInt)
- sym := auxToSym(v.Aux)
- if v_0.Op != OpS390XADD {
- 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 {
- ptr := v_0_0
- idx := v_0_1
- val := v_1
- mem := v_2
- if !(ptr.Op != OpSB) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = int32ToAuxInt(off)
- v.Aux = symToAux(sym)
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
// match: (MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVDstore [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 != OpS390XSRDconst || v_1.AuxInt != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
x := v_2
- if x.Op != OpS390XMOVWstore || x.AuxInt != i-4 || x.Aux != s {
+ if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -13476,8 +10910,8 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
break
}
v.reset(OpS390XMOVDstore)
- v.AuxInt = i - 4
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 4)
+ v.Aux = symToAux(s)
v.AddArg3(p, w, mem)
return true
}
@@ -13485,17 +10919,17 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
// cond: p.Op != OpSB && x.Uses == 1 && clobber(x)
// result: (MOVDstore [i-4] {s} p w0 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w0 := v_1
if w0.Op != OpS390XSRDconst {
break
}
- j := w0.AuxInt
+ j := auxIntToInt8(w0.AuxInt)
w := w0.Args[0]
x := v_2
- if x.Op != OpS390XMOVWstore || x.AuxInt != i-4 || x.Aux != s {
+ if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -13503,25 +10937,25 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || x_1.AuxInt != j+32 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+32 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVDstore)
- v.AuxInt = i - 4
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 4)
+ v.Aux = symToAux(s)
v.AddArg3(p, w0, mem)
return true
}
// match: (MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
- // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(i-4) && clobber(x)
+ // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(int64(i)-4) && clobber(x)
// result: (STM2 [i-4] {s} p w0 w1 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w1 := v_1
x := v_2
- if x.Op != OpS390XMOVWstore || x.AuxInt != i-4 || x.Aux != s {
+ if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
@@ -13529,25 +10963,25 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if !(p.Op != OpSB && x.Uses == 1 && is20Bit(i-4) && clobber(x)) {
+ if !(p.Op != OpSB && x.Uses == 1 && is20Bit(int64(i)-4) && clobber(x)) {
break
}
v.reset(OpS390XSTM2)
- v.AuxInt = i - 4
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 4)
+ v.Aux = symToAux(s)
v.AddArg4(p, w0, w1, mem)
return true
}
// match: (MOVWstore [i] {s} p w2 x:(STM2 [i-8] {s} p w0 w1 mem))
- // cond: x.Uses == 1 && is20Bit(i-8) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)
// result: (STM3 [i-8] {s} p w0 w1 w2 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w2 := v_1
x := v_2
- if x.Op != OpS390XSTM2 || x.AuxInt != i-8 || x.Aux != s {
+ if x.Op != OpS390XSTM2 || auxIntToInt32(x.AuxInt) != i-8 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[3]
@@ -13556,25 +10990,25 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
}
w0 := x.Args[1]
w1 := x.Args[2]
- if !(x.Uses == 1 && is20Bit(i-8) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)) {
break
}
v.reset(OpS390XSTM3)
- v.AuxInt = i - 8
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 8)
+ v.Aux = symToAux(s)
v.AddArg5(p, w0, w1, w2, mem)
return true
}
// match: (MOVWstore [i] {s} p w3 x:(STM3 [i-12] {s} p w0 w1 w2 mem))
- // cond: x.Uses == 1 && is20Bit(i-12) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-12) && clobber(x)
// result: (STM4 [i-12] {s} p w0 w1 w2 w3 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w3 := v_1
x := v_2
- if x.Op != OpS390XSTM3 || x.AuxInt != i-12 || x.Aux != s {
+ if x.Op != OpS390XSTM3 || auxIntToInt32(x.AuxInt) != i-12 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[4]
@@ -13584,12 +11018,12 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
w0 := x.Args[1]
w1 := x.Args[2]
w2 := x.Args[3]
- if !(x.Uses == 1 && is20Bit(i-12) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-12) && clobber(x)) {
break
}
v.reset(OpS390XSTM4)
- v.AuxInt = i - 12
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 12)
+ v.Aux = symToAux(s)
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
@@ -13601,234 +11035,102 @@ func rewriteValueS390X_OpS390XMOVWstoreconst(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem)
- // cond: isU12Bit(ValAndOff(sc).Off()+off)
- // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem)
+ // cond: isU12Bit(sc.Off()+int64(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 != OpS390XADDconst {
break
}
- off := v_0.AuxInt
+ off := auxIntToInt32(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
- if !(isU12Bit(ValAndOff(sc).Off() + off)) {
+ if !(isU12Bit(sc.Off() + int64(off))) {
break
}
v.reset(OpS390XMOVWstoreconst)
- 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
}
// match: (MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem)
- // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)
- // result: (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem)
+ // cond: ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)
+ // result: (MOVWstoreconst [sc.addOffset32(off)] {mergeSymTyped(sym1, sym2)} ptr mem)
for {
- sc := v.AuxInt
- sym1 := v.Aux
+ sc := auxIntToValAndOff(v.AuxInt)
+ sym1 := auxToSym(v.Aux)
if v_0.Op != OpS390XMOVDaddr {
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 !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off)) {
+ if !(ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off)) {
break
}
v.reset(OpS390XMOVWstoreconst)
- v.AuxInt = ValAndOff(sc).add(off)
- v.Aux = mergeSym(sym1, sym2)
+ v.AuxInt = valAndOffToAuxInt(sc.addOffset32(off))
+ v.Aux = symToAux(mergeSymTyped(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
- // cond: p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off() + 4 == ValAndOff(c).Off() && clobber(x)
- // result: (MOVDstore [ValAndOff(a).Off()] {s} p (MOVDconst [ValAndOff(c).Val()&0xffffffff | ValAndOff(a).Val()<<32]) mem)
+ // cond: p.Op != OpSB && x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
+ // result: (MOVDstore [a.Off32()] {s} p (MOVDconst [c.Val()&0xffffffff | a.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 != OpS390XMOVWstoreconst {
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] || !(p.Op != OpSB && x.Uses == 1 && ValAndOff(a).Off()+4 == ValAndOff(c).Off() && clobber(x)) {
+ if p != x.Args[0] || !(p.Op != OpSB && x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) {
break
}
v.reset(OpS390XMOVDstore)
- v.AuxInt = ValAndOff(a).Off()
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(a.Off32())
+ v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpS390XMOVDconst, typ.UInt64)
- v0.AuxInt = ValAndOff(c).Val()&0xffffffff | ValAndOff(a).Val()<<32
+ v0.AuxInt = int64ToAuxInt(c.Val()&0xffffffff | a.Val()<<32)
v.AddArg3(p, v0, mem)
return true
}
return false
}
-func rewriteValueS390X_OpS390XMOVWstoreidx(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (MOVWstoreidx [c] {sym} (ADDconst [d] ptr) idx val mem)
- // cond: is20Bit(c+d)
- // result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- if v_0.Op != OpS390XADDconst {
- continue
- }
- d := v_0.AuxInt
- ptr := v_0.Args[0]
- idx := v_1
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVWstoreidx [c] {sym} ptr (ADDconst [d] idx) val mem)
- // cond: is20Bit(c+d)
- // result: (MOVWstoreidx [c+d] {sym} ptr idx val mem)
- for {
- c := v.AuxInt
- sym := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- ptr := v_0
- if v_1.Op != OpS390XADDconst {
- continue
- }
- d := v_1.AuxInt
- idx := v_1.Args[0]
- val := v_2
- mem := v_3
- if !(is20Bit(c + d)) {
- continue
- }
- v.reset(OpS390XMOVWstoreidx)
- v.AuxInt = c + d
- v.Aux = sym
- v.AddArg4(ptr, idx, val, mem)
- return true
- }
- break
- }
- // match: (MOVWstoreidx [i] {s} p idx w x:(MOVWstoreidx [i-4] {s} p idx (SRDconst [32] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDstoreidx [i-4] {s} p idx w mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w := v_2
- x := v_3
- if x.Op != OpS390XMOVWstoreidx || x.AuxInt != i-4 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != 32 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = i - 4
- v.Aux = s
- v.AddArg4(p, idx, w, mem)
- return true
- }
- }
- break
- }
- // match: (MOVWstoreidx [i] {s} p idx w0:(SRDconst [j] w) x:(MOVWstoreidx [i-4] {s} p idx (SRDconst [j+32] w) mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: (MOVDstoreidx [i-4] {s} p idx w0 mem)
- for {
- i := v.AuxInt
- s := v.Aux
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- p := v_0
- idx := v_1
- w0 := v_2
- if w0.Op != OpS390XSRDconst {
- continue
- }
- j := w0.AuxInt
- w := w0.Args[0]
- x := v_3
- if x.Op != OpS390XMOVWstoreidx || x.AuxInt != i-4 || x.Aux != s {
- continue
- }
- mem := x.Args[3]
- x_0 := x.Args[0]
- x_1 := x.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x_0, x_1 = _i1+1, x_1, x_0 {
- if p != x_0 || idx != x_1 {
- continue
- }
- x_2 := x.Args[2]
- if x_2.Op != OpS390XSRDconst || x_2.AuxInt != j+32 || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
- continue
- }
- v.reset(OpS390XMOVDstoreidx)
- v.AuxInt = i - 4
- v.Aux = s
- v.AddArg4(p, idx, w0, mem)
- return true
- }
- }
- break
- }
- return false
-}
func rewriteValueS390X_OpS390XMULLD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MULLD x (MOVDconst [c]))
// cond: is32Bit(c)
- // result: (MULLDconst [c] x)
+ // 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 != OpS390XMOVDconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
continue
}
v.reset(OpS390XMULLDconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
break
}
// match: (MULLD <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (MULLDload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -13838,17 +11140,17 @@ func rewriteValueS390X_OpS390XMULLD(v *Value) bool {
if g.Op != OpS390XMOVDload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XMULLDload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -13920,15 +11222,15 @@ func rewriteValueS390X_OpS390XMULLDconst(v *Value) bool {
return true
}
// match: (MULLDconst [c] (MOVDconst [d]))
- // result: (MOVDconst [c*d])
+ // result: (MOVDconst [int64(c)*d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c * d
+ v.AuxInt = int64ToAuxInt(int64(c) * d)
return true
}
return false
@@ -13962,47 +11264,47 @@ func rewriteValueS390X_OpS390XMULLDload(v *Value) bool {
return true
}
// match: (MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (MULLDload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XMULLDload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (MULLDload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XMULLDload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -14012,23 +11314,23 @@ func rewriteValueS390X_OpS390XMULLW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MULLW x (MOVDconst [c]))
- // result: (MULLWconst [int64(int32(c))] x)
+ // 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 != OpS390XMOVDconst {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XMULLWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
break
}
// match: (MULLW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (MULLWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -14038,24 +11340,24 @@ func rewriteValueS390X_OpS390XMULLW(v *Value) bool {
if g.Op != OpS390XMOVWload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XMULLWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
break
}
// match: (MULLW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (MULLWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -14065,17 +11367,17 @@ func rewriteValueS390X_OpS390XMULLW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XMULLWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -14147,15 +11449,15 @@ func rewriteValueS390X_OpS390XMULLWconst(v *Value) bool {
return true
}
// match: (MULLWconst [c] (MOVDconst [d]))
- // result: (MOVDconst [int64(int32(c*d))])
+ // result: (MOVDconst [int64(c*int32(d))])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(int32(c * d))
+ v.AuxInt = int64ToAuxInt(int64(c * int32(d)))
return true
}
return false
@@ -14165,47 +11467,47 @@ func rewriteValueS390X_OpS390XMULLWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (MULLWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XMULLWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (MULLWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XMULLWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -14391,14 +11693,14 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
}
// match: (OR (SLDconst [63] (SRDconst [63] (LGDR x))) (MOVDconst [c]))
// cond: c & -1<<63 == 0
- // result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [c]) x))
+ // 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 || v_0.AuxInt != 63 {
+ if v_0.Op != OpS390XSLDconst || auxIntToInt8(v_0.AuxInt) != 63 {
continue
}
v_0_0 := v_0.Args[0]
- if v_0_0.Op != OpS390XSRDconst || v_0_0.AuxInt != 63 {
+ if v_0_0.Op != OpS390XSRDconst || auxIntToInt8(v_0_0.AuxInt) != 63 {
continue
}
v_0_0_0 := v_0_0.Args[0]
@@ -14409,14 +11711,14 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if v_1.Op != OpS390XMOVDconst {
continue
}
- c := v_1.AuxInt
+ 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 = c
+ v1.AuxInt = float64ToAuxInt(math.Float64frombits(uint64(c)))
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
@@ -14458,7 +11760,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
}
// match: (OR (AND (MOVDconst [-1<<63]) (LGDR x)) (MOVDconst [c]))
// cond: c & -1<<63 == 0
- // result: (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [c]) x))
+ // 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 {
@@ -14468,21 +11770,21 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
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 || v_0_0.AuxInt != -1<<63 || v_0_1.Op != OpS390XLGDR {
+ 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 := v_1.AuxInt
+ 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 = c
+ v1.AuxInt = float64ToAuxInt(math.Float64frombits(uint64(c)))
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
@@ -14519,7 +11821,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
return true
}
// match: (OR <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ORload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -14529,17 +11831,17 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if g.Op != OpS390XMOVDload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XORload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -14554,20 +11856,20 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVBZload {
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 != OpS390XSLDconst || sh.AuxInt != 8 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 8 {
continue
}
x0 := sh.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -14577,8 +11879,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpS390XMOVHZload, 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
}
@@ -14593,20 +11895,20 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVHZload {
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 != OpS390XSLDconst || sh.AuxInt != 16 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 16 {
continue
}
x0 := sh.Args[0]
if x0.Op != OpS390XMOVHZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -14616,8 +11918,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpS390XMOVWZload, 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
}
@@ -14632,20 +11934,20 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVWZload {
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 != OpS390XSLDconst || sh.AuxInt != 32 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 32 {
continue
}
x0 := sh.Args[0]
if x0.Op != OpS390XMOVWZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -14655,8 +11957,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpS390XMOVDload, 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
}
@@ -14671,13 +11973,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
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
@@ -14692,13 +11994,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -14713,10 +12015,10 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j1
+ v1.AuxInt = int8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, 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)
@@ -14734,13 +12036,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVHZload {
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
@@ -14755,13 +12057,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVHZload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -14776,10 +12078,10 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j1
+ v1.AuxInt = int8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVWZload, 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)
@@ -14788,294 +12090,6 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
}
break
}
- // match: (OR x1:(MOVBZloadidx [i1] {s} p idx mem) sh:(SLDconst [8] x0:(MOVBZloadidx [i0] {s} p idx mem)))
- // cond: i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x0_0, x0_1 = _i2+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] || !(i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (OR x1:(MOVHZloadidx [i1] {s} p idx mem) sh:(SLDconst [16] x0:(MOVHZloadidx [i0] {s} p idx mem)))
- // cond: i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVHZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 16 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVHZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x0_0, x0_1 = _i2+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] || !(i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (OR x1:(MOVWZloadidx [i1] {s} p idx mem) sh:(SLDconst [32] x0:(MOVWZloadidx [i0] {s} p idx mem)))
- // cond: i1 == i0+4 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVDloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVWZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 32 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVWZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x0_0, x0_1 = _i2+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] || !(i1 == i0+4 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVDloadidx, typ.UInt64)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (OR s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)) or:(OR s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := s0.AuxInt
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := s1.AuxInt
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x1_0, x1_1 = _i3+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j1
- v2 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, typ.UInt16)
- v2.AuxInt = i0
- v2.Aux = s
- v2.AddArg3(p, idx, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
- // match: (OR s0:(SLDconst [j0] x0:(MOVHZloadidx [i0] {s} p idx mem)) or:(OR s1:(SLDconst [j1] x1:(MOVHZloadidx [i1] {s} p idx mem)) y))
- // cond: i1 == i0+2 && j1 == j0-16 && j1 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZloadidx [i0] {s} p idx mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := s0.AuxInt
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVHZloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := s1.AuxInt
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVHZloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x1_0, x1_1 = _i3+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0-16 && j1%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j1
- v2 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, typ.UInt32)
- v2.AuxInt = i0
- v2.Aux = s
- v2.AddArg3(p, idx, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
// match: (OR x0:(MOVBZload [i0] {s} p mem) sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
// cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
// result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
@@ -15085,20 +12099,20 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x0.Op != OpS390XMOVBZload {
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 != OpS390XSLDconst || sh.AuxInt != 8 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 8 {
continue
}
x1 := sh.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -15109,8 +12123,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XMOVHZreg, typ.UInt64)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XMOVHBRload, 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
@@ -15130,12 +12144,12 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x0.Op != OpS390XMOVHBRload {
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 != OpS390XSLDconst || sh.AuxInt != 16 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 16 {
continue
}
r1 := sh.Args[0]
@@ -15146,8 +12160,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVHBRload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -15158,8 +12172,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XMOVWZreg, typ.UInt64)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XMOVWBRload, 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
@@ -15179,12 +12193,12 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x0.Op != OpS390XMOVWBRload {
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 != OpS390XSLDconst || sh.AuxInt != 32 {
+ if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 32 {
continue
}
r1 := sh.Args[0]
@@ -15195,8 +12209,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVWBRload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -15206,8 +12220,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x1.Pos, OpS390XMOVDBRload, 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
}
@@ -15222,13 +12236,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
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
@@ -15243,13 +12257,13 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -15264,11 +12278,11 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j0
+ v1.AuxInt = int8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, 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)
@@ -15287,7 +12301,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
r1 := s1.Args[0]
if r1.Op != OpS390XMOVHZreg {
continue
@@ -15296,8 +12310,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x1.Op != OpS390XMOVHBRload {
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
@@ -15312,7 +12326,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
r0 := s0.Args[0]
if r0.Op != OpS390XMOVHZreg {
continue
@@ -15321,8 +12335,8 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if x0.Op != OpS390XMOVHBRload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -15337,11 +12351,11 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j0
+ v1.AuxInt = int8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVWZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVWBRload, 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)
@@ -15351,326 +12365,6 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
}
break
}
- // match: (OR x0:(MOVBZloadidx [i0] {s} p idx mem) sh:(SLDconst [8] x1:(MOVBZloadidx [i1] {s} p idx mem)))
- // cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x1_0, x1_1 = _i2+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] || !(p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XMOVHBRloadidx, typ.Int16)
- v1.AuxInt = i0
- v1.Aux = s
- v1.AddArg3(p, idx, mem)
- v0.AddArg(v1)
- return true
- }
- }
- }
- break
- }
- // match: (OR r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem)) sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 16 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x1_0, x1_1 = _i2+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XMOVWBRloadidx, typ.Int32)
- v1.AuxInt = i0
- v1.Aux = s
- v1.AddArg3(p, idx, mem)
- v0.AddArg(v1)
- return true
- }
- }
- }
- break
- }
- // match: (OR r0:(MOVWZreg x0:(MOVWBRloadidx [i0] {s} p idx mem)) sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRloadidx [i1] {s} p idx mem))))
- // cond: i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVDBRloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVWZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVWBRloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- sh := v_1
- if sh.Op != OpS390XSLDconst || sh.AuxInt != 32 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVWZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVWBRloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x1_0, x1_1 = _i2+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] || !(i1 == i0+4 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVDBRloadidx, typ.Int64)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (OR s1:(SLDconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)) or:(OR s0:(SLDconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)) y))
- // cond: p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := s1.AuxInt
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := s0.AuxInt
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x0_0, x0_1 = _i3+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] {
- continue
- }
- y := or_1
- if !(p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j0
- v2 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
- v3 := b.NewValue0(v.Pos, OpS390XMOVHBRloadidx, typ.Int16)
- v3.AuxInt = i0
- v3.Aux = s
- v3.AddArg3(p, idx, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
- // match: (OR s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))) or:(OR s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem))) y))
- // cond: i1 == i0+2 && j1 == j0+16 && j0 % 32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRloadidx [i0] {s} p idx mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLDconst {
- continue
- }
- j1 := s1.AuxInt
- r1 := s1.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- or := v_1
- if or.Op != OpS390XOR {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLDconst {
- continue
- }
- j0 := s0.AuxInt
- r0 := s0.Args[0]
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x0_0, x0_1 = _i3+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] {
- continue
- }
- y := or_1
- if !(i1 == i0+2 && j1 == j0+16 && j0%32 == 0 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, r0, r1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XOR, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = j0
- v2 := b.NewValue0(v.Pos, OpS390XMOVWZreg, typ.UInt64)
- v3 := b.NewValue0(v.Pos, OpS390XMOVWBRloadidx, typ.Int32)
- v3.AuxInt = i0
- v3.Aux = s
- v3.AddArg3(p, idx, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XORW(v *Value) bool {
@@ -15679,16 +12373,16 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (ORW x (MOVDconst [c]))
- // result: (ORWconst [int64(int32(c))] x)
+ // result: (ORWconst [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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XORWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -15729,7 +12423,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
return true
}
// match: (ORW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ORWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -15739,24 +12433,24 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if g.Op != OpS390XMOVWload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XORWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
break
}
// match: (ORW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (ORWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -15766,17 +12460,17 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XORWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -15791,20 +12485,20 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if x1.Op != OpS390XMOVBZload {
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 != OpS390XSLWconst || sh.AuxInt != 8 {
+ if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 8 {
continue
}
x0 := sh.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -15814,8 +12508,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpS390XMOVHZload, 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
}
@@ -15830,20 +12524,20 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if x1.Op != OpS390XMOVHZload {
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 != OpS390XSLWconst || sh.AuxInt != 16 {
+ if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 16 {
continue
}
x0 := sh.Args[0]
if x0.Op != OpS390XMOVHZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -15853,8 +12547,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpS390XMOVWZload, 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
}
@@ -15869,13 +12563,13 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s0.Op != OpS390XSLWconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
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
@@ -15890,13 +12584,13 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s1.Op != OpS390XSLWconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -15911,10 +12605,10 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XORW, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = j1
+ v1.AuxInt = int8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, 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)
@@ -15923,174 +12617,6 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
}
break
}
- // match: (ORW x1:(MOVBZloadidx [i1] {s} p idx mem) sh:(SLWconst [8] x0:(MOVBZloadidx [i0] {s} p idx mem)))
- // cond: i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- sh := v_1
- if sh.Op != OpS390XSLWconst || sh.AuxInt != 8 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x0_0, x0_1 = _i2+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] || !(i1 == i0+1 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, typ.UInt16)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (ORW x1:(MOVHZloadidx [i1] {s} p idx mem) sh:(SLWconst [16] x0:(MOVHZloadidx [i0] {s} p idx mem)))
- // cond: i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWZloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x1 := v_0
- if x1.Op != OpS390XMOVHZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- sh := v_1
- if sh.Op != OpS390XSLWconst || sh.AuxInt != 16 {
- continue
- }
- x0 := sh.Args[0]
- if x0.Op != OpS390XMOVHZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x0_0, x0_1 = _i2+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] || !(i1 == i0+2 && p.Op != OpSB && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, typ.UInt32)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (ORW s0:(SLWconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)) or:(ORW s1:(SLWconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)) y))
- // cond: i1 == i0+1 && j1 == j0-8 && j1 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZloadidx [i0] {s} p idx mem)) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s0 := v_0
- if s0.Op != OpS390XSLWconst {
- continue
- }
- j0 := s0.AuxInt
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- or := v_1
- if or.Op != OpS390XORW {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s1 := or_0
- if s1.Op != OpS390XSLWconst {
- continue
- }
- j1 := s1.AuxInt
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x1_0, x1_1 = _i3+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] {
- continue
- }
- y := or_1
- if !(i1 == i0+1 && j1 == j0-8 && j1%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XORW, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = j1
- v2 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, typ.UInt16)
- v2.AuxInt = i0
- v2.Aux = s
- v2.AddArg3(p, idx, mem)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
// match: (ORW x0:(MOVBZload [i0] {s} p mem) sh:(SLWconst [8] x1:(MOVBZload [i1] {s} p mem)))
// cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
// result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
@@ -16100,20 +12626,20 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if x0.Op != OpS390XMOVBZload {
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 != OpS390XSLWconst || sh.AuxInt != 8 {
+ if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 8 {
continue
}
x1 := sh.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -16124,8 +12650,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XMOVHZreg, typ.UInt64)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XMOVHBRload, 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
@@ -16145,12 +12671,12 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if x0.Op != OpS390XMOVHBRload {
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 != OpS390XSLWconst || sh.AuxInt != 16 {
+ if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 16 {
continue
}
r1 := sh.Args[0]
@@ -16161,8 +12687,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if x1.Op != OpS390XMOVHBRload {
continue
}
- i1 := x1.AuxInt
- if x1.Aux != s {
+ i1 := auxIntToInt32(x1.AuxInt)
+ if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
@@ -16172,8 +12698,8 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x1.Pos, OpS390XMOVWBRload, 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
}
@@ -16188,13 +12714,13 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s1.Op != OpS390XSLWconst {
continue
}
- j1 := s1.AuxInt
+ j1 := auxIntToInt8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
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
@@ -16209,13 +12735,13 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s0.Op != OpS390XSLWconst {
continue
}
- j0 := s0.AuxInt
+ j0 := auxIntToInt8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
}
- i0 := x0.AuxInt
- if x0.Aux != s {
+ i0 := auxIntToInt32(x0.AuxInt)
+ if auxToSym(x0.Aux) != s {
continue
}
_ = x0.Args[1]
@@ -16230,11 +12756,11 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XORW, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = j0
+ v1.AuxInt = int8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, 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)
@@ -16244,186 +12770,6 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
}
break
}
- // match: (ORW x0:(MOVBZloadidx [i0] {s} p idx mem) sh:(SLWconst [8] x1:(MOVBZloadidx [i1] {s} p idx mem)))
- // cond: p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, sh)
- // result: @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- x0 := v_0
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- sh := v_1
- if sh.Op != OpS390XSLWconst || sh.AuxInt != 8 {
- continue
- }
- x1 := sh.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x1_0, x1_1 = _i2+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] || !(p.Op != OpSB && i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XMOVHBRloadidx, typ.Int16)
- v1.AuxInt = i0
- v1.Aux = s
- v1.AddArg3(p, idx, mem)
- v0.AddArg(v1)
- return true
- }
- }
- }
- break
- }
- // match: (ORW r0:(MOVHZreg x0:(MOVHBRloadidx [i0] {s} p idx mem)) sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRloadidx [i1] {s} p idx mem))))
- // cond: i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, r0, r1, sh)
- // result: @mergePoint(b,x0,x1) (MOVWBRloadidx [i0] {s} p idx mem)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- r0 := v_0
- if r0.Op != OpS390XMOVHZreg {
- continue
- }
- x0 := r0.Args[0]
- if x0.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i0 := x0.AuxInt
- s := x0.Aux
- mem := x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x0_0, x0_1 = _i1+1, x0_1, x0_0 {
- p := x0_0
- idx := x0_1
- sh := v_1
- if sh.Op != OpS390XSLWconst || sh.AuxInt != 16 {
- continue
- }
- r1 := sh.Args[0]
- if r1.Op != OpS390XMOVHZreg {
- continue
- }
- x1 := r1.Args[0]
- if x1.Op != OpS390XMOVHBRloadidx {
- continue
- }
- i1 := x1.AuxInt
- if x1.Aux != s {
- continue
- }
- _ = x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, x1_0, x1_1 = _i2+1, x1_1, x1_0 {
- if p != x1_0 || idx != x1_1 || mem != x1.Args[2] || !(i1 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && r0.Uses == 1 && r1.Uses == 1 && sh.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, r0, r1, sh)) {
- continue
- }
- b = mergePoint(b, x0, x1)
- v0 := b.NewValue0(v.Pos, OpS390XMOVWBRloadidx, typ.Int32)
- v.copyOf(v0)
- v0.AuxInt = i0
- v0.Aux = s
- v0.AddArg3(p, idx, mem)
- return true
- }
- }
- }
- break
- }
- // match: (ORW s1:(SLWconst [j1] x1:(MOVBZloadidx [i1] {s} p idx mem)) or:(ORW s0:(SLWconst [j0] x0:(MOVBZloadidx [i0] {s} p idx mem)) y))
- // cond: p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0 % 16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b,x0,x1,y) != nil && clobber(x0, x1, s0, s1, or)
- // result: @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRloadidx [i0] {s} p idx mem))) y)
- for {
- for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
- s1 := v_0
- if s1.Op != OpS390XSLWconst {
- continue
- }
- j1 := s1.AuxInt
- x1 := s1.Args[0]
- if x1.Op != OpS390XMOVBZloadidx {
- continue
- }
- i1 := x1.AuxInt
- s := x1.Aux
- mem := x1.Args[2]
- x1_0 := x1.Args[0]
- x1_1 := x1.Args[1]
- for _i1 := 0; _i1 <= 1; _i1, x1_0, x1_1 = _i1+1, x1_1, x1_0 {
- p := x1_0
- idx := x1_1
- or := v_1
- if or.Op != OpS390XORW {
- continue
- }
- _ = or.Args[1]
- or_0 := or.Args[0]
- or_1 := or.Args[1]
- for _i2 := 0; _i2 <= 1; _i2, or_0, or_1 = _i2+1, or_1, or_0 {
- s0 := or_0
- if s0.Op != OpS390XSLWconst {
- continue
- }
- j0 := s0.AuxInt
- x0 := s0.Args[0]
- if x0.Op != OpS390XMOVBZloadidx {
- continue
- }
- i0 := x0.AuxInt
- if x0.Aux != s {
- continue
- }
- _ = x0.Args[2]
- x0_0 := x0.Args[0]
- x0_1 := x0.Args[1]
- for _i3 := 0; _i3 <= 1; _i3, x0_0, x0_1 = _i3+1, x0_1, x0_0 {
- if p != x0_0 || idx != x0_1 || mem != x0.Args[2] {
- continue
- }
- y := or_1
- if !(p.Op != OpSB && i1 == i0+1 && j1 == j0+8 && j0%16 == 0 && x0.Uses == 1 && x1.Uses == 1 && s0.Uses == 1 && s1.Uses == 1 && or.Uses == 1 && mergePoint(b, x0, x1, y) != nil && clobber(x0, x1, s0, s1, or)) {
- continue
- }
- b = mergePoint(b, x0, x1, y)
- v0 := b.NewValue0(v.Pos, OpS390XORW, v.Type)
- v.copyOf(v0)
- v1 := b.NewValue0(v.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = j0
- v2 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
- v3 := b.NewValue0(v.Pos, OpS390XMOVHBRloadidx, typ.Int16)
- v3.AuxInt = i0
- v3.Aux = s
- v3.AddArg3(p, idx, mem)
- v2.AddArg(v3)
- v1.AddArg(v2)
- v0.AddArg2(v1, y)
- return true
- }
- }
- }
- }
- break
- }
return false
}
func rewriteValueS390X_OpS390XORWconst(v *Value) bool {
@@ -16453,15 +12799,15 @@ func rewriteValueS390X_OpS390XORWconst(v *Value) bool {
return true
}
// match: (ORWconst [c] (MOVDconst [d]))
- // result: (MOVDconst [c|d])
+ // result: (MOVDconst [int64(c)|d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c | d
+ v.AuxInt = int64ToAuxInt(int64(c) | d)
return true
}
return false
@@ -16471,47 +12817,47 @@ func rewriteValueS390X_OpS390XORWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ORWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XORWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XORWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -16582,47 +12928,47 @@ func rewriteValueS390X_OpS390XORload(v *Value) bool {
return true
}
// match: (ORload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (ORload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XORload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (ORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (ORload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (ORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XORload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -16632,15 +12978,15 @@ func rewriteValueS390X_OpS390XRLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (RLL x (MOVDconst [c]))
- // result: (RLLconst x [c&31])
+ // result: (RLLconst x [int8(c&31)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XRLLconst)
- v.AuxInt = c & 31
+ v.AuxInt = int8ToAuxInt(int8(c & 31))
v.AddArg(x)
return true
}
@@ -16650,15 +12996,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 [c&63])
+ // result: (RLLGconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XRLLGconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
@@ -16670,20 +13016,20 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SLD x (MOVDconst [c]))
- // result: (SLDconst x [c&63])
+ // result: (SLDconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSLDconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SLD x (AND (MOVDconst [c]) y))
- // result: (SLD x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SLD x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -16696,11 +13042,11 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSLD)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -16818,20 +13164,20 @@ func rewriteValueS390X_OpS390XSLW(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SLW x (MOVDconst [c]))
- // result: (SLWconst x [c&63])
+ // result: (SLWconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSLWconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SLW x (AND (MOVDconst [c]) y))
- // result: (SLW x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SLW x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -16844,11 +13190,11 @@ func rewriteValueS390X_OpS390XSLW(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSLW)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -16966,20 +13312,20 @@ func rewriteValueS390X_OpS390XSRAD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRAD x (MOVDconst [c]))
- // result: (SRADconst x [c&63])
+ // result: (SRADconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRADconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SRAD x (AND (MOVDconst [c]) y))
- // result: (SRAD x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SRAD x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -16992,11 +13338,11 @@ func rewriteValueS390X_OpS390XSRAD(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSRAD)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -17126,20 +13472,20 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRAW x (MOVDconst [c]))
- // result: (SRAWconst x [c&63])
+ // result: (SRAWconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRAWconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SRAW x (AND (MOVDconst [c]) y))
- // result: (SRAW x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SRAW x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -17152,11 +13498,11 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSRAW)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -17286,20 +13632,20 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRD x (MOVDconst [c]))
- // result: (SRDconst x [c&63])
+ // result: (SRDconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRDconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SRD x (AND (MOVDconst [c]) y))
- // result: (SRD x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SRD x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -17312,11 +13658,11 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSRD)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -17454,20 +13800,20 @@ func rewriteValueS390X_OpS390XSRW(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRW x (MOVDconst [c]))
- // result: (SRWconst x [c&63])
+ // result: (SRWconst x [int8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRWconst)
- v.AuxInt = c & 63
+ v.AuxInt = int8ToAuxInt(int8(c & 63))
v.AddArg(x)
return true
}
// match: (SRW x (AND (MOVDconst [c]) y))
- // result: (SRW x (ANDWconst <typ.UInt32> [c&63] y))
+ // result: (SRW x (ANDWconst <typ.UInt32> [int32(c&63)] y))
for {
x := v_0
if v_1.Op != OpS390XAND {
@@ -17480,11 +13826,11 @@ func rewriteValueS390X_OpS390XSRW(v *Value) bool {
if v_1_0.Op != OpS390XMOVDconst {
continue
}
- c := v_1_0.AuxInt
+ c := auxIntToInt64(v_1_0.AuxInt)
y := v_1_1
v.reset(OpS390XSRW)
v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
- v0.AuxInt = c & 63
+ v0.AuxInt = int32ToAuxInt(int32(c & 63))
v0.AddArg(y)
v.AddArg2(x, v0)
return true
@@ -17602,16 +13948,16 @@ func rewriteValueS390X_OpS390XSTM2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (STM2 [i] {s} p w2 w3 x:(STM2 [i-8] {s} p w0 w1 mem))
- // cond: x.Uses == 1 && is20Bit(i-8) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)
// result: (STM4 [i-8] {s} p w0 w1 w2 w3 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w2 := v_1
w3 := v_2
x := v_3
- if x.Op != OpS390XSTM2 || x.AuxInt != i-8 || x.Aux != s {
+ if x.Op != OpS390XSTM2 || auxIntToInt32(x.AuxInt) != i-8 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[3]
@@ -17620,22 +13966,22 @@ func rewriteValueS390X_OpS390XSTM2(v *Value) bool {
}
w0 := x.Args[1]
w1 := x.Args[2]
- if !(x.Uses == 1 && is20Bit(i-8) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-8) && clobber(x)) {
break
}
v.reset(OpS390XSTM4)
- v.AuxInt = i - 8
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 8)
+ v.Aux = symToAux(s)
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
// match: (STM2 [i] {s} p (SRDconst [32] x) x mem)
// result: (MOVDstore [i] {s} p x mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || v_1.AuxInt != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
break
}
x := v_1.Args[0]
@@ -17644,8 +13990,8 @@ func rewriteValueS390X_OpS390XSTM2(v *Value) bool {
}
mem := v_3
v.reset(OpS390XMOVDstore)
- v.AuxInt = i
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i)
+ v.Aux = symToAux(s)
v.AddArg3(p, x, mem)
return true
}
@@ -17657,16 +14003,16 @@ func rewriteValueS390X_OpS390XSTMG2(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (STMG2 [i] {s} p w2 w3 x:(STMG2 [i-16] {s} p w0 w1 mem))
- // cond: x.Uses == 1 && is20Bit(i-16) && clobber(x)
+ // cond: x.Uses == 1 && is20Bit(int64(i)-16) && clobber(x)
// result: (STMG4 [i-16] {s} p w0 w1 w2 w3 mem)
for {
- i := v.AuxInt
- s := v.Aux
+ i := auxIntToInt32(v.AuxInt)
+ s := auxToSym(v.Aux)
p := v_0
w2 := v_1
w3 := v_2
x := v_3
- if x.Op != OpS390XSTMG2 || x.AuxInt != i-16 || x.Aux != s {
+ if x.Op != OpS390XSTMG2 || auxIntToInt32(x.AuxInt) != i-16 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[3]
@@ -17675,12 +14021,12 @@ func rewriteValueS390X_OpS390XSTMG2(v *Value) bool {
}
w0 := x.Args[1]
w1 := x.Args[2]
- if !(x.Uses == 1 && is20Bit(i-16) && clobber(x)) {
+ if !(x.Uses == 1 && is20Bit(int64(i)-16) && clobber(x)) {
break
}
v.reset(OpS390XSTMG4)
- v.AuxInt = i - 16
- v.Aux = s
+ v.AuxInt = int32ToAuxInt(i - 16)
+ v.Aux = symToAux(s)
v.AddArg6(p, w0, w1, w2, w3, mem)
return true
}
@@ -17692,36 +14038,36 @@ func rewriteValueS390X_OpS390XSUB(v *Value) bool {
b := v.Block
// match: (SUB x (MOVDconst [c]))
// cond: is32Bit(c)
- // result: (SUBconst x [c])
+ // result: (SUBconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
if !(is32Bit(c)) {
break
}
v.reset(OpS390XSUBconst)
- v.AuxInt = c
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (SUB (MOVDconst [c]) x)
// cond: is32Bit(c)
- // result: (NEG (SUBconst <v.Type> x [c]))
+ // result: (NEG (SUBconst <v.Type> x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
if !(is32Bit(c)) {
break
}
v.reset(OpS390XNEG)
v0 := b.NewValue0(v.Pos, OpS390XSUBconst, v.Type)
- v0.AuxInt = c
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -17738,7 +14084,7 @@ func rewriteValueS390X_OpS390XSUB(v *Value) bool {
return true
}
// match: (SUB <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (SUBload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -17747,17 +14093,17 @@ func rewriteValueS390X_OpS390XSUB(v *Value) bool {
if g.Op != OpS390XMOVDload {
break
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
break
}
v.reset(OpS390XSUBload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -17840,29 +14186,29 @@ func rewriteValueS390X_OpS390XSUBW(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SUBW x (MOVDconst [c]))
- // result: (SUBWconst x [int64(int32(c))])
+ // result: (SUBWconst x [int32(c)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
break
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSUBWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (SUBW (MOVDconst [c]) x)
- // result: (NEGW (SUBWconst <v.Type> x [int64(int32(c))]))
+ // result: (NEGW (SUBWconst <v.Type> x [int32(c)]))
for {
if v_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
+ c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpS390XNEGW)
v0 := b.NewValue0(v.Pos, OpS390XSUBWconst, v.Type)
- v0.AuxInt = int64(int32(c))
+ v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
@@ -17879,7 +14225,7 @@ func rewriteValueS390X_OpS390XSUBW(v *Value) bool {
return true
}
// match: (SUBW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (SUBWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -17888,22 +14234,22 @@ func rewriteValueS390X_OpS390XSUBW(v *Value) bool {
if g.Op != OpS390XMOVWload {
break
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
break
}
v.reset(OpS390XSUBWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (SUBW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (SUBWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -17912,17 +14258,17 @@ func rewriteValueS390X_OpS390XSUBW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
break
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
break
}
v.reset(OpS390XSUBWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -17943,12 +14289,12 @@ func rewriteValueS390X_OpS390XSUBWconst(v *Value) bool {
return true
}
// match: (SUBWconst [c] x)
- // result: (ADDWconst [int64(int32(-c))] x)
+ // result: (ADDWconst [-int32(c)] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
x := v_0
v.reset(OpS390XADDWconst)
- v.AuxInt = int64(int32(-c))
+ v.AuxInt = int32ToAuxInt(-int32(c))
v.AddArg(x)
return true
}
@@ -17958,47 +14304,47 @@ func rewriteValueS390X_OpS390XSUBWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SUBWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (SUBWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XSUBWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (SUBWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (SUBWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (SUBWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XSUBWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -18031,32 +14377,32 @@ func rewriteValueS390X_OpS390XSUBconst(v *Value) bool {
return true
}
// match: (SUBconst (MOVDconst [d]) [c])
- // result: (MOVDconst [d-c])
+ // result: (MOVDconst [d-int64(c)])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = d - c
+ v.AuxInt = int64ToAuxInt(d - int64(c))
return true
}
// match: (SUBconst (SUBconst x [d]) [c])
- // cond: is32Bit(-c-d)
+ // cond: is32Bit(-int64(c)-int64(d))
// result: (ADDconst [-c-d] x)
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XSUBconst {
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(OpS390XADDconst)
- v.AuxInt = -c - d
+ v.AuxInt = int32ToAuxInt(-c - d)
v.AddArg(x)
return true
}
@@ -18091,47 +14437,47 @@ func rewriteValueS390X_OpS390XSUBload(v *Value) bool {
return true
}
// match: (SUBload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (SUBload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XSUBload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (SUBload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (SUBload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (SUBload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XSUBload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -18266,7 +14612,7 @@ func rewriteValueS390X_OpS390XXOR(v *Value) bool {
return true
}
// match: (XOR <t> x g:(MOVDload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (XORload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -18276,17 +14622,17 @@ func rewriteValueS390X_OpS390XXOR(v *Value) bool {
if g.Op != OpS390XMOVDload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XXORload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -18298,16 +14644,16 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORW x (MOVDconst [c]))
- // result: (XORWconst [int64(int32(c))] x)
+ // result: (XORWconst [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 {
continue
}
- c := v_1.AuxInt
+ c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XXORWconst)
- v.AuxInt = int64(int32(c))
+ v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
@@ -18349,7 +14695,7 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool {
return true
}
// match: (XORW <t> x g:(MOVWload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (XORWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -18359,24 +14705,24 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool {
if g.Op != OpS390XMOVWload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XXORWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
break
}
// match: (XORW <t> x g:(MOVWZload [off] {sym} ptr mem))
- // cond: ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)
// result: (XORWload <t> [off] {sym} x ptr mem)
for {
t := v.Type
@@ -18386,17 +14732,17 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool {
if g.Op != OpS390XMOVWZload {
continue
}
- off := g.AuxInt
- sym := g.Aux
+ off := auxIntToInt32(g.AuxInt)
+ sym := auxToSym(g.Aux)
mem := g.Args[1]
ptr := g.Args[0]
- if !(ptr.Op != OpSB && is20Bit(off) && canMergeLoadClobber(v, g, x) && clobber(g)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off)) && canMergeLoadClobber(v, g, x) && clobber(g)) {
continue
}
v.reset(OpS390XXORWload)
v.Type = t
- v.AuxInt = off
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
@@ -18419,15 +14765,15 @@ func rewriteValueS390X_OpS390XXORWconst(v *Value) bool {
return true
}
// match: (XORWconst [c] (MOVDconst [d]))
- // result: (MOVDconst [c^d])
+ // result: (MOVDconst [int64(c)^d])
for {
- c := v.AuxInt
+ c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt64(v_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c ^ d
+ v.AuxInt = int64ToAuxInt(int64(c) ^ d)
return true
}
return false
@@ -18437,47 +14783,47 @@ func rewriteValueS390X_OpS390XXORWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (XORWload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (XORWload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XXORWload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (XORWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (XORWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (XORWload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XXORWload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -18538,47 +14884,47 @@ func rewriteValueS390X_OpS390XXORload(v *Value) bool {
return true
}
// match: (XORload [off1] {sym} x (ADDconst [off2] ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(off1+off2)
+ // cond: ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))
// result: (XORload [off1+off2] {sym} x ptr mem)
for {
- off1 := v.AuxInt
- sym := v.Aux
+ off1 := auxIntToInt32(v.AuxInt)
+ sym := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XADDconst {
break
}
- off2 := v_1.AuxInt
+ off2 := auxIntToInt32(v_1.AuxInt)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(off1+off2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2))) {
break
}
v.reset(OpS390XXORload)
- v.AuxInt = off1 + off2
- v.Aux = sym
+ v.AuxInt = int32ToAuxInt(off1 + off2)
+ v.Aux = symToAux(sym)
v.AddArg3(x, ptr, mem)
return true
}
// match: (XORload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem)
- // cond: ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)
- // result: (XORload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+ // cond: ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)
+ // result: (XORload [o1+o2] {mergeSymTyped(s1, s2)} x ptr mem)
for {
- o1 := v.AuxInt
- s1 := v.Aux
+ o1 := auxIntToInt32(v.AuxInt)
+ s1 := auxToSym(v.Aux)
x := v_0
if v_1.Op != OpS390XMOVDaddr {
break
}
- o2 := v_1.AuxInt
- s2 := v_1.Aux
+ o2 := auxIntToInt32(v_1.AuxInt)
+ s2 := auxToSym(v_1.Aux)
ptr := v_1.Args[0]
mem := v_2
- if !(ptr.Op != OpSB && is20Bit(o1+o2) && canMergeSym(s1, s2)) {
+ if !(ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2)) {
break
}
v.reset(OpS390XXORload)
- v.AuxInt = o1 + o2
- v.Aux = mergeSym(s1, s2)
+ v.AuxInt = int32ToAuxInt(o1 + o2)
+ v.Aux = symToAux(mergeSymTyped(s1, s2))
v.AddArg3(x, ptr, mem)
return true
}
@@ -18662,19 +15008,19 @@ func rewriteValueS390X_OpSelect0(v *Value) bool {
return true
}
// match: (Select0 (ADDCconst (MOVDconst [c]) [d]))
- // result: (MOVDconst [c+d])
+ // result: (MOVDconst [c+int64(d)])
for {
if v_0.Op != OpS390XADDCconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt16(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpS390XMOVDconst {
break
}
- c := v_0_0.AuxInt
+ c := auxIntToInt64(v_0_0.AuxInt)
v.reset(OpS390XMOVDconst)
- v.AuxInt = c + d
+ v.AuxInt = int64ToAuxInt(c + int64(d))
return true
}
// match: (Select0 (SUBC (MOVDconst [c]) (MOVDconst [d])))
@@ -18859,38 +15205,38 @@ func rewriteValueS390X_OpSelect1(v *Value) bool {
return true
}
// match: (Select1 (ADDCconst (MOVDconst [c]) [d]))
- // cond: uint64(c+d) >= uint64(c) && c+d == 0
+ // cond: uint64(c+int64(d)) >= uint64(c) && c+int64(d) == 0
// result: (FlagEQ)
for {
if v_0.Op != OpS390XADDCconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt16(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpS390XMOVDconst {
break
}
- c := v_0_0.AuxInt
- if !(uint64(c+d) >= uint64(c) && c+d == 0) {
+ c := auxIntToInt64(v_0_0.AuxInt)
+ if !(uint64(c+int64(d)) >= uint64(c) && c+int64(d) == 0) {
break
}
v.reset(OpS390XFlagEQ)
return true
}
// match: (Select1 (ADDCconst (MOVDconst [c]) [d]))
- // cond: uint64(c+d) >= uint64(c) && c+d != 0
+ // cond: uint64(c+int64(d)) >= uint64(c) && c+int64(d) != 0
// result: (FlagLT)
for {
if v_0.Op != OpS390XADDCconst {
break
}
- d := v_0.AuxInt
+ d := auxIntToInt16(v_0.AuxInt)
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpS390XMOVDconst {
break
}
- c := v_0_0.AuxInt
- if !(uint64(c+d) >= uint64(c) && c+d != 0) {
+ c := auxIntToInt64(v_0_0.AuxInt)
+ if !(uint64(c+int64(d)) >= uint64(c) && c+int64(d) != 0) {
break
}
v.reset(OpS390XFlagLT)
diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go
index cef781ffaa..e0fa9768d9 100644
--- a/src/cmd/compile/internal/ssa/rewritedec.go
+++ b/src/cmd/compile/internal/ssa/rewritedec.go
@@ -328,9 +328,10 @@ func rewriteValuedec_OpStore(v *Value) bool {
v.AddArg3(v0, len, v1)
return true
}
- // match: (Store dst (SliceMake ptr len cap) mem)
- // result: (Store {typ.Int} (OffPtr <typ.IntPtr> [2*config.PtrSize] dst) cap (Store {typ.Int} (OffPtr <typ.IntPtr> [config.PtrSize] dst) len (Store {typ.BytePtr} dst ptr mem)))
+ // match: (Store {t} dst (SliceMake ptr len cap) mem)
+ // result: (Store {typ.Int} (OffPtr <typ.IntPtr> [2*config.PtrSize] dst) cap (Store {typ.Int} (OffPtr <typ.IntPtr> [config.PtrSize] dst) len (Store {t.Elem().PtrTo()} dst ptr mem)))
for {
+ t := auxToType(v.Aux)
dst := v_0
if v_1.Op != OpSliceMake {
break
@@ -350,7 +351,7 @@ func rewriteValuedec_OpStore(v *Value) bool {
v2.AuxInt = int64ToAuxInt(config.PtrSize)
v2.AddArg(dst)
v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v3.Aux = typeToAux(typ.BytePtr)
+ v3.Aux = typeToAux(t.Elem().PtrTo())
v3.AddArg3(dst, ptr, mem)
v1.AddArg3(v2, len, v3)
v.AddArg3(v0, cap, v1)
diff --git a/src/cmd/compile/internal/ssa/softfloat.go b/src/cmd/compile/internal/ssa/softfloat.go
index 4b578b133b..a8a8f83629 100644
--- a/src/cmd/compile/internal/ssa/softfloat.go
+++ b/src/cmd/compile/internal/ssa/softfloat.go
@@ -18,6 +18,7 @@ func softfloat(f *Func) {
for _, b := range f.Blocks {
for _, v := range b.Values {
if v.Type.IsFloat() {
+ f.unCache(v)
switch v.Op {
case OpPhi, OpLoad, OpArg:
if v.Type.Size() == 4 {
@@ -72,7 +73,7 @@ func softfloat(f *Func) {
if newInt64 && f.Config.RegSize == 4 {
// On 32bit arch, decompose Uint64 introduced in the switch above.
decomposeBuiltIn(f)
- applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
+ applyRewrite(f, rewriteBlockdec64, rewriteValuedec64, removeDeadValues)
}
}
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 7ead0ff300..6692df7921 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -54,6 +54,9 @@ type Value struct {
// nor a slot on Go stack, and the generation of this value is delayed to its use time.
OnWasmStack bool
+ // Is this value in the per-function constant cache? If so, remove from cache before changing it or recycling it.
+ InCache bool
+
// Storage for the first three args
argstorage [3]*Value
}
@@ -210,7 +213,7 @@ func (v *Value) auxString() string {
}
return s + fmt.Sprintf(" [%s]", v.AuxValAndOff())
case auxCCop:
- return fmt.Sprintf(" {%s}", v.Aux.(Op))
+ return fmt.Sprintf(" {%s}", Op(v.AuxInt))
case auxS390XCCMask, auxS390XRotateParams:
return fmt.Sprintf(" {%v}", v.Aux)
case auxFlagConstant:
@@ -332,6 +335,9 @@ func (v *Value) resetArgs() {
// of cmd/compile by almost 10%, and slows it down.
//go:noinline
func (v *Value) reset(op Op) {
+ if v.InCache {
+ v.Block.Func.unCache(v)
+ }
v.Op = op
v.resetArgs()
v.AuxInt = 0
@@ -342,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.InCache {
+ v.Block.Func.unCache(v)
+ }
v.Op = OpCopy
v.resetArgs()
v.AddArg(a)
@@ -460,3 +469,23 @@ func (v *Value) LackingPos() bool {
return v.Op == OpVarDef || v.Op == OpVarKill || v.Op == OpVarLive || v.Op == OpPhi ||
(v.Op == OpFwdRef || v.Op == OpCopy) && v.Type == types.TypeMem
}
+
+// removeable reports whether the value v can be removed from the SSA graph entirely
+// if its use count drops to 0.
+func (v *Value) removeable() bool {
+ if v.Type.IsVoid() {
+ // Void ops, like nil pointer checks, must stay.
+ return false
+ }
+ if v.Type.IsMemory() {
+ // All memory ops aren't needed here, but we do need
+ // to keep calls at least (because they might have
+ // syncronization operations we can't see).
+ return false
+ }
+ if v.Op.HasSideEffects() {
+ // These are mostly synchronization operations.
+ return false
+ }
+ return true
+}
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index c7fb059475..214798a1ab 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -31,7 +31,7 @@ func needwb(v *Value, zeroes map[ID]ZeroRegion) bool {
if !ok {
v.Fatalf("store aux is not a type: %s", v.LongString())
}
- if !t.HasHeapPointer() {
+ if !t.HasPointers() {
return false
}
if IsStackAddr(v.Args[0]) {
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 20ae856bba..a777a5fd90 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -1230,6 +1230,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
@@ -1398,14 +1403,9 @@ func (t *Type) IsUntyped() bool {
return false
}
-// TODO(austin): We probably only need HasHeapPointer. See
-// golang.org/cl/73412 for discussion.
-
+// HasPointers reports whether t contains a heap pointer.
+// Note that this function ignores pointers to go:notinheap types.
func (t *Type) HasPointers() bool {
- return t.hasPointers1(false)
-}
-
-func (t *Type) hasPointers1(ignoreNotInHeap bool) bool {
switch t.Etype {
case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
@@ -1415,34 +1415,27 @@ func (t *Type) hasPointers1(ignoreNotInHeap bool) bool {
if t.NumElem() == 0 { // empty array has no pointers
return false
}
- return t.Elem().hasPointers1(ignoreNotInHeap)
+ return t.Elem().HasPointers()
case TSTRUCT:
for _, t1 := range t.Fields().Slice() {
- if t1.Type.hasPointers1(ignoreNotInHeap) {
+ if t1.Type.HasPointers() {
return true
}
}
return false
case TPTR, TSLICE:
- return !(ignoreNotInHeap && t.Elem().NotInHeap())
+ return !t.Elem().NotInHeap()
case TTUPLE:
ttup := t.Extra.(*Tuple)
- return ttup.first.hasPointers1(ignoreNotInHeap) || ttup.second.hasPointers1(ignoreNotInHeap)
+ return ttup.first.HasPointers() || ttup.second.HasPointers()
}
return true
}
-// HasHeapPointer reports whether t contains a heap pointer.
-// This is used for write barrier insertion, so it ignores
-// pointers to go:notinheap types.
-func (t *Type) HasHeapPointer() bool {
- return t.hasPointers1(true)
-}
-
func (t *Type) Symbol() *obj.LSym {
return TypeLinkSym(t)
}
diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go
index 2de978c28a..c21ac32297 100644
--- a/src/cmd/compile/internal/x86/ssa.go
+++ b/src/cmd/compile/internal/x86/ssa.go
@@ -261,8 +261,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
n.To.Reg = x86.REG_DX
}
- j.To.Val = n
- j2.To.Val = s.Pc()
+ j.To.SetTarget(n)
+ j2.To.SetTarget(s.Pc())
}
case ssa.Op386HMULL, ssa.Op386HMULLU:
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index a83ae35293..5ea5c81656 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -1106,8 +1106,9 @@ func (t *tester) cgoTest(dt *distTest) error {
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=external")
- // A -g argument in CGO_CFLAGS should not affect how the test runs.
- cmd.Env = append(cmd.Env, "CGO_CFLAGS=-g0")
+ // cgo should be able to cope with both -g arguments and colored
+ // diagnostics.
+ cmd.Env = append(cmd.Env, "CGO_CFLAGS=-g0 -fdiagnostics-color")
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=auto")
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=external")
diff --git a/src/cmd/fix/fix.go b/src/cmd/fix/fix.go
index 2c64e9b414..b49db37571 100644
--- a/src/cmd/fix/fix.go
+++ b/src/cmd/fix/fix.go
@@ -7,13 +7,9 @@ package main
import (
"fmt"
"go/ast"
- "go/parser"
"go/token"
- "os"
"path"
- "reflect"
"strconv"
- "strings"
)
type fix struct {
@@ -323,160 +319,12 @@ func declImports(gen *ast.GenDecl, path string) bool {
return false
}
-// isPkgDot reports whether t is the expression "pkg.name"
-// where pkg is an imported identifier.
-func isPkgDot(t ast.Expr, pkg, name string) bool {
- sel, ok := t.(*ast.SelectorExpr)
- return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name
-}
-
-// isPtrPkgDot reports whether f is the expression "*pkg.name"
-// where pkg is an imported identifier.
-func isPtrPkgDot(t ast.Expr, pkg, name string) bool {
- ptr, ok := t.(*ast.StarExpr)
- return ok && isPkgDot(ptr.X, pkg, name)
-}
-
// isTopName reports whether n is a top-level unresolved identifier with the given name.
func isTopName(n ast.Expr, name string) bool {
id, ok := n.(*ast.Ident)
return ok && id.Name == name && id.Obj == nil
}
-// isName reports whether n is an identifier with the given name.
-func isName(n ast.Expr, name string) bool {
- id, ok := n.(*ast.Ident)
- return ok && id.String() == name
-}
-
-// isCall reports whether t is a call to pkg.name.
-func isCall(t ast.Expr, pkg, name string) bool {
- call, ok := t.(*ast.CallExpr)
- return ok && isPkgDot(call.Fun, pkg, name)
-}
-
-// If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil.
-func isIdent(n interface{}) *ast.Ident {
- id, _ := n.(*ast.Ident)
- return id
-}
-
-// refersTo reports whether n is a reference to the same object as x.
-func refersTo(n ast.Node, x *ast.Ident) bool {
- id, ok := n.(*ast.Ident)
- // The test of id.Name == x.Name handles top-level unresolved
- // identifiers, which all have Obj == nil.
- return ok && id.Obj == x.Obj && id.Name == x.Name
-}
-
-// isBlank reports whether n is the blank identifier.
-func isBlank(n ast.Expr) bool {
- return isName(n, "_")
-}
-
-// isEmptyString reports whether n is an empty string literal.
-func isEmptyString(n ast.Expr) bool {
- lit, ok := n.(*ast.BasicLit)
- return ok && lit.Kind == token.STRING && len(lit.Value) == 2
-}
-
-func warn(pos token.Pos, msg string, args ...interface{}) {
- if pos.IsValid() {
- msg = "%s: " + msg
- arg1 := []interface{}{fset.Position(pos).String()}
- args = append(arg1, args...)
- }
- fmt.Fprintf(os.Stderr, msg+"\n", args...)
-}
-
-// countUses returns the number of uses of the identifier x in scope.
-func countUses(x *ast.Ident, scope []ast.Stmt) int {
- count := 0
- ff := func(n interface{}) {
- if n, ok := n.(ast.Node); ok && refersTo(n, x) {
- count++
- }
- }
- for _, n := range scope {
- walk(n, ff)
- }
- return count
-}
-
-// rewriteUses replaces all uses of the identifier x and !x in scope
-// with f(x.Pos()) and fnot(x.Pos()).
-func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) {
- var lastF ast.Expr
- ff := func(n interface{}) {
- ptr, ok := n.(*ast.Expr)
- if !ok {
- return
- }
- nn := *ptr
-
- // The child node was just walked and possibly replaced.
- // If it was replaced and this is a negation, replace with fnot(p).
- not, ok := nn.(*ast.UnaryExpr)
- if ok && not.Op == token.NOT && not.X == lastF {
- *ptr = fnot(nn.Pos())
- return
- }
- if refersTo(nn, x) {
- lastF = f(nn.Pos())
- *ptr = lastF
- }
- }
- for _, n := range scope {
- walk(n, ff)
- }
-}
-
-// assignsTo reports whether any of the code in scope assigns to or takes the address of x.
-func assignsTo(x *ast.Ident, scope []ast.Stmt) bool {
- assigned := false
- ff := func(n interface{}) {
- if assigned {
- return
- }
- switch n := n.(type) {
- case *ast.UnaryExpr:
- // use of &x
- if n.Op == token.AND && refersTo(n.X, x) {
- assigned = true
- return
- }
- case *ast.AssignStmt:
- for _, l := range n.Lhs {
- if refersTo(l, x) {
- assigned = true
- return
- }
- }
- }
- }
- for _, n := range scope {
- if assigned {
- break
- }
- walk(n, ff)
- }
- return assigned
-}
-
-// newPkgDot returns an ast.Expr referring to "pkg.name" at position pos.
-func newPkgDot(pos token.Pos, pkg, name string) ast.Expr {
- return &ast.SelectorExpr{
- X: &ast.Ident{
- NamePos: pos,
- Name: pkg,
- },
- Sel: &ast.Ident{
- NamePos: pos,
- Name: name,
- },
- }
-}
-
// renameTop renames all references to the top-level name old.
// It reports whether it makes any changes.
func renameTop(f *ast.File, old, new string) bool {
@@ -707,143 +555,3 @@ func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) {
}
return
}
-
-func usesImport(f *ast.File, path string) (used bool) {
- spec := importSpec(f, path)
- if spec == nil {
- return
- }
-
- name := spec.Name.String()
- switch name {
- case "<nil>":
- // If the package name is not explicitly specified,
- // make an educated guess. This is not guaranteed to be correct.
- lastSlash := strings.LastIndex(path, "/")
- if lastSlash == -1 {
- name = path
- } else {
- name = path[lastSlash+1:]
- }
- case "_", ".":
- // Not sure if this import is used - err on the side of caution.
- return true
- }
-
- walk(f, func(n interface{}) {
- sel, ok := n.(*ast.SelectorExpr)
- if ok && isTopName(sel.X, name) {
- used = true
- }
- })
-
- return
-}
-
-func expr(s string) ast.Expr {
- x, err := parser.ParseExpr(s)
- if err != nil {
- panic("parsing " + s + ": " + err.Error())
- }
- // Remove position information to avoid spurious newlines.
- killPos(reflect.ValueOf(x))
- return x
-}
-
-var posType = reflect.TypeOf(token.Pos(0))
-
-func killPos(v reflect.Value) {
- switch v.Kind() {
- case reflect.Ptr, reflect.Interface:
- if !v.IsNil() {
- killPos(v.Elem())
- }
- case reflect.Slice:
- n := v.Len()
- for i := 0; i < n; i++ {
- killPos(v.Index(i))
- }
- case reflect.Struct:
- n := v.NumField()
- for i := 0; i < n; i++ {
- f := v.Field(i)
- if f.Type() == posType {
- f.SetInt(0)
- continue
- }
- killPos(f)
- }
- }
-}
-
-// A Rename describes a single renaming.
-type rename struct {
- OldImport string // only apply rename if this import is present
- NewImport string // add this import during rewrite
- Old string // old name: p.T or *p.T
- New string // new name: p.T or *p.T
-}
-
-func renameFix(tab []rename) func(*ast.File) bool {
- return func(f *ast.File) bool {
- return renameFixTab(f, tab)
- }
-}
-
-func parseName(s string) (ptr bool, pkg, nam string) {
- i := strings.Index(s, ".")
- if i < 0 {
- panic("parseName: invalid name " + s)
- }
- if strings.HasPrefix(s, "*") {
- ptr = true
- s = s[1:]
- i--
- }
- pkg = s[:i]
- nam = s[i+1:]
- return
-}
-
-func renameFixTab(f *ast.File, tab []rename) bool {
- fixed := false
- added := map[string]bool{}
- check := map[string]bool{}
- for _, t := range tab {
- if !imports(f, t.OldImport) {
- continue
- }
- optr, opkg, onam := parseName(t.Old)
- walk(f, func(n interface{}) {
- np, ok := n.(*ast.Expr)
- if !ok {
- return
- }
- x := *np
- if optr {
- p, ok := x.(*ast.StarExpr)
- if !ok {
- return
- }
- x = p.X
- }
- if !isPkgDot(x, opkg, onam) {
- return
- }
- if t.NewImport != "" && !added[t.NewImport] {
- addImport(f, t.NewImport)
- added[t.NewImport] = true
- }
- *np = expr(t.New)
- check[t.OldImport] = true
- fixed = true
- })
- }
-
- for ipath := range check {
- if !usesImport(f, ipath) {
- deleteImport(f, ipath)
- }
- }
- return fixed
-}
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 21670b9996..0952dbb84c 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -7,8 +7,8 @@ require (
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.20200625141748-0b26df4a2231
+ 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/tools v0.0.0-20200901153117-6e59e24738da
golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316 // indirect
)
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index 1b5ef515c2..adbc5a96ac 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -6,34 +6,34 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
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=
+github.com/yuin/goldmark v1.2.1/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=
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.20200625141748-0b26df4a2231 h1:R11LxkoUvECaAHdM5/ZOevSR7n+016EgTw8nbE1l+XM=
-golang.org/x/mod v0.3.1-0.20200625141748-0b26df4a2231/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.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/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-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
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-20200625203802-6e8e738ad208/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-20200323222414-85ca7c5b95cd/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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-20200901153117-6e59e24738da h1:8nFbt74voFOsM+Hb5XtF+1SNbbf3dzikH5osZO1hyyo=
+golang.org/x/tools v0.0.0-20200901153117-6e59e24738da/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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=
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 68bad3cff1..8ad4f66d09 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -916,6 +916,7 @@
// Dir string // directory holding files for this module, if any
// GoMod string // path to go.mod file used when loading this module, if any
// GoVersion string // go version used in module
+// Retracted string // retraction information, if any (with -retracted or -u)
// Error *ModuleError // error loading module
// }
//
@@ -947,14 +948,16 @@
// The -u flag adds information about available upgrades.
// When the latest version of a given module is newer than
// the current one, list -u sets the Module's Update field
-// to information about the newer module.
+// to information about the newer module. list -u will also set
+// the module's Retracted field if the current version is retracted.
// The Module's String method indicates an available upgrade by
// formatting the newer version in brackets after the current version.
+// If a version is retracted, the string "(retracted)" will follow it.
// For example, 'go list -m -u all' might print:
//
// my/main/module
// golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
-// rsc.io/pdf v0.1.1 [v0.1.2]
+// rsc.io/pdf v0.1.1 (retracted) [v0.1.2]
//
// (For tools, 'go list -m -u -json all' may be more convenient to parse.)
//
@@ -964,6 +967,14 @@
// the default output format to display the module path followed by the
// space-separated version list.
//
+// The -retracted flag causes list to report information about retracted
+// module versions. When -retracted is used with -f or -json, the Retracted
+// field will be set to a string explaining why the version was retracted.
+// The string is taken from comments on the retract directive in the
+// module's go.mod file. When -retracted is used with -versions, retracted
+// versions are listed together with unretracted versions. The -retracted
+// flag may be used with or without -m.
+//
// The arguments to list -m are interpreted as a list of modules, not packages.
// The main module is the module containing the current directory.
// The active modules are the main module and its dependencies.
@@ -1100,9 +1111,14 @@
// module path and version pair. If the @v is omitted, a replacement without
// 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
+// -retract=version is a no-op if that retraction already exists.
+//
// The -require, -droprequire, -exclude, -dropexclude, -replace,
-// and -dropreplace editing flags may be repeated, and the changes
-// are applied in the order given.
+// -dropreplace, -retract, and -dropretract editing flags may be repeated,
+// and the changes are applied in the order given.
//
// The -go=version flag sets the expected Go language version.
//
@@ -1136,6 +1152,15 @@
// New Module
// }
//
+// type Retract struct {
+// Low string
+// High string
+// Rationale string
+// }
+//
+// Retract entries representing a single version (not an interval) will have
+// the "Low" and "High" fields set to the same value.
+//
// Note that this only describes the go.mod file itself, not other modules
// referred to indirectly. For the full set of modules available to a build,
// use 'go list -m -json all'.
@@ -1894,15 +1919,17 @@
// require new/thing/v2 v2.3.4
// exclude old/thing v1.2.3
// replace bad/thing v1.4.5 => good/thing v1.4.5
+// retract v1.5.6
//
// The verbs are
// module, to define the module path;
// go, to set the expected language version;
// require, to require a particular module at a given version or later;
-// exclude, to exclude a particular module version from use; and
-// replace, to replace a module version with a different module version.
+// exclude, to exclude a particular module version from use;
+// replace, to replace a module version with a different module version; and
+// retract, to indicate a previously released version should not be used.
// Exclude and replace apply only in the main module's go.mod and are ignored
-// in dependencies. See https://research.swtch.com/vgo-mvs for details.
+// in dependencies. See https://golang.org/ref/mod for details.
//
// The leading verb can be factored out of adjacent lines to create a block,
// like in Go imports:
@@ -2145,7 +2172,10 @@
// 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.
+// 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.
//
// The -t flag instructs get to also download the packages required to build
// the tests for the specified packages.
diff --git a/src/cmd/go/internal/base/flag.go b/src/cmd/go/internal/base/flag.go
index 6727196816..c97c744520 100644
--- a/src/cmd/go/internal/base/flag.go
+++ b/src/cmd/go/internal/base/flag.go
@@ -28,13 +28,42 @@ 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", "", "")
}
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index f9bbcd9180..9bf1db73ef 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -27,7 +27,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 +49,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)
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/get/get.go b/src/cmd/go/internal/get/get.go
index e5bacadaa3..3f7a66384a 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -18,8 +18,11 @@ 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"
+
+ "golang.org/x/mod/module"
)
var CmdGet = &base.Command{
@@ -41,7 +44,10 @@ 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.
+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.
The -t flag instructs get to also download the packages required to build
the tests for the specified packages.
@@ -103,14 +109,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) {
@@ -403,17 +407,12 @@ 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
)
- security := web.SecureOnly
- if Insecure {
- security = web.Insecure
- }
-
// p can be either a real package, or a pseudo-package whose “import path” is
// actually a wildcard pattern.
// Trim the path at the element containing the first wildcard,
@@ -427,22 +426,26 @@ func downloadPackage(p *load.Package) error {
}
importPrefix = importPrefix[:slash]
}
- if err := CheckImportPath(importPrefix); err != nil {
+ if err := module.CheckImportPath(importPrefix); err != nil {
return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
}
+ security := web.SecureOnly
+ 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).
@@ -450,10 +453,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
}
@@ -467,13 +470,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) && !Insecure {
+ if !blindRepo && !vcsCmd.IsSecure(repo) && security != web.Insecure {
return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
}
@@ -496,7 +499,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
}
@@ -512,7 +515,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.
@@ -533,12 +536,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
}
}
@@ -547,12 +550,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
}
@@ -560,7 +563,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/get/path.go b/src/cmd/go/internal/get/path.go
deleted file mode 100644
index ce2e0cdd70..0000000000
--- a/src/cmd/go/internal/get/path.go
+++ /dev/null
@@ -1,192 +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.
-
-package get
-
-import (
- "fmt"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// The following functions are copied verbatim from golang.org/x/mod/module/module.go,
-// with a change to additionally reject Windows short-names,
-// and one to accept arbitrary letters (golang.org/issue/29101).
-//
-// TODO(bcmills): After the call site for this function is backported,
-// consolidate this back down to a single copy.
-//
-// NOTE: DO NOT MERGE THESE UNTIL WE DECIDE ABOUT ARBITRARY LETTERS IN MODULE MODE.
-
-// CheckImportPath checks that an import path is valid.
-func CheckImportPath(path string) error {
- if err := checkPath(path, false); err != nil {
- return fmt.Errorf("malformed import path %q: %v", path, err)
- }
- return nil
-}
-
-// checkPath checks that a general path is valid.
-// It returns an error describing why but not mentioning path.
-// Because these checks apply to both module paths and import paths,
-// the caller is expected to add the "malformed ___ path %q: " prefix.
-// fileName indicates whether the final element of the path is a file name
-// (as opposed to a directory name).
-func checkPath(path string, fileName bool) error {
- if !utf8.ValidString(path) {
- return fmt.Errorf("invalid UTF-8")
- }
- if path == "" {
- return fmt.Errorf("empty string")
- }
- if path[0] == '-' {
- return fmt.Errorf("leading dash")
- }
- if strings.Contains(path, "//") {
- return fmt.Errorf("double slash")
- }
- if path[len(path)-1] == '/' {
- return fmt.Errorf("trailing slash")
- }
- elemStart := 0
- for i, r := range path {
- if r == '/' {
- if err := checkElem(path[elemStart:i], fileName); err != nil {
- return err
- }
- elemStart = i + 1
- }
- }
- if err := checkElem(path[elemStart:], fileName); err != nil {
- return err
- }
- return nil
-}
-
-// checkElem checks whether an individual path element is valid.
-// fileName indicates whether the element is a file name (not a directory name).
-func checkElem(elem string, fileName bool) error {
- if elem == "" {
- return fmt.Errorf("empty path element")
- }
- if strings.Count(elem, ".") == len(elem) {
- return fmt.Errorf("invalid path element %q", elem)
- }
- if elem[0] == '.' && !fileName {
- return fmt.Errorf("leading dot in path element")
- }
- if elem[len(elem)-1] == '.' {
- return fmt.Errorf("trailing dot in path element")
- }
-
- charOK := pathOK
- if fileName {
- charOK = fileNameOK
- }
- for _, r := range elem {
- if !charOK(r) {
- return fmt.Errorf("invalid char %q", r)
- }
- }
-
- // Windows disallows a bunch of path elements, sadly.
- // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
- short := elem
- if i := strings.Index(short, "."); i >= 0 {
- short = short[:i]
- }
- for _, bad := range badWindowsNames {
- if strings.EqualFold(bad, short) {
- return fmt.Errorf("disallowed path element %q", elem)
- }
- }
-
- // Reject path components that look like Windows short-names.
- // Those usually end in a tilde followed by one or more ASCII digits.
- if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 {
- suffix := short[tilde+1:]
- suffixIsDigits := true
- for _, r := range suffix {
- if r < '0' || r > '9' {
- suffixIsDigits = false
- break
- }
- }
- if suffixIsDigits {
- return fmt.Errorf("trailing tilde and digits in path element")
- }
- }
-
- return nil
-}
-
-// pathOK reports whether r can appear in an import path element.
-//
-// NOTE: This function DIVERGES from module mode pathOK by accepting Unicode letters.
-func pathOK(r rune) bool {
- if r < utf8.RuneSelf {
- return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' ||
- '0' <= r && r <= '9' ||
- 'A' <= r && r <= 'Z' ||
- 'a' <= r && r <= 'z'
- }
- return unicode.IsLetter(r)
-}
-
-// fileNameOK reports whether r can appear in a file name.
-// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.
-// If we expand the set of allowed characters here, we have to
-// work harder at detecting potential case-folding and normalization collisions.
-// See note about "safe encoding" below.
-func fileNameOK(r rune) bool {
- if r < utf8.RuneSelf {
- // Entire set of ASCII punctuation, from which we remove characters:
- // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
- // We disallow some shell special characters: " ' * < > ? ` |
- // (Note that some of those are disallowed by the Windows file system as well.)
- // We also disallow path separators / : and \ (fileNameOK is only called on path element characters).
- // We allow spaces (U+0020) in file names.
- const allowed = "!#$%&()+,-.=@[]^_{}~ "
- if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {
- return true
- }
- for i := 0; i < len(allowed); i++ {
- if rune(allowed[i]) == r {
- return true
- }
- }
- return false
- }
- // It may be OK to add more ASCII punctuation here, but only carefully.
- // For example Windows disallows < > \, and macOS disallows :, so we must not allow those.
- return unicode.IsLetter(r)
-}
-
-// badWindowsNames are the reserved file path elements on Windows.
-// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
-var badWindowsNames = []string{
- "CON",
- "PRN",
- "AUX",
- "NUL",
- "COM1",
- "COM2",
- "COM3",
- "COM4",
- "COM5",
- "COM6",
- "COM7",
- "COM8",
- "COM9",
- "LPT1",
- "LPT2",
- "LPT3",
- "LPT4",
- "LPT5",
- "LPT6",
- "LPT7",
- "LPT8",
- "LPT9",
-}
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index e68c39f392..23500dd9d8 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -10,6 +10,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "fmt"
"io"
"os"
"sort"
@@ -215,6 +216,7 @@ applied to a Go struct, but now a Module struct:
Dir string // directory holding files for this module, if any
GoMod string // path to go.mod file used when loading this module, if any
GoVersion string // go version used in module
+ Retracted string // retraction information, if any (with -retracted or -u)
Error *ModuleError // error loading module
}
@@ -246,14 +248,16 @@ the replaced source code.)
The -u flag adds information about available upgrades.
When the latest version of a given module is newer than
the current one, list -u sets the Module's Update field
-to information about the newer module.
+to information about the newer module. list -u will also set
+the module's Retracted field if the current version is retracted.
The Module's String method indicates an available upgrade by
formatting the newer version in brackets after the current version.
+If a version is retracted, the string "(retracted)" will follow it.
For example, 'go list -m -u all' might print:
my/main/module
golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
- rsc.io/pdf v0.1.1 [v0.1.2]
+ rsc.io/pdf v0.1.1 (retracted) [v0.1.2]
(For tools, 'go list -m -u -json all' may be more convenient to parse.)
@@ -263,6 +267,14 @@ to semantic versioning, earliest to latest. The flag also changes
the default output format to display the module path followed by the
space-separated version list.
+The -retracted flag causes list to report information about retracted
+module versions. When -retracted is used with -f or -json, the Retracted
+field will be set to a string explaining why the version was retracted.
+The string is taken from comments on the retract directive in the
+module's go.mod file. When -retracted is used with -versions, retracted
+versions are listed together with unretracted versions. The -retracted
+flag may be used with or without -m.
+
The arguments to list -m are interpreted as a list of modules, not packages.
The main module is the module containing the current directory.
The active modules are the main module and its dependencies.
@@ -296,17 +308,18 @@ func init() {
}
var (
- listCompiled = CmdList.Flag.Bool("compiled", false, "")
- listDeps = CmdList.Flag.Bool("deps", false, "")
- listE = CmdList.Flag.Bool("e", false, "")
- listExport = CmdList.Flag.Bool("export", false, "")
- listFmt = CmdList.Flag.String("f", "", "")
- listFind = CmdList.Flag.Bool("find", false, "")
- listJson = CmdList.Flag.Bool("json", false, "")
- listM = CmdList.Flag.Bool("m", false, "")
- listU = CmdList.Flag.Bool("u", false, "")
- listTest = CmdList.Flag.Bool("test", false, "")
- listVersions = CmdList.Flag.Bool("versions", false, "")
+ listCompiled = CmdList.Flag.Bool("compiled", false, "")
+ listDeps = CmdList.Flag.Bool("deps", false, "")
+ listE = CmdList.Flag.Bool("e", false, "")
+ listExport = CmdList.Flag.Bool("export", false, "")
+ listFmt = CmdList.Flag.String("f", "", "")
+ listFind = CmdList.Flag.Bool("find", false, "")
+ listJson = CmdList.Flag.Bool("json", false, "")
+ listM = CmdList.Flag.Bool("m", false, "")
+ listRetracted = CmdList.Flag.Bool("retracted", false, "")
+ listTest = CmdList.Flag.Bool("test", false, "")
+ listU = CmdList.Flag.Bool("u", false, "")
+ listVersions = CmdList.Flag.Bool("versions", false, "")
)
var nl = []byte{'\n'}
@@ -367,6 +380,16 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
}
+ modload.Init()
+ if *listRetracted {
+ if cfg.BuildMod == "vendor" {
+ base.Fatalf("go list -retracted cannot be used when vendoring is enabled")
+ }
+ if !modload.Enabled() {
+ base.Fatalf("go list -retracted can only be used in module-aware mode")
+ }
+ }
+
if *listM {
// Module mode.
if *listCompiled {
@@ -414,9 +437,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
}
- modload.LoadBuildList(ctx)
-
- mods := modload.ListModules(ctx, args, *listU, *listVersions)
+ mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted)
if !*listE {
for _, m := range mods {
if m.Error != nil {
@@ -522,7 +543,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?
@@ -557,7 +578,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.
@@ -607,6 +628,55 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
}
+ // TODO(golang.org/issue/40676): This mechanism could be extended to support
+ // -u without -m.
+ if *listRetracted {
+ // Load retractions for modules that provide packages that will be printed.
+ // TODO(golang.org/issue/40775): Packages from the same module refer to
+ // distinct ModulePublic instance. It would be nice if they could all point
+ // to the same instance. This would require additional global state in
+ // modload.loaded, so that should be refactored first. For now, we update
+ // all instances.
+ modToArg := make(map[*modinfo.ModulePublic]string)
+ argToMods := make(map[string][]*modinfo.ModulePublic)
+ var args []string
+ addModule := func(mod *modinfo.ModulePublic) {
+ if mod.Version == "" {
+ return
+ }
+ arg := fmt.Sprintf("%s@%s", mod.Path, mod.Version)
+ if argToMods[arg] == nil {
+ args = append(args, arg)
+ }
+ argToMods[arg] = append(argToMods[arg], mod)
+ modToArg[mod] = arg
+ }
+ for _, p := range pkgs {
+ if p.Module == nil {
+ continue
+ }
+ addModule(p.Module)
+ if p.Module.Replace != nil {
+ addModule(p.Module.Replace)
+ }
+ }
+
+ if len(args) > 0 {
+ listU := false
+ listVersions := false
+ rmods := modload.ListModules(ctx, args, listU, listVersions, *listRetracted)
+ for i, arg := range args {
+ rmod := rmods[i]
+ for _, mod := range argToMods[arg] {
+ mod.Retracted = rmod.Retracted
+ if rmod.Error != nil && mod.Error == nil {
+ mod.Error = rmod.Error
+ }
+ }
+ }
+ }
+ }
+
// Record non-identity import mappings in p.ImportMap.
for _, p := range pkgs {
for i, srcPath := range p.Internal.RawImports {
@@ -625,6 +695,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/test.go b/src/cmd/go/internal/load/test.go
index a0e275095b..e0f13323df 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -191,6 +191,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
GoFiles: p.XTestGoFiles,
Imports: p.XTestImports,
ForTest: p.ImportPath,
+ Module: p.Module,
Error: pxtestErr,
},
Internal: PackageInternal{
@@ -222,6 +223,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
ImportPath: p.ImportPath + ".test",
Root: p.Root,
Imports: str.StringList(TestMainDeps),
+ Module: p.Module,
},
Internal: PackageInternal{
Build: &build.Package{Name: "main"},
diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go
index d4c161fca1..6227fd9f33 100644
--- a/src/cmd/go/internal/modcmd/download.go
+++ b/src/cmd/go/internal/modcmd/download.go
@@ -12,9 +12,8 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
- "cmd/go/internal/modload"
"cmd/go/internal/modfetch"
- "cmd/go/internal/work"
+ "cmd/go/internal/modload"
"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 {
@@ -136,9 +135,10 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
var mods []*moduleJSON
listU := false
listVersions := false
+ listRetractions := false
type token struct{}
sem := make(chan token, runtime.GOMAXPROCS(0))
- for _, info := range modload.ListModules(ctx, args, listU, listVersions) {
+ for _, info := range modload.ListModules(ctx, args, listU, listVersions, listRetractions) {
if info.Replace != nil {
info = info.Replace
}
@@ -187,4 +187,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
}
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 a81c25270f..03a774b824 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"
@@ -68,9 +67,14 @@ The -dropreplace=old[@v] flag drops a replacement of the given
module path and version pair. If the @v is omitted, a replacement without
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
+-retract=version is a no-op if that retraction already exists.
+
The -require, -droprequire, -exclude, -dropexclude, -replace,
-and -dropreplace editing flags may be repeated, and the changes
-are applied in the order given.
+-dropreplace, -retract, and -dropretract editing flags may be repeated,
+and the changes are applied in the order given.
The -go=version flag sets the expected Go language version.
@@ -104,6 +108,15 @@ writing it back to go.mod. The JSON output corresponds to these Go types:
New Module
}
+ type Retract struct {
+ Low string
+ High string
+ Rationale string
+ }
+
+Retract entries representing a single version (not an interval) will have
+the "Low" and "High" fields set to the same value.
+
Note that this only describes the go.mod file itself, not other modules
referred to indirectly. For the full set of modules available to a build,
use 'go list -m -json all'.
@@ -137,8 +150,10 @@ func init() {
cmdEdit.Flag.Var(flagFunc(flagDropReplace), "dropreplace", "")
cmdEdit.Flag.Var(flagFunc(flagReplace), "replace", "")
cmdEdit.Flag.Var(flagFunc(flagDropExclude), "dropexclude", "")
+ cmdEdit.Flag.Var(flagFunc(flagRetract), "retract", "")
+ cmdEdit.Flag.Var(flagFunc(flagDropRetract), "dropretract", "")
- work.AddModCommonFlags(cmdEdit)
+ base.AddModCommonFlags(&cmdEdit.Flag)
base.AddBuildFlagsNX(&cmdEdit.Flag)
}
@@ -252,12 +267,7 @@ func parsePathVersion(flag, arg string) (path, version string) {
base.Fatalf("go mod: -%s=%s: invalid path: %v", flag, arg, err)
}
- // We don't call modfile.CheckPathVersion, because that insists
- // on versions being in semver form, but here we want to allow
- // versions like "master" or "1234abcdef", which the go command will resolve
- // the next time it runs (or during -fix).
- // Even so, we need to make sure the version is a valid token.
- if modfile.MustQuote(version) {
+ if !allowedVersionArg(version) {
base.Fatalf("go mod: -%s=%s: invalid version %q", flag, arg, version)
}
@@ -289,12 +299,48 @@ func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version
return path, version, fmt.Errorf("invalid %s path: %v", adj, err)
}
}
- if path != arg && modfile.MustQuote(version) {
+ if path != arg && !allowedVersionArg(version) {
return path, version, fmt.Errorf("invalid %s version: %q", adj, version)
}
return path, version, nil
}
+// parseVersionInterval parses a single version like "v1.2.3" or a closed
+// interval like "[v1.2.3,v1.4.5]". Note that a single version has the same
+// representation as an interval with equal upper and lower bounds: both
+// Low and High are set.
+func parseVersionInterval(arg string) (modfile.VersionInterval, error) {
+ if !strings.HasPrefix(arg, "[") {
+ if !allowedVersionArg(arg) {
+ return modfile.VersionInterval{}, fmt.Errorf("invalid version: %q", arg)
+ }
+ return modfile.VersionInterval{Low: arg, High: arg}, nil
+ }
+ if !strings.HasSuffix(arg, "]") {
+ return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
+ }
+ s := arg[1 : len(arg)-1]
+ i := strings.Index(s, ",")
+ if i < 0 {
+ return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
+ }
+ low := strings.TrimSpace(s[:i])
+ high := strings.TrimSpace(s[i+1:])
+ if !allowedVersionArg(low) || !allowedVersionArg(high) {
+ return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
+ }
+ return modfile.VersionInterval{Low: low, High: high}, nil
+}
+
+// allowedVersionArg returns whether a token may be used as a version in go.mod.
+// We don't call modfile.CheckPathVersion, because that insists on versions
+// being in semver form, but here we want to allow versions like "master" or
+// "1234abcdef", which the go command will resolve the next time it runs (or
+// during -fix). Even so, we need to make sure the version is a valid token.
+func allowedVersionArg(arg string) bool {
+ return !modfile.MustQuote(arg)
+}
+
// flagRequire implements the -require flag.
func flagRequire(arg string) {
path, version := parsePathVersion("require", arg)
@@ -377,6 +423,32 @@ func flagDropReplace(arg string) {
})
}
+// flagRetract implements the -retract flag.
+func flagRetract(arg string) {
+ vi, err := parseVersionInterval(arg)
+ if err != nil {
+ base.Fatalf("go mod: -retract=%s: %v", arg, err)
+ }
+ edits = append(edits, func(f *modfile.File) {
+ if err := f.AddRetract(vi, ""); err != nil {
+ base.Fatalf("go mod: -retract=%s: %v", arg, err)
+ }
+ })
+}
+
+// flagDropRetract implements the -dropretract flag.
+func flagDropRetract(arg string) {
+ vi, err := parseVersionInterval(arg)
+ if err != nil {
+ base.Fatalf("go mod: -dropretract=%s: %v", arg, err)
+ }
+ edits = append(edits, func(f *modfile.File) {
+ if err := f.DropRetract(vi); err != nil {
+ base.Fatalf("go mod: -dropretract=%s: %v", arg, err)
+ }
+ })
+}
+
// fileJSON is the -json output data structure.
type fileJSON struct {
Module module.Version
@@ -384,6 +456,7 @@ type fileJSON struct {
Require []requireJSON
Exclude []module.Version
Replace []replaceJSON
+ Retract []retractJSON
}
type requireJSON struct {
@@ -397,6 +470,12 @@ type replaceJSON struct {
New module.Version
}
+type retractJSON struct {
+ Low string `json:",omitempty"`
+ High string `json:",omitempty"`
+ Rationale string `json:",omitempty"`
+}
+
// editPrintJSON prints the -json output.
func editPrintJSON(modFile *modfile.File) {
var f fileJSON
@@ -415,6 +494,9 @@ func editPrintJSON(modFile *modfile.File) {
for _, r := range modFile.Replace {
f.Replace = append(f.Replace, replaceJSON{r.Old, r.New})
}
+ for _, r := range modFile.Retract {
+ f.Retract = append(f.Retract, retractJSON{r.Low, r.High, r.Rationale})
+ }
data, err := json.MarshalIndent(&f, "", "\t")
if err != nil {
base.Fatalf("go: internal error: %v", err)
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 6da12b9cab..a149b65605 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -15,7 +15,6 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/modload"
- "cmd/go/internal/work"
"golang.org/x/mod/module"
)
@@ -33,7 +32,7 @@ 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) {
@@ -48,7 +47,7 @@ func runGraph(ctx context.Context, cmd *base.Command, args []string) {
base.Fatalf("go: cannot find main module; see 'go help modules'")
}
}
- modload.LoadBuildList(ctx)
+ 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..21b235653e 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -9,7 +9,6 @@ package modcmd
import (
"cmd/go/internal/base"
"cmd/go/internal/modload"
- "cmd/go/internal/work"
"context"
"os"
"strings"
@@ -30,7 +29,7 @@ To override this guess, supply the module path as an argument.
}
func init() {
- work.AddModCommonFlags(cmdInit)
+ base.AddModCommonFlags(&cmdInit.Flag)
}
func runInit(ctx context.Context, cmd *base.Command, args []string) {
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
index c7c53d7c0c..30df674ef6 100644
--- a/src/cmd/go/internal/modcmd/tidy.go
+++ b/src/cmd/go/internal/modcmd/tidy.go
@@ -10,7 +10,6 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/modload"
- "cmd/go/internal/work"
"context"
)
@@ -32,7 +31,7 @@ to standard error.
func init() {
cmdTidy.Run = runTidy // break init cycle
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
- work.AddModCommonFlags(cmdTidy)
+ base.AddModCommonFlags(&cmdTidy.Flag)
}
func runTidy(ctx context.Context, cmd *base.Command, args []string) {
@@ -40,6 +39,18 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
base.Fatalf("go mod tidy: no arguments allowed")
}
+ // 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.LoadTests = true
+
modload.LoadALL(ctx)
modload.TidyBuildList()
modload.TrimGoSum()
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index e5353b5c7f..91d2509452 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -19,7 +19,6 @@ import (
"cmd/go/internal/cfg"
"cmd/go/internal/imports"
"cmd/go/internal/modload"
- "cmd/go/internal/work"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
@@ -41,7 +40,7 @@ modules and packages to standard error.
func init() {
cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "")
- work.AddModCommonFlags(cmdVendor)
+ base.AddModCommonFlags(&cmdVendor.Flag)
}
func runVendor(ctx context.Context, cmd *base.Command, args []string) {
@@ -77,7 +76,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
}
var buf bytes.Buffer
- for _, m := range modload.BuildList()[1:] {
+ for _, m := range modload.LoadedModules()[1:] {
if pkgs := modpkgs[m]; len(pkgs) > 0 || isExplicit[m] {
line := moduleLine(m, modload.Replacement(m))
buf.WriteString(line)
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 73ab714d10..7700588bde 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -17,7 +17,6 @@ import (
"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 +37,7 @@ non-zero status.
}
func init() {
- work.AddModCommonFlags(cmdVerify)
+ base.AddModCommonFlags(&cmdVerify.Flag)
}
func runVerify(ctx context.Context, cmd *base.Command, args []string) {
@@ -60,7 +59,7 @@ func runVerify(ctx context.Context, cmd *base.Command, args []string) {
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 {
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index da33fff89e..8454fdfec6 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -11,7 +11,6 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/modload"
- "cmd/go/internal/work"
"golang.org/x/mod/module"
)
@@ -58,23 +57,26 @@ 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
+ } else {
+ modload.LoadTests = true
}
if *whyM {
listU := false
listVersions := false
+ listRetractions := false
for _, arg := range args {
if strings.Contains(arg, "@") {
base.Fatalf("go mod why: module query not allowed")
}
}
- mods := modload.ListModules(ctx, args, listU, listVersions)
+ mods := modload.ListModules(ctx, args, listU, listVersions, listRetractions)
byModule := make(map[module.Version][]string)
for _, path := range loadALL(ctx) {
m := modload.PackageModule(path)
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index e29eb0a942..01d8f007ac 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -503,6 +503,9 @@ func checkGoMod(path, version string, data []byte) error {
}
// checkModSum checks that the recorded checksum for mod is h.
+//
+// mod.Version may have the additional suffix "/go.mod" to request the checksum
+// for the module's go.mod file only.
func checkModSum(mod module.Version, h string) error {
// We lock goSum when manipulating it,
// but we arrange to release the lock when calling checkSumDB,
@@ -579,9 +582,16 @@ func addModSumLocked(mod module.Version, h string) {
// checkSumDB checks the mod, h pair against the Go checksum database.
// It calls base.Fatalf if the hash is to be rejected.
func checkSumDB(mod module.Version, h string) error {
+ modWithoutSuffix := mod
+ noun := "module"
+ if strings.HasSuffix(mod.Version, "/go.mod") {
+ noun = "go.mod"
+ modWithoutSuffix.Version = strings.TrimSuffix(mod.Version, "/go.mod")
+ }
+
db, lines, err := lookupSumDB(mod)
if err != nil {
- return module.VersionError(mod, fmt.Errorf("verifying module: %v", err))
+ return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: %v", noun, err))
}
have := mod.Path + " " + mod.Version + " " + h
@@ -591,7 +601,7 @@ func checkSumDB(mod module.Version, h string) error {
return nil
}
if strings.HasPrefix(line, prefix) {
- return module.VersionError(mod, fmt.Errorf("verifying module: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, h, db, line[len(prefix)-len("h1:"):]))
+ return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):]))
}
}
return nil
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/repo.go b/src/cmd/go/internal/modfetch/repo.go
index 34f805d58a..eed4dd4258 100644
--- a/src/cmd/go/internal/modfetch/repo.go
+++ b/src/cmd/go/internal/modfetch/repo.go
@@ -13,9 +13,9 @@ import (
"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"
@@ -261,13 +261,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 +279,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 +306,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
}
diff --git a/src/cmd/go/internal/modfetch/sumdb.go b/src/cmd/go/internal/modfetch/sumdb.go
index 783c4a433b..47a2571531 100644
--- a/src/cmd/go/internal/modfetch/sumdb.go
+++ b/src/cmd/go/internal/modfetch/sumdb.go
@@ -22,7 +22,6 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
- "cmd/go/internal/get"
"cmd/go/internal/lockedfile"
"cmd/go/internal/web"
@@ -33,7 +32,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,
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index ee9757912b..829cfe055a 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -17,7 +17,7 @@ import (
"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"
@@ -181,7 +181,7 @@ 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
)
@@ -206,7 +206,7 @@ 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", "")
}
@@ -278,7 +278,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
}
modload.LoadTests = *getT
- buildList := modload.LoadBuildList(ctx)
+ buildList := modload.LoadAllModules(ctx)
buildList = buildList[:len(buildList):len(buildList)] // copy on append
versionByPath := make(map[string]string)
for _, m := range buildList {
@@ -290,7 +290,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// 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()
@@ -599,7 +599,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
base.ExitIfErrors()
// Stop if no changes have been made to the build list.
- buildList = modload.BuildList()
+ buildList = modload.LoadedModules()
eq := len(buildList) == len(prevBuildList)
for i := 0; eq && i < len(buildList); i++ {
eq = buildList[i] == prevBuildList[i]
@@ -617,7 +617,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// Handle downgrades.
var down []module.Version
- for _, m := range modload.BuildList() {
+ for _, m := range modload.LoadedModules() {
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})
@@ -628,6 +628,10 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
if err != nil {
base.Fatalf("go: %v", err)
}
+
+ // TODO(bcmills) What should happen here under lazy loading?
+ // Downgrading may intentionally violate the lazy-loading invariants.
+
modload.SetBuildList(buildList)
modload.ReloadBuildList() // note: does not update go.mod
base.ExitIfErrors()
@@ -637,7 +641,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
var lostUpgrades []*query
if len(down) > 0 {
versionByPath = make(map[string]string)
- for _, m := range modload.BuildList() {
+ for _, m := range modload.LoadedModules() {
versionByPath[m.Path] = m.Version
}
for _, q := range byPath {
@@ -702,6 +706,15 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// Everything succeeded. Update go.mod.
modload.AllowWriteGoMod()
modload.WriteGoMod()
+ modload.DisallowWriteGoMod()
+
+ // 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)
// If -d was specified, we're done after the module work.
// We've already downloaded modules by loading packages above.
@@ -804,6 +817,14 @@ func getQuery(ctx context.Context, path, vers string, prevM module.Version, forc
base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set")
}
+ // 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
+ }
+
// If the query must be a module path, try only that module path.
if forceModulePath {
if path == modload.Target.Path {
@@ -812,7 +833,7 @@ func getQuery(ctx context.Context, path, vers string, prevM module.Version, forc
}
}
- info, err := modload.Query(ctx, path, vers, prevM.Version, modload.Allowed)
+ 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)
@@ -838,7 +859,7 @@ func getQuery(ctx context.Context, path, vers string, prevM module.Version, forc
// 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, modload.Allowed)
+ 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.
@@ -864,190 +885,41 @@ func getQuery(ctx context.Context, path, vers string, prevM module.Version, forc
return m, nil
}
-// 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
-
- // 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
-
- // 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
-}
-
-// 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,
- }
- 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)
- }
- }
- for pkg := range pkgs {
- add(pkg)
+// 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.LoadedModules()
+ args := make([]string, 0, len(buildList))
+ for _, m := range buildList {
+ if m.Version == "" {
+ // main module or dummy target module
+ continue
}
- 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 _, imp := range testImports {
- add(imp)
+ 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>"
}
+ rationale := modload.ShortRetractionRationale(mod.Retracted[0])
+ logOncef("go: warning: %s@%s is retracted: %s", mod.Path, mod.Version, rationale)
}
}
- 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
- }
- if m != modload.Target {
- return rs, nil
- }
-
- 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
- }
- }
- 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)
- }
- }
- return rs, nil
-}
-
-// Upgrade returns the desired upgrade for m.
-//
-// If m was requested at a specific version on the command line, then
-// Upgrade returns that version.
-//
-// 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
- }
-
- if !u.upgrade[m.Path] {
- // Not involved in upgrade. Leave alone.
- return m, nil
- }
-
- // 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.Allowed)
- 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
- }
-
- // 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)
- }
- return m, nil
- }
-
- if info.Version != m.Version {
- logOncef("go: %s %s => %s", m.Path, getU, info.Version)
- }
- 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})
-}
-
-var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""}
-
-type lostUpgradeReqs struct {
- mvs.Reqs
- lost module.Version
-}
-
-func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) {
- if mod == lostUpgradeRoot {
- return []module.Version{r.lost}, nil
+ if modload.HasModRoot() && retractPath != "" {
+ logOncef("go: run 'go get %s@latest' to switch to the latest unretracted version", retractPath)
}
- return r.Reqs.Required(mod)
}
var loggedLines sync.Map
diff --git a/src/cmd/go/internal/modget/mvs.go b/src/cmd/go/internal/modget/mvs.go
new file mode 100644
index 0000000000..19fffd2947
--- /dev/null
+++ b/src/cmd/go/internal/modget/mvs.go
@@ -0,0 +1,202 @@
+// 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 (
+ "context"
+ "errors"
+
+ "cmd/go/internal/base"
+ "cmd/go/internal/modload"
+ "cmd/go/internal/mvs"
+
+ "golang.org/x/mod/module"
+)
+
+// 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
+
+ // 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
+
+ // 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
+}
+
+// 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,
+ }
+ 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)
+ }
+ }
+ for pkg := range pkgs {
+ add(pkg)
+ }
+ 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 _, imp := range testImports {
+ add(imp)
+ }
+ }
+ }
+ 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
+ }
+ if m != modload.Target {
+ return rs, nil
+ }
+
+ 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
+ }
+ }
+ 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)
+ }
+ }
+ return rs, nil
+}
+
+// Upgrade returns the desired upgrade for m.
+//
+// If m was requested at a specific version on the command line, then
+// Upgrade returns that version.
+//
+// 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
+ }
+
+ if !u.upgrade[m.Path] {
+ // Not involved in upgrade. Leave alone.
+ return m, nil
+ }
+
+ // 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
+ }
+
+ // 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)
+ }
+ return m, nil
+ }
+
+ if info.Version != m.Version {
+ logOncef("go: %s %s => %s", m.Path, getU, info.Version)
+ }
+ 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})
+}
+
+var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""}
+
+type lostUpgradeReqs struct {
+ mvs.Reqs
+ lost module.Version
+}
+
+func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) {
+ if mod == lostUpgradeRoot {
+ return []module.Version{r.lost}, nil
+ }
+ return r.Reqs.Required(mod)
+}
diff --git a/src/cmd/go/internal/modinfo/info.go b/src/cmd/go/internal/modinfo/info.go
index 07248d1a61..897be56397 100644
--- a/src/cmd/go/internal/modinfo/info.go
+++ b/src/cmd/go/internal/modinfo/info.go
@@ -21,6 +21,7 @@ type ModulePublic struct {
Dir string `json:",omitempty"` // directory holding local copy of files, if any
GoMod string `json:",omitempty"` // path to go.mod file describing module, if any
GoVersion string `json:",omitempty"` // go version used in module
+ Retracted []string `json:",omitempty"` // retraction information, if any (with -retracted or -u)
Error *ModuleError `json:",omitempty"` // error loading module
}
@@ -30,18 +31,26 @@ type ModuleError struct {
func (m *ModulePublic) String() string {
s := m.Path
+ versionString := func(mm *ModulePublic) string {
+ v := mm.Version
+ if len(mm.Retracted) == 0 {
+ return v
+ }
+ return v + " (retracted)"
+ }
+
if m.Version != "" {
- s += " " + m.Version
+ s += " " + versionString(m)
if m.Update != nil {
- s += " [" + m.Update.Version + "]"
+ s += " [" + versionString(m.Update) + "]"
}
}
if m.Replace != nil {
s += " => " + m.Replace.Path
if m.Replace.Version != "" {
- s += " " + m.Replace.Version
+ s += " " + versionString(m.Replace)
if m.Replace.Update != nil {
- s += " [" + m.Replace.Update.Version + "]"
+ s += " [" + versionString(m.Replace.Update) + "]"
}
}
}
diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go
index a101681a1f..9ca6230500 100644
--- a/src/cmd/go/internal/modload/build.go
+++ b/src/cmd/go/internal/modload/build.go
@@ -8,6 +8,7 @@ import (
"bytes"
"context"
"encoding/hex"
+ "errors"
"fmt"
"internal/goroot"
"os"
@@ -58,7 +59,9 @@ func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic {
if !ok {
return nil
}
- return moduleInfo(context.TODO(), m, true)
+ fromBuildList := true
+ listRetracted := false
+ return moduleInfo(context.TODO(), m, fromBuildList, listRetracted)
}
func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
@@ -66,13 +69,17 @@ func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic {
return nil
}
+ listRetracted := false
if i := strings.Index(path, "@"); i >= 0 {
- return moduleInfo(ctx, module.Version{Path: path[:i], Version: path[i+1:]}, false)
+ m := module.Version{Path: path[:i], Version: path[i+1:]}
+ fromBuildList := false
+ return moduleInfo(ctx, m, fromBuildList, listRetracted)
}
- for _, m := range BuildList() {
+ for _, m := range LoadedModules() {
if m.Path == path {
- return moduleInfo(ctx, m, true)
+ fromBuildList := true
+ return moduleInfo(ctx, m, fromBuildList, listRetracted)
}
}
@@ -90,7 +97,7 @@ func addUpdate(ctx context.Context, m *modinfo.ModulePublic) {
return
}
- if info, err := Query(ctx, m.Path, "upgrade", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
+ if info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
m.Update = &modinfo.ModulePublic{
Path: m.Path,
Version: info.Version,
@@ -100,11 +107,37 @@ func addUpdate(ctx context.Context, m *modinfo.ModulePublic) {
}
// addVersions fills in m.Versions with the list of known versions.
-func addVersions(m *modinfo.ModulePublic) {
- m.Versions, _ = versions(m.Path)
+// Excluded versions will be omitted. If listRetracted is false, retracted
+// versions will also be omitted.
+func addVersions(ctx context.Context, m *modinfo.ModulePublic, listRetracted bool) {
+ allowed := CheckAllowed
+ if listRetracted {
+ allowed = CheckExclusions
+ }
+ m.Versions, _ = versions(ctx, m.Path, allowed)
}
-func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modinfo.ModulePublic {
+// addRetraction fills in m.Retracted if the module was retracted by its author.
+// m.Error is set if there's an error loading retraction information.
+func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
+ if m.Version == "" {
+ return
+ }
+
+ err := checkRetractions(ctx, module.Version{Path: m.Path, Version: m.Version})
+ var rerr *retractedError
+ if errors.As(err, &rerr) {
+ if len(rerr.rationale) == 0 {
+ m.Retracted = []string{"retracted by module author"}
+ } else {
+ m.Retracted = rerr.rationale
+ }
+ } else if err != nil && m.Error == nil {
+ m.Error = &modinfo.ModuleError{Err: err.Error()}
+ }
+}
+
+func moduleInfo(ctx context.Context, m module.Version, fromBuildList, listRetracted bool) *modinfo.ModulePublic {
if m == Target {
info := &modinfo.ModulePublic{
Path: m.Path,
@@ -126,12 +159,14 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modi
Version: m.Version,
Indirect: fromBuildList && loaded != nil && !loaded.direct[m.Path],
}
- if loaded != nil {
- info.GoVersion = loaded.goVersion[m.Path]
+ if v, ok := rawGoVersion.Load(m); ok {
+ info.GoVersion = v.(string)
}
// completeFromModCache fills in the extra fields in m using the module cache.
completeFromModCache := func(m *modinfo.ModulePublic) {
+ mod := module.Version{Path: m.Path, Version: m.Version}
+
if m.Version != "" {
if q, err := Query(ctx, m.Path, m.Version, "", nil); err != nil {
m.Error = &modinfo.ModuleError{Err: err.Error()}
@@ -140,7 +175,6 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modi
m.Time = &q.Time
}
- mod := module.Version{Path: m.Path, Version: m.Version}
gomod, err := modfetch.CachePath(mod, "mod")
if err == nil {
if info, err := os.Stat(gomod); err == nil && info.Mode().IsRegular() {
@@ -151,10 +185,22 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modi
if err == nil {
m.Dir = dir
}
+
+ if listRetracted {
+ addRetraction(ctx, m)
+ }
+ }
+
+ if m.GoVersion == "" {
+ if summary, err := rawGoModSummary(mod); err == nil && summary.goVersionV != "" {
+ m.GoVersion = summary.goVersionV[1:]
+ }
}
}
if !fromBuildList {
+ // If this was an explicitly-versioned argument to 'go mod download' or
+ // 'go list -m', report the actual requested version, not its replacement.
completeFromModCache(info) // Will set m.Error in vendor mode.
return info
}
@@ -178,9 +224,11 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modi
// worth the cost, and we're going to overwrite the GoMod and Dir from the
// replacement anyway. See https://golang.org/issue/27859.
info.Replace = &modinfo.ModulePublic{
- Path: r.Path,
- Version: r.Version,
- GoVersion: info.GoVersion,
+ Path: r.Path,
+ Version: r.Version,
+ }
+ if v, ok := rawGoVersion.Load(m); ok {
+ info.Replace.GoVersion = v.(string)
}
if r.Version == "" {
if filepath.IsAbs(r.Path) {
@@ -194,7 +242,9 @@ func moduleInfo(ctx context.Context, m module.Version, fromBuildList bool) *modi
completeFromModCache(info.Replace)
info.Dir = info.Replace.Dir
info.GoMod = info.Replace.GoMod
+ info.Retracted = info.Replace.Retracted
}
+ info.GoVersion = info.Replace.GoVersion
return info
}
diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
new file mode 100644
index 0000000000..581a1b944a
--- /dev/null
+++ b/src/cmd/go/internal/modload/buildlist.go
@@ -0,0 +1,122 @@
+// 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"
+
+ "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
+
+// 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 ImportPaths:
+// LoadAllModules need only be called if ImportPaths is not,
+// typically in commands that care about modules but no particular package.
+//
+// The caller must not modify the returned list.
+func LoadAllModules(ctx context.Context) []module.Version {
+ InitMod(ctx)
+ ReloadBuildList()
+ WriteGoMod()
+ return buildList
+}
+
+// LoadedModules returns the list of module requirements loaded or set by a
+// previous call (typically LoadAllModules or ImportPaths), starting with the
+// Target module and in a deterministic (stable) order.
+//
+// The caller must not modify the returned list.
+func LoadedModules() []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...)
+}
+
+// ReloadBuildList resets the state of loaded packages, then loads and returns
+// the build list set in SetBuildList.
+func ReloadBuildList() []module.Version {
+ loaded = loadFromRoots(loaderParams{
+ tags: imports.Tags(),
+ listRoots: func() []string { return nil },
+ allClosesOverTests: index.allPatternClosesOverTests(), // but doesn't matter because the root list is empty.
+ })
+ return buildList
+}
+
+// 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...)
+}
+
+// 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 d80206b194..37f23d967f 100644
--- a/src/cmd/go/internal/modload/help.go
+++ b/src/cmd/go/internal/modload/help.go
@@ -432,15 +432,17 @@ verb followed by arguments. For example:
require new/thing/v2 v2.3.4
exclude old/thing v1.2.3
replace bad/thing v1.4.5 => good/thing v1.4.5
+ retract v1.5.6
The verbs are
module, to define the module path;
go, to set the expected language version;
require, to require a particular module at a given version or later;
- exclude, to exclude a particular module version from use; and
- replace, to replace a module version with a different module version.
+ exclude, to exclude a particular module version from use;
+ replace, to replace a module version with a different module version; and
+ retract, to indicate a previously released version should not be used.
Exclude and replace apply only in the main module's go.mod and are ignored
-in dependencies. See https://research.swtch.com/vgo-mvs for details.
+in dependencies. See https://golang.org/ref/mod for details.
The leading verb can be factored out of adjacent lines to create a block,
like in Go imports:
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index 5c51a79124..10b1e7f4b8 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -26,6 +26,8 @@ import (
"golang.org/x/mod/semver"
)
+var errImportMissing = errors.New("import missing")
+
type ImportMissingError struct {
Path string
Module module.Version
@@ -48,6 +50,11 @@ func (e *ImportMissingError) Error() string {
}
return "cannot find module providing package " + e.Path
}
+
+ 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)
}
@@ -100,18 +107,39 @@ func (e *AmbiguousImportError) Error() string {
var _ load.ImportPathError = &AmbiguousImportError{}
-// 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".
+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
+}
+
+var _ load.ImportPathError = &invalidImportError{}
+
+// 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.
+//
+// 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 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 returns errImportMissing as the error.
+func importFromBuildList(ctx context.Context, path string) (m module.Version, dir string, err error) {
if strings.Contains(path, "@") {
return module.Version{}, "", fmt.Errorf("import path should not have @version")
}
@@ -190,29 +218,25 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err
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}
- }
+ return module.Version{}, "", errImportMissing
+}
+
+// queryImport attempts to locate a module that can be added to the current
+// build list to provide the package with the given import path.
+func queryImport(ctx context.Context, path string) (module.Version, error) {
+ pathIsStd := search.IsStandardImportPath(path)
+
if modRoot == "" && !allowMissingModuleImports {
- return module.Version{}, "", &ImportMissingError{
+ return module.Version{}, &ImportMissingError{
Path: path,
QueryErr: errors.New("working directory is not part of a module"),
}
}
// Not on build list.
- // To avoid spurious remote fetches, next try the latest replacement for each module.
- // (golang.org/issue/26241)
+ // To avoid spurious remote fetches, next try the latest replacement for each
+ // module (golang.org/issue/26241). This should give a useful message
+ // in -mod=readonly, and it will allow us to add a requirement with -mod=mod.
if modFile != nil {
latest := map[string]string{} // path -> version
for _, r := range modFile.Replace {
@@ -226,7 +250,7 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err
}
}
- mods = make([]module.Version, 0, len(latest))
+ 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
@@ -252,19 +276,19 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err
root, isLocal, err := fetch(ctx, m)
if err != nil {
// Report fetch error as above.
- return module.Version{}, "", err
+ 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}
+ 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,
// 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,6 +297,11 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err
}
}
+ // 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}
+ }
+
if pathIsStd {
// 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
@@ -281,25 +310,39 @@ func Import(ctx context.Context, path string) (m module.Version, dir string, err
// QueryPackage cannot possibly find a module containing this package.
//
// Instead of trying QueryPackage, report an ImportMissingError immediately.
- return module.Version{}, "", &ImportMissingError{Path: path}
+ return module.Version{}, &ImportMissingError{Path: path}
+ }
+
+ if cfg.BuildMod == "readonly" {
+ 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", Allowed)
+ candidates, err := QueryPackage(ctx, path, "latest", CheckAllowed)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
// Return "cannot find module providing package […]" instead of whatever
// low-level error QueryPackage produced.
- return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: err}
+ 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,
@@ -310,13 +353,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,
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 93027c44c4..1f50dcb11c 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -368,13 +368,9 @@ func InitMod(ctx context.Context) {
modFile = f
index = indexModFile(data, f, fixed)
- if len(f.Syntax.Stmt) == 0 || f.Module == nil {
- // Empty mod file. Must add module path.
- path, err := findModulePath(modRoot)
- if err != nil {
- base.Fatalf("go: %v", err)
- }
- f.AddModuleStmt(path)
+ if f.Module == nil {
+ // No module declaration. Must add module path.
+ 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 {
@@ -383,14 +379,61 @@ func InitMod(ctx context.Context) {
legacyModInit()
}
- modFileToBuildList()
+ if err := checkModulePathLax(f.Module.Mod.Path); err != nil {
+ base.Fatalf("go: %v", err)
+ }
+
setDefaultBuildMod()
+ modFileToBuildList()
if cfg.BuildMod == "vendor" {
readVendorList()
checkVendorConsistency()
}
}
+// 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
+// requirements in the future, but strong enough to help users avoid significant
+// problems.
+func checkModulePathLax(p string) error {
+ // TODO(matloob): Replace calls of this function in this CL with calls
+ // to module.CheckImportPath once it's been laxened, if it becomes laxened.
+ // See golang.org/issue/29101 for a discussion about whether to make CheckImportPath
+ // more lax or more strict.
+
+ errorf := func(format string, args ...interface{}) error {
+ return fmt.Errorf("invalid module path %q: %s", p, fmt.Sprintf(format, args...))
+ }
+
+ // Disallow shell characters " ' * < > ? ` | to avoid triggering bugs
+ // with file systems and subcommands. Disallow file path separators : and \
+ // because path separators other than / will confuse the module cache.
+ // See fileNameOK in golang.org/x/mod/module/module.go.
+ shellChars := "`" + `\"'*<>?|`
+ fsChars := `\:`
+ if i := strings.IndexAny(p, shellChars); i >= 0 {
+ return errorf("contains disallowed shell character %q", p[i])
+ }
+ if i := strings.IndexAny(p, fsChars); i >= 0 {
+ return errorf("contains disallowed path separator character %q", p[i])
+ }
+
+ // Ensure path.IsAbs and build.IsLocalImport are false, and that the path is
+ // invariant under path.Clean, also to avoid confusing the module cache.
+ if path.IsAbs(p) {
+ return errorf("is an absolute path")
+ }
+ if build.IsLocalImport(p) {
+ return errorf("is a local import path")
+ }
+ if path.Clean(p) != p {
+ return errorf("is not clean")
+ }
+
+ return nil
+}
+
// fixVersion returns a modfile.VersionFixer implemented using the Query function.
//
// It resolves commit hashes and branch names to versions,
@@ -459,7 +502,15 @@ func modFileToBuildList() {
list := []module.Version{Target}
for _, r := range modFile.Require {
- list = append(list, r.Mod)
+ if index != nil && index.exclude[r.Mod] {
+ if cfg.BuildMod == "mod" {
+ fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
+ } else {
+ fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
+ }
+ } else {
+ list = append(list, r.Mod)
+ }
}
buildList = list
}
@@ -467,46 +518,49 @@ 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 = "mod"
return
}
if fi, err := os.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
modGo := "unspecified"
- if index.goVersion != "" {
- if semver.Compare("v"+index.goVersion, "v1.14") >= 0 {
+ if index.goVersionV != "" {
+ if semver.Compare(index.goVersionV, "v1.14") >= 0 {
// The Go version is at least 1.14, and a vendor directory exists.
// Set -mod=vendor by default.
cfg.BuildMod = "vendor"
cfg.BuildModReason = "Go version in go.mod is at least 1.14 and vendor directory exists."
return
} else {
- modGo = index.goVersion
+ modGo = index.goVersionV[1:]
}
}
- // 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."
+ return
}
+ cfg.BuildMod = "mod"
}
func legacyModInit() {
@@ -674,16 +728,35 @@ func findModulePath(dir string) (string, error) {
}
// Look for path in GOPATH.
+ var badPathErr error
for _, gpdir := range filepath.SplitList(cfg.BuildContext.GOPATH) {
if gpdir == "" {
continue
}
if rel := search.InDir(dir, filepath.Join(gpdir, "src")); rel != "" && rel != "." {
- return filepath.ToSlash(rel), nil
+ path := filepath.ToSlash(rel)
+ // TODO(matloob): replace this with module.CheckImportPath
+ // once it's been laxened.
+ // Only checkModulePathLax here. There are some unpublishable
+ // module names that are compatible with checkModulePathLax
+ // but they already work in GOPATH so don't break users
+ // trying to do a build with modules. gorelease will alert users
+ // publishing their modules to fix their paths.
+ if err := checkModulePathLax(path); err != nil {
+ badPathErr = err
+ break
+ }
+ return path, nil
}
}
- msg := `cannot determine module path for source directory %s (outside GOPATH, module path must be specified)
+ reason := "outside GOPATH, module path must be specified"
+ if badPathErr != nil {
+ // return a different error message if the module was in GOPATH, but
+ // the module path determined above would be an invalid path.
+ reason = fmt.Sprintf("bad module path inferred from directory in GOPATH: %v", badPathErr)
+ }
+ msg := `cannot determine module path for source directory %s (%s)
Example usage:
'go mod init example.com/m' to initialize a v0 or v1 module
@@ -691,7 +764,7 @@ Example usage:
Run 'go help mod init' for more information.
`
- return "", fmt.Errorf(msg, dir)
+ return "", fmt.Errorf(msg, dir, reason)
}
var (
@@ -787,19 +860,16 @@ func WriteGoMod() {
// prefer to report a dirty go.mod over a dirty go.sum
if cfg.BuildModReason != "" {
base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason)
- } else {
+ } else if cfg.BuildModExplicit {
base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly")
}
}
- // 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.
+ modfetch.WriteGoSum(keepSums(true))
return
}
@@ -810,6 +880,9 @@ 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.
+ modfetch.WriteGoSum(keepSums(true))
}()
// Make a best-effort attempt to acquire the side lock, only to exclude
@@ -850,7 +923,10 @@ func WriteGoMod() {
// 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 {
+//
+// 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 {
// Walk the module graph and keep sums needed by MVS.
modkey := func(m module.Version) module.Version {
return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
@@ -862,9 +938,6 @@ func keepSums() map[module.Version]bool {
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
@@ -894,9 +967,27 @@ func keepSums() map[module.Version]bool {
}
}
+ // 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 != "" {
+ kept = r
+ } else {
+ kept = m
+ }
+ keep[kept] = true
+ keep[module.Version{Path: kept.Path, Version: kept.Version + "/go.mod"}] = true
+ }
+ }
+
return keep
}
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 7bf4e86c8d..3491f941cd 100644
--- a/src/cmd/go/internal/modload/list.go
+++ b/src/cmd/go/internal/modload/list.go
@@ -20,12 +20,12 @@ import (
"golang.org/x/mod/module"
)
-func ListModules(ctx context.Context, args []string, listU, listVersions bool) []*modinfo.ModulePublic {
- mods := listModules(ctx, args, listVersions)
+func ListModules(ctx context.Context, args []string, listU, listVersions, listRetracted bool) []*modinfo.ModulePublic {
+ mods := listModules(ctx, args, listVersions, listRetracted)
type token struct{}
sem := make(chan token, runtime.GOMAXPROCS(0))
- if listU || listVersions {
+ if listU || listVersions || listRetracted {
for _, m := range mods {
add := func(m *modinfo.ModulePublic) {
sem <- token{}
@@ -34,7 +34,10 @@ func ListModules(ctx context.Context, args []string, listU, listVersions bool) [
addUpdate(ctx, m)
}
if listVersions {
- addVersions(m)
+ addVersions(ctx, m, listRetracted)
+ }
+ if listRetracted || listU {
+ addRetraction(ctx, m)
}
<-sem
}()
@@ -54,10 +57,10 @@ func ListModules(ctx context.Context, args []string, listU, listVersions bool) [
return mods
}
-func listModules(ctx context.Context, args []string, listVersions bool) []*modinfo.ModulePublic {
- LoadBuildList(ctx)
+func listModules(ctx context.Context, args []string, listVersions, listRetracted bool) []*modinfo.ModulePublic {
+ LoadAllModules(ctx)
if len(args) == 0 {
- return []*modinfo.ModulePublic{moduleInfo(ctx, buildList[0], true)}
+ return []*modinfo.ModulePublic{moduleInfo(ctx, buildList[0], true, listRetracted)}
}
var mods []*modinfo.ModulePublic
@@ -83,7 +86,13 @@ func listModules(ctx context.Context, args []string, listVersions bool) []*modin
}
}
- info, err := Query(ctx, path, vers, current, nil)
+ allowed := CheckAllowed
+ if IsRevisionQuery(vers) || listRetracted {
+ // Allow excluded and retracted versions if the user asked for a
+ // specific revision or used 'go list -retracted'.
+ allowed = nil
+ }
+ info, err := Query(ctx, path, vers, current, allowed)
if err != nil {
mods = append(mods, &modinfo.ModulePublic{
Path: path,
@@ -92,7 +101,8 @@ func listModules(ctx context.Context, args []string, listVersions bool) []*modin
})
continue
}
- mods = append(mods, moduleInfo(ctx, module.Version{Path: path, Version: info.Version}, false))
+ mod := moduleInfo(ctx, module.Version{Path: path, Version: info.Version}, false, listRetracted)
+ mods = append(mods, mod)
continue
}
@@ -117,7 +127,7 @@ func listModules(ctx context.Context, args []string, listVersions bool) []*modin
matched = true
if !matchedBuildList[i] {
matchedBuildList[i] = true
- mods = append(mods, moduleInfo(ctx, m, true))
+ mods = append(mods, moduleInfo(ctx, m, true, listRetracted))
}
}
}
@@ -129,7 +139,8 @@ func listModules(ctx context.Context, args []string, listVersions bool) []*modin
// Instead, resolve the module, even if it isn't an existing dependency.
info, err := Query(ctx, arg, "latest", "", nil)
if err == nil {
- mods = append(mods, moduleInfo(ctx, module.Version{Path: arg, Version: info.Version}, false))
+ mod := moduleInfo(ctx, module.Version{Path: arg, Version: info.Version}, false, listRetracted)
+ mods = append(mods, mod)
} else {
mods = append(mods, &modinfo.ModulePublic{
Path: arg,
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index 686d491219..1664d8c5be 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -4,6 +4,95 @@
package modload
+// This file contains the module-mode package loader, as well as some accessory
+// functions pertaining to the package import graph.
+//
+// There are several exported entry points into package loading (such as
+// ImportPathsQuiet and LoadALL), but they are all 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 and related functions
+// (LoadALL, LoadVendor), 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 with lazy loading 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"
@@ -14,8 +103,12 @@ import (
"path"
pathpkg "path"
"path/filepath"
+ "reflect"
+ "runtime"
"sort"
"strings"
+ "sync"
+ "sync/atomic"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
@@ -25,28 +118,12 @@ import (
"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),
@@ -63,7 +140,18 @@ func ImportPaths(ctx context.Context, patterns []string) []*search.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) {
+ InitMod(ctx)
+
+ allPatternIsRoot := false
+ var matches []*search.Match
+ for _, pattern := range search.CleanPatterns(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 +178,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 +191,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, 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, 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,51 +216,28 @@ func ImportPathsQuiet(ctx context.Context, patterns []string, tags map[string]bo
}
}
- InitMod(ctx)
-
- var matches []*search.Match
- for _, pattern := range search.CleanPatterns(patterns) {
- matches = append(matches, search.NewMatch(pattern))
- }
+ loaded = loadFromRoots(loaderParams{
+ tags: tags,
+ allPatternIsRoot: allPatternIsRoot,
+ allClosesOverTests: index.allPatternClosesOverTests(),
- 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)
+ updateMatches(loaded)
checkMultiplePaths()
WriteGoMod()
return matches
}
-// 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()
-}
-
// matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories
// outside of the standard library and active modules.
func matchLocalDirs(m *search.Match) {
@@ -310,7 +374,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 +388,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 ""
@@ -347,12 +424,14 @@ 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{
+ tags: tags,
+ listRoots: func() (roots []string) {
+ roots = append(roots, imports...)
+ roots = append(roots, testImports...)
+ return roots
+ },
+ allClosesOverTests: index.allPatternClosesOverTests(),
})
WriteGoMod()
}
@@ -383,34 +462,19 @@ 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.
+//
+// In modules that specify "go 1.16" or higher, ALL follows only one layer of
+// test dependencies. In "go 1.15" or lower, ALL follows the imports of tests of
+// dependencies of tests.
func LoadALL(ctx context.Context) []string {
- return loadAll(ctx, true)
+ InitMod(ctx)
+ return loadAll(ctx, index.allPatternClosesOverTests())
}
// LoadVendor is like LoadALL but only follows test dependencies
@@ -418,20 +482,20 @@ func LoadALL(ctx context.Context) []string {
// 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)
+ // 'go mod vendor' has never followed test dependencies since Go 1.11.
+ const closeOverTests = false
+ return loadAll(ctx, closeOverTests)
+}
- 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 })
+func loadAll(ctx context.Context, closeOverTests bool) []string {
+ inTarget := TargetPackages(ctx, "...")
+ loaded = loadFromRoots(loaderParams{
+ tags: imports.AnyTags(),
+ listRoots: func() []string { return inTarget.Pkgs },
+ allPatternIsRoot: true,
+ allClosesOverTests: closeOverTests,
+ })
checkMultiplePaths()
WriteGoMod()
@@ -443,7 +507,7 @@ func loadAll(ctx context.Context, testAll bool) []string {
}
paths = append(paths, pkg.path)
}
- for _, err := range all.Errs {
+ for _, err := range inTarget.Errs {
base.Errorf("%v", err)
}
base.ExitIfErrors()
@@ -463,52 +527,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 +581,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,76 +616,148 @@ 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
- goVersion map[string]string // go version recorded in each module
+ direct map[string]bool // imported directly by main module
+}
+
+type loaderParams struct {
+ tags map[string]bool // tags for scanDir
+ listRoots func() []string
+ allPatternIsRoot bool // Is the "all" pattern an additional root?
+ allClosesOverTests bool // Does the "all" pattern include the transitive closure of tests of packages in "all"?
}
// LoadTests controls whether the loaders load tests of the root packages.
var LoadTests bool
-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
+func (ld *loader) reset() {
+ select {
+ case <-ld.work.Idle():
+ default:
+ panic("loader.reset when not idle")
}
- return ld
-}
-
-func (ld *loader) reset() {
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()
buildList, err = mvs.BuildList(Target, reqs)
@@ -681,47 +765,34 @@ func (ld *loader) load(roots func() []string) {
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.
- }
- base.ExitIfErrors()
- if numAdded == 0 {
+
+ modAddedBy := ld.resolveMissingImports(addedModuleFor)
+ if len(modAddedBy) == 0 {
break
}
@@ -754,99 +825,264 @@ func (ld *loader) load(roots func() []string) {
}
}
- // Add Go versions, computed during walk.
- ld.goVersion = make(map[string]string)
- for _, m := range buildList {
- v, _ := reqs.(*mvsReqs).versions.Load(m)
- ld.goVersion[m.Path], _ = v.(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.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 ld.testRoots && isRoot || ld.testAll {
- test := &loadPkg{
- path: path,
- testOf: pkg,
- }
- pkg.test = test
+ if pkg.err != errImportMissing {
+ // Leave other errors for Import or load.Packages to report.
+ continue
+ }
+
+ 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
}
- if isRoot {
- ld.roots = append(ld.roots, pkg)
+
+ 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
- }
- if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) {
- // Leave for error during load.
- // (Module mode does not allow local imports.)
- 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
+ }
- // 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 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 LoadTests && new.has(pkgIsRoot):
+ // LoadTest explicitly requests tests of “the root packages”.
+ wantTest = true
}
- var testImports []string
- var err error
- imports, testImports, err = scanDir(pkg.dir, ld.tags)
- if err != nil {
- pkg.err = err
- 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)
}
- if pkg.test != nil {
- pkg.testImports = testImports
+ }
+
+ 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)
}
}
+}
+
+// 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
+ }
- inStd := (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "")
+ pkg.mod, pkg.dir, pkg.err = importFromBuildList(context.TODO(), pkg.path)
+ 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)
+ }
+
+ 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
@@ -857,13 +1093,21 @@ 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.
vendorPath := pathpkg.Join("vendor", path)
if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil {
return vendorPath
@@ -876,30 +1120,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
}
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index 9f4ec5a49f..18dd293ac9 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -5,13 +5,31 @@
package modload
import (
+ "context"
+ "errors"
+ "fmt"
+ "path/filepath"
+ "strings"
+ "sync"
+ "unicode"
+
"cmd/go/internal/base"
"cmd/go/internal/cfg"
+ "cmd/go/internal/lockedfile"
+ "cmd/go/internal/modfetch"
+ "cmd/go/internal/par"
+ "cmd/go/internal/trace"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
)
+// lazyLoadingVersion is the Go version (plus leading "v") at which lazy module
+// loading takes effect.
+const lazyLoadingVersionV = "v1.16"
+const go116EnableLazyLoading = true
+
var modFile *modfile.File
// A modFileIndex is an index of data corresponding to a modFile
@@ -20,7 +38,7 @@ type modFileIndex struct {
data []byte
dataNeedsFix bool // true if fixVersion applied a change while parsing data
module module.Version
- goVersion string
+ goVersionV string // GoVersion with "v" prefix
require map[module.Version]requireMeta
replace map[module.Version]module.Version
exclude map[module.Version]bool
@@ -33,9 +51,151 @@ type requireMeta struct {
indirect bool
}
-// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod.
-func Allowed(m module.Version) bool {
- return index == nil || !index.exclude[m]
+// CheckAllowed returns an error equivalent to ErrDisallowed if m is excluded by
+// the main module's go.mod or retracted by its author. Most version queries use
+// this to filter out versions that should not be used.
+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 {
+ return err
+ }
+ return nil
+}
+
+// ErrDisallowed is returned by version predicates passed to Query and similar
+// functions to indicate that a version should not be considered.
+var ErrDisallowed = errors.New("disallowed module version")
+
+// CheckExclusions returns an error equivalent to ErrDisallowed if module m is
+// excluded by the main module's go.mod file.
+func CheckExclusions(ctx context.Context, m module.Version) error {
+ if index != nil && index.exclude[m] {
+ return module.VersionError(m, errExcluded)
+ }
+ return nil
+}
+
+var errExcluded = &excludedError{}
+
+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
+// its author.
+func checkRetractions(ctx context.Context, m module.Version) error {
+ if m.Version == "" {
+ // Main module, standard library, or file replacement module.
+ // Cannot be retracted.
+ return nil
+ }
+
+ // Look up retraction information from the latest available version of
+ // the module. Cache retraction information so we don't parse the go.mod
+ // file repeatedly.
+ type entry struct {
+ retract []retraction
+ err error
+ }
+ path := m.Path
+ e := retractCache.Do(path, func() (v interface{}) {
+ ctx, span := trace.StartSpan(ctx, "checkRetractions "+path)
+ defer span.Done()
+
+ if repl := Replacement(module.Version{Path: m.Path}); repl.Path != "" {
+ // All versions of the module were replaced with a local directory.
+ // Don't load retractions.
+ return &entry{nil, nil}
+ }
+
+ // 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)
+ if err != nil {
+ return &entry{err: 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})
+ if err != nil {
+ return &entry{err: err}
+ }
+ return &entry{retract: summary.retract}
+ }).(*entry)
+
+ if e.err != nil {
+ return fmt.Errorf("loading module retractions: %v", e.err)
+ }
+
+ var rationale []string
+ isRetracted := false
+ for _, r := range e.retract {
+ if semver.Compare(r.Low, m.Version) <= 0 && semver.Compare(m.Version, r.High) <= 0 {
+ isRetracted = true
+ if r.Rationale != "" {
+ rationale = append(rationale, r.Rationale)
+ }
+ }
+ }
+ if isRetracted {
+ return &retractedError{rationale: rationale}
+ }
+ return nil
+}
+
+var retractCache par.Cache
+
+type retractedError struct {
+ rationale []string
+}
+
+func (e *retractedError) Error() string {
+ msg := "retracted by module author"
+ 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])
+ }
+ return msg
+}
+
+func (e *retractedError) Is(err error) bool {
+ return err == ErrDisallowed
+}
+
+// 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.
+func ShortRetractionRationale(rationale string) string {
+ const maxRationaleBytes = 500
+ if i := strings.Index(rationale, "\n"); i >= 0 {
+ rationale = rationale[:i]
+ }
+ rationale = strings.TrimSpace(rationale)
+ if rationale == "" {
+ return "retracted by module author"
+ }
+ if len(rationale) > maxRationaleBytes {
+ return "(rationale omitted: too long)"
+ }
+ for _, r := range rationale {
+ if !unicode.IsGraphic(r) && !unicode.IsSpace(r) {
+ return "(rationale omitted: contains non-printable characters)"
+ }
+ }
+ // NOTE: the go.mod parser rejects invalid UTF-8, so we don't check that here.
+ return rationale
}
// Replacement returns the replacement for mod, if any, from go.mod.
@@ -66,9 +226,11 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd
i.module = modFile.Module.Mod
}
- i.goVersion = ""
+ i.goVersionV = ""
if modFile.Go != nil {
- i.goVersion = modFile.Go.Version
+ // We're going to use the semver package to compare Go versions, so go ahead
+ // and add the "v" prefix it expects once instead of every time.
+ i.goVersionV = "v" + modFile.Go.Version
}
i.require = make(map[module.Version]requireMeta, len(modFile.Require))
@@ -92,6 +254,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 !go116EnableLazyLoading {
+ return true
+ }
+ if i != nil && semver.Compare(i.goVersionV, lazyLoadingVersionV) < 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,
@@ -114,11 +293,11 @@ func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool {
}
if modFile.Go == nil {
- if i.goVersion != "" {
+ if i.goVersionV != "" {
return true
}
- } else if modFile.Go.Version != i.goVersion {
- if i.goVersion == "" && cfg.BuildMod == "readonly" {
+ } else if "v"+modFile.Go.Version != i.goVersionV {
+ if i.goVersionV == "" && cfg.BuildMod == "readonly" {
// go.mod files did not always require a 'go' version, so do not error out
// if one is missing — we may be inside an older module in the module
// cache, and should bias toward providing useful behavior.
@@ -162,3 +341,190 @@ func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool {
return false
}
+
+// rawGoVersion records the Go version parsed from each module's go.mod file.
+//
+// If a module is replaced, the version of the replacement is keyed by the
+// replacement module.Version, not the version being replaced.
+var rawGoVersion sync.Map // map[module.Version]string
+
+// A modFileSummary is a summary of a go.mod file for which we do not need to
+// retain complete information — for example, the go.mod file of a dependency
+// module.
+type modFileSummary struct {
+ module module.Version
+ goVersionV string // GoVersion with "v" prefix
+ require []module.Version
+ retract []retraction
+}
+
+// A retraction consists of a retracted version interval and rationale.
+// retraction is like modfile.Retract, but it doesn't point to the syntax tree.
+type retraction struct {
+ modfile.VersionInterval
+ Rationale string
+}
+
+// goModSummary returns a summary of the go.mod file for module m,
+// 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.
+//
+// The caller must not modify the returned summary.
+func goModSummary(m module.Version) (*modFileSummary, error) {
+ if m == Target {
+ 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}
+ }
+
+ // 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.
+
+ // 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}
+ }
+
+ actual := Replacement(m)
+ if actual.Path == "" {
+ actual = m
+ }
+ summary, err := rawGoModSummary(actual)
+ if err != nil {
+ return cached{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"))}
+ }
+
+ // 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:
+ module declares its path as: %s
+ 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]
+ for _, r := range summary.require {
+ if !index.exclude[r] {
+ nonExcluded = append(nonExcluded, r)
+ }
+ }
+ summary.require = nonExcluded
+ }
+ return cached{summary, nil}
+ }).(cached)
+
+ return c.summary, c.err
+}
+
+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.
+//
+// rawGoModSummary cannot be used on the Target module.
+func rawGoModSummary(m module.Version) (*modFileSummary, error) {
+ if m == Target {
+ 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")
+
+ 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 := modfetch.GoMod(m.Path, m.Version)
+ if err != nil {
+ return nil, err
+ }
+ 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.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.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
+}
diff --git a/src/cmd/go/internal/modload/mvs.go b/src/cmd/go/internal/modload/mvs.go
index 67eb2c2e19..24856260d4 100644
--- a/src/cmd/go/internal/modload/mvs.go
+++ b/src/cmd/go/internal/modload/mvs.go
@@ -11,16 +11,10 @@ import (
"os"
"path/filepath"
"sort"
- "sync"
- "cmd/go/internal/base"
- "cmd/go/internal/cfg"
- "cmd/go/internal/lockedfile"
"cmd/go/internal/modfetch"
"cmd/go/internal/mvs"
- "cmd/go/internal/par"
- "golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
)
@@ -29,8 +23,6 @@ import (
// with any exclusions or replacements applied internally.
type mvsReqs struct {
buildList []module.Version
- cache par.Cache
- versions sync.Map
}
// Reqs returns the current module requirement graph.
@@ -44,118 +36,21 @@ func Reqs() mvs.Reqs {
}
func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
- type cached struct {
- list []module.Version
- err error
- }
-
- c := r.cache.Do(mod, func() interface{} {
- list, err := r.required(mod)
- if err != nil {
- return cached{nil, err}
- }
- for i, mv := range list {
- if index != nil {
- for index.exclude[mv] {
- mv1, err := r.next(mv)
- if err != nil {
- return cached{nil, err}
- }
- if mv1.Version == "none" {
- return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)}
- }
- mv = mv1
- }
- }
- list[i] = mv
- }
-
- return cached{list, nil}
- }).(cached)
-
- return c.list, c.err
-}
-
-func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version {
- list := make([]module.Version, 0, len(f.Require))
- for _, r := range f.Require {
- list = append(list, r.Mod)
- }
- return list
-}
-
-// required returns a unique copy of the requirements of mod.
-func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) {
if mod == Target {
- if modFile != nil && modFile.Go != nil {
- r.versions.LoadOrStore(mod, modFile.Go.Version)
- }
- return append([]module.Version(nil), r.buildList[1:]...), nil
- }
-
- if cfg.BuildMod == "vendor" {
- // For every module other than the target,
- // return the full list of modules from modules.txt.
- readVendorList()
- return append([]module.Version(nil), vendorList...), nil
- }
-
- origPath := mod.Path
- if repl := Replacement(mod); repl.Path != "" {
- if repl.Version == "" {
- // TODO: need to slip the new version into the tags list etc.
- dir := repl.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, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
- }
- f, err := modfile.ParseLax(gomod, data, nil)
- if err != nil {
- return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
- }
- if f.Go != nil {
- r.versions.LoadOrStore(mod, f.Go.Version)
- }
- return r.modFileToList(f), nil
- }
- mod = repl
+ // Use the build list as it existed when r was constructed, not the current
+ // global build list.
+ return r.buildList[1:], nil
}
if mod.Version == "none" {
return nil, nil
}
- if !semver.IsValid(mod.Version) {
- // Disallow the broader queries supported by fetch.Lookup.
- base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version)
- }
-
- data, err := modfetch.GoMod(mod.Path, mod.Version)
+ summary, err := goModSummary(mod)
if err != nil {
return nil, err
}
- f, err := modfile.ParseLax("go.mod", data, nil)
- if err != nil {
- return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err))
- }
-
- if f.Module == nil {
- return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line"))
- }
- if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path {
- return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod:
- module declares its path as: %s
- but was required as: %s`, mpath, origPath))
- }
- if f.Go != nil {
- r.versions.LoadOrStore(mod, f.Go.Version)
- }
-
- return r.modFileToList(f), nil
+ return summary.require, nil
}
// Max returns the maximum of v1 and v2 according to semver.Compare.
@@ -177,16 +72,29 @@ func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) {
return m, nil
}
-func versions(path string) ([]string, error) {
+func versions(ctx context.Context, path string, allowed AllowedFunc) ([]string, error) {
// Note: modfetch.Lookup and repo.Versions are cached,
// 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)
- if err == nil {
- versions, err = repo.Versions("")
+ if err != nil {
+ return err
+ }
+ allVersions, err := repo.Versions("")
+ if err != nil {
+ return err
+ }
+ allowedVersions := make([]string, 0, len(allVersions))
+ for _, v := range allVersions {
+ if err := allowed(ctx, module.Version{Path: path, Version: v}); err == nil {
+ allowedVersions = append(allowedVersions, v)
+ } else if !errors.Is(err, ErrDisallowed) {
+ return err
+ }
}
- return err
+ versions = allowedVersions
+ return nil
})
return versions, err
}
@@ -194,7 +102,8 @@ func versions(path string) ([]string, error) {
// Previous returns the tagged version of m.Path immediately prior to
// m.Version, or version "none" if no prior version is tagged.
func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
- list, err := versions(m.Path)
+ // TODO(golang.org/issue/38714): thread tracing context through MVS.
+ list, err := versions(context.TODO(), m.Path, CheckAllowed)
if err != nil {
return module.Version{}, err
}
@@ -209,7 +118,8 @@ func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
// It is only used by the exclusion processing in the Required method,
// not called directly by MVS.
func (*mvsReqs) next(m module.Version) (module.Version, error) {
- list, err := versions(m.Path)
+ // TODO(golang.org/issue/38714): thread tracing context through MVS.
+ list, err := versions(context.TODO(), m.Path, CheckAllowed)
if err != nil {
return module.Version{}, err
}
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index e82eb1506f..f67a738677 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -52,12 +52,16 @@ import (
// version that would otherwise be chosen. This prevents accidental downgrades
// from newer pre-release or development versions.
//
-// If the allowed function is non-nil, Query excludes any versions for which
-// allowed returns false.
+// The allowed function (which may be nil) is used to filter out unsuitable
+// versions (see AllowedFunc documentation for details). If the query refers to
+// a specific revision (for example, "master"; see IsRevisionQuery), and the
+// revision is disallowed by allowed, Query returns the error. If the query
+// does not refer to a specific revision (for example, "latest"), Query
+// acts as if versions disallowed by allowed do not exist.
//
// If path is the path of the main module and the query is "latest",
// Query returns Target.Version as the version.
-func Query(ctx context.Context, path, query, current string, allowed func(module.Version) bool) (*modfetch.RevInfo, error) {
+func Query(ctx context.Context, path, query, current string, allowed AllowedFunc) (*modfetch.RevInfo, error) {
var info *modfetch.RevInfo
err := modfetch.TryProxies(func(proxy string) (err error) {
info, err = queryProxy(ctx, proxy, path, query, current, allowed)
@@ -66,6 +70,17 @@ func Query(ctx context.Context, path, query, current string, allowed func(module
return info, err
}
+// AllowedFunc is used by Query and other functions to filter out unsuitable
+// versions, for example, those listed in exclude directives in the main
+// module's go.mod file.
+//
+// An AllowedFunc returns an error equivalent to ErrDisallowed for an unsuitable
+// version. Any other error indicates the function was unable to determine
+// whether the version should be allowed, for example, the function was unable
+// to fetch or parse a go.mod file containing retractions. Typically, errors
+// other than ErrDisallowd may be ignored.
+type AllowedFunc func(context.Context, module.Version) error
+
var errQueryDisabled error = queryDisabledError{}
type queryDisabledError struct{}
@@ -77,7 +92,7 @@ func (queryDisabledError) Error() string {
return fmt.Sprintf("cannot query module due to -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
}
-func queryProxy(ctx context.Context, proxy, path, query, current string, allowed func(module.Version) bool) (*modfetch.RevInfo, error) {
+func queryProxy(ctx context.Context, proxy, path, query, current string, allowed AllowedFunc) (*modfetch.RevInfo, error) {
ctx, span := trace.StartSpan(ctx, "modload.queryProxy "+path+" "+query)
defer span.Done()
@@ -88,7 +103,7 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
return nil, errQueryDisabled
}
if allowed == nil {
- allowed = func(module.Version) bool { return true }
+ allowed = func(context.Context, module.Version) error { return nil }
}
// Parse query to detect parse errors (and possibly handle query)
@@ -104,7 +119,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
return module.CheckPathMajor(v, pathMajor) == nil
}
var (
- ok func(module.Version) bool
+ match = func(m module.Version) bool { return true }
+
prefix string
preferOlder bool
mayUseLatest bool
@@ -112,21 +128,18 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
)
switch {
case query == "latest":
- ok = allowed
mayUseLatest = true
case query == "upgrade":
- ok = allowed
mayUseLatest = true
case query == "patch":
if current == "" {
- ok = allowed
mayUseLatest = true
} else {
prefix = semver.MajorMinor(current)
- ok = func(m module.Version) bool {
- return matchSemverPrefix(prefix, m.Version) && allowed(m)
+ match = func(m module.Version) bool {
+ return matchSemverPrefix(prefix, m.Version)
}
}
@@ -139,8 +152,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
// 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)
}
- ok = func(m module.Version) bool {
- return semver.Compare(m.Version, v) <= 0 && allowed(m)
+ match = func(m module.Version) bool {
+ return semver.Compare(m.Version, v) <= 0
}
if !matchesMajor(v) {
preferIncompatible = true
@@ -151,8 +164,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
if !semver.IsValid(v) {
return badVersion(v)
}
- ok = func(m module.Version) bool {
- return semver.Compare(m.Version, v) < 0 && allowed(m)
+ match = func(m module.Version) bool {
+ return semver.Compare(m.Version, v) < 0
}
if !matchesMajor(v) {
preferIncompatible = true
@@ -163,8 +176,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
if !semver.IsValid(v) {
return badVersion(v)
}
- ok = func(m module.Version) bool {
- return semver.Compare(m.Version, v) >= 0 && allowed(m)
+ match = func(m module.Version) bool {
+ return semver.Compare(m.Version, v) >= 0
}
preferOlder = true
if !matchesMajor(v) {
@@ -180,8 +193,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
// 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)
}
- ok = func(m module.Version) bool {
- return semver.Compare(m.Version, v) > 0 && allowed(m)
+ match = func(m module.Version) bool {
+ return semver.Compare(m.Version, v) > 0
}
preferOlder = true
if !matchesMajor(v) {
@@ -189,8 +202,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
}
case semver.IsValid(query) && isSemverPrefix(query):
- ok = func(m module.Version) bool {
- return matchSemverPrefix(query, m.Version) && allowed(m)
+ match = func(m module.Version) bool {
+ return matchSemverPrefix(query, m.Version)
}
prefix = query + "."
if !matchesMajor(query) {
@@ -219,8 +232,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
return nil, queryErr
}
}
- if !allowed(module.Version{Path: path, Version: info.Version}) {
- return nil, fmt.Errorf("%s@%s excluded", path, info.Version)
+ if err := allowed(ctx, module.Version{Path: path, Version: info.Version}); errors.Is(err, ErrDisallowed) {
+ return nil, err
}
return info, nil
}
@@ -229,8 +242,8 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
if query != "latest" {
return nil, fmt.Errorf("can't query specific version (%q) for the main module (%s)", query, path)
}
- if !allowed(Target) {
- return nil, fmt.Errorf("internal error: main module version is not allowed")
+ 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
}
@@ -248,7 +261,13 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
if err != nil {
return nil, err
}
- releases, prereleases, err := filterVersions(ctx, path, versions, ok, preferIncompatible)
+ 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)
if err != nil {
return nil, err
}
@@ -288,11 +307,12 @@ 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,
- // provided it is not excluded.
+ // Special case for "latest": if no tags match, use latest commit in repo
+ // if it is allowed.
latest, err := repo.Latest()
if err == nil {
- if allowed(module.Version{Path: path, Version: latest.Version}) {
+ m := module.Version{Path: path, Version: latest.Version}
+ if err := allowed(ctx, m); !errors.Is(err, ErrDisallowed) {
return lookup(latest.Version)
}
} else if !errors.Is(err, os.ErrNotExist) {
@@ -303,6 +323,22 @@ func queryProxy(ctx context.Context, proxy, path, query, current string, allowed
return nil, &NoMatchingVersionError{query: query, current: current}
}
+// IsRevisionQuery returns true if vers is a version query that may refer to
+// a particular version or revision in a repository like "v1.0.0", "master",
+// or "0123abcd". IsRevisionQuery returns false if vers is a query that
+// chooses from among available versions like "latest" or ">v1.0.0".
+func IsRevisionQuery(vers string) bool {
+ if vers == "latest" ||
+ vers == "upgrade" ||
+ vers == "patch" ||
+ strings.HasPrefix(vers, "<") ||
+ strings.HasPrefix(vers, ">") ||
+ (semver.IsValid(vers) && isSemverPrefix(vers)) {
+ return false
+ }
+ return true
+}
+
// isSemverPrefix reports whether v is a semantic version prefix: v1 or v1.2 (not v1.2.3).
// The caller is assumed to have checked that semver.IsValid(v) is true.
func isSemverPrefix(v string) bool {
@@ -329,13 +365,16 @@ func matchSemverPrefix(p, v string) bool {
// filterVersions classifies versions into releases and pre-releases, filtering
// out:
-// 1. versions that do not satisfy the 'ok' predicate, and
+// 1. versions that do not satisfy the 'allowed' predicate, and
// 2. "+incompatible" versions, if a compatible one satisfies the predicate
// and the incompatible version is not preferred.
-func filterVersions(ctx context.Context, path string, versions []string, ok func(module.Version) bool, preferIncompatible bool) (releases, prereleases []string, err error) {
+//
+// 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) {
var lastCompatible string
for _, v := range versions {
- if !ok(module.Version{Path: path, Version: v}) {
+ if err := allowed(ctx, module.Version{Path: path, Version: v}); errors.Is(err, ErrDisallowed) {
continue
}
@@ -385,7 +424,7 @@ type QueryResult struct {
// 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 func(module.Version) bool) ([]QueryResult, error) {
+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)
@@ -406,7 +445,7 @@ func QueryPackage(ctx context.Context, path, query string, allowed func(module.V
// 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 func(module.Version) bool) ([]QueryResult, error) {
+func QueryPattern(ctx context.Context, pattern, query string, allowed AllowedFunc) ([]QueryResult, error) {
ctx, span := trace.StartSpan(ctx, "modload.QueryPattern "+pattern+" "+query)
defer span.Done()
@@ -450,8 +489,8 @@ func QueryPattern(ctx context.Context, pattern, query string, allowed func(modul
if query != "latest" {
return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path)
}
- if !allowed(Target) {
- return nil, fmt.Errorf("internal error: package %s is in the main module (%s), but version is not allowed", pattern, Target.Path)
+ 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 []QueryResult{{
Mod: Target,
diff --git a/src/cmd/go/internal/modload/query_test.go b/src/cmd/go/internal/modload/query_test.go
index 77080e9b5b..351826f2ab 100644
--- a/src/cmd/go/internal/modload/query_test.go
+++ b/src/cmd/go/internal/modload/query_test.go
@@ -187,9 +187,11 @@ func TestQuery(t *testing.T) {
if allow == "" {
allow = "*"
}
- allowed := func(m module.Version) bool {
- ok, _ := path.Match(allow, m.Version)
- return ok
+ allowed := func(ctx context.Context, m module.Version) error {
+ if ok, _ := path.Match(allow, m.Version); !ok {
+ return ErrDisallowed
+ }
+ return nil
}
tt := tt
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.query+"/"+tt.current+"/"+allow, func(t *testing.T) {
diff --git a/src/cmd/go/internal/modload/vendor.go b/src/cmd/go/internal/modload/vendor.go
index 71f68efbcc..9f34b829fc 100644
--- a/src/cmd/go/internal/modload/vendor.go
+++ b/src/cmd/go/internal/modload/vendor.go
@@ -133,7 +133,7 @@ func checkVendorConsistency() {
readVendorList()
pre114 := false
- if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 {
+ if semver.Compare(index.goVersionV, "v1.14") < 0 {
// Go versions before 1.14 did not include enough information in
// vendor/modules.txt to check for consistency.
// If we know that we're on an earlier version, relax the consistency check.
@@ -150,6 +150,8 @@ func checkVendorConsistency() {
}
}
+ // Iterate over the Require directives in their original (not indexed) order
+ // so that the errors match the original file.
for _, r := range modFile.Require {
if !vendorMeta[r.Mod].Explicit {
if pre114 {
diff --git a/src/cmd/go/internal/mvs/errors.go b/src/cmd/go/internal/mvs/errors.go
new file mode 100644
index 0000000000..5564965fb5
--- /dev/null
+++ b/src/cmd/go/internal/mvs/errors.go
@@ -0,0 +1,101 @@
+// 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 mvs
+
+import (
+ "fmt"
+ "strings"
+
+ "golang.org/x/mod/module"
+)
+
+// BuildListError decorates an error that occurred gathering requirements
+// while constructing a build list. BuildListError prints the chain
+// of requirements to the module where the error occurred.
+type BuildListError struct {
+ Err error
+ stack []buildListErrorElem
+}
+
+type buildListErrorElem struct {
+ m module.Version
+
+ // nextReason is the reason this module depends on the next module in the
+ // stack. Typically either "requires", or "updating to".
+ nextReason string
+}
+
+// NewBuildListError returns a new BuildListError wrapping an error that
+// occurred at a module found along the given path of requirements and/or
+// upgrades, which must be non-empty.
+//
+// The isUpgrade function reports whether a path step is due to an upgrade.
+// A nil isUpgrade function indicates that none of the path steps are due to upgrades.
+func NewBuildListError(err error, path []module.Version, isUpgrade func(from, to module.Version) bool) *BuildListError {
+ stack := make([]buildListErrorElem, 0, len(path))
+ for len(path) > 1 {
+ reason := "requires"
+ if isUpgrade != nil && isUpgrade(path[0], path[1]) {
+ reason = "updating to"
+ }
+ stack = append(stack, buildListErrorElem{
+ m: path[0],
+ nextReason: reason,
+ })
+ path = path[1:]
+ }
+ stack = append(stack, buildListErrorElem{m: path[0]})
+
+ return &BuildListError{
+ Err: err,
+ stack: stack,
+ }
+}
+
+// Module returns the module where the error occurred. If the module stack
+// is empty, this returns a zero value.
+func (e *BuildListError) Module() module.Version {
+ if len(e.stack) == 0 {
+ return module.Version{}
+ }
+ return e.stack[len(e.stack)-1].m
+}
+
+func (e *BuildListError) Error() string {
+ b := &strings.Builder{}
+ stack := e.stack
+
+ // Don't print modules at the beginning of the chain without a
+ // version. These always seem to be the main module or a
+ // synthetic module ("target@").
+ for len(stack) > 0 && stack[0].m.Version == "" {
+ stack = stack[1:]
+ }
+
+ if len(stack) == 0 {
+ b.WriteString(e.Err.Error())
+ } else {
+ for _, elem := range stack[:len(stack)-1] {
+ fmt.Fprintf(b, "%s %s\n\t", elem.m, elem.nextReason)
+ }
+ // Ensure that the final module path and version are included as part of the
+ // error message.
+ m := stack[len(stack)-1].m
+ if mErr, ok := e.Err.(*module.ModuleError); ok {
+ actual := module.Version{Path: mErr.Path, Version: mErr.Version}
+ if v, ok := mErr.Err.(*module.InvalidVersionError); ok {
+ actual.Version = v.Version
+ }
+ if actual == m {
+ fmt.Fprintf(b, "%v", e.Err)
+ } else {
+ fmt.Fprintf(b, "%s (replaced by %s): %v", m, actual, mErr.Err)
+ }
+ } else {
+ fmt.Fprintf(b, "%v", module.VersionError(m, e.Err))
+ }
+ }
+ return b.String()
+}
diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go
index 1f8eaa1f60..ea23a9f45e 100644
--- a/src/cmd/go/internal/mvs/mvs.go
+++ b/src/cmd/go/internal/mvs/mvs.go
@@ -9,7 +9,6 @@ package mvs
import (
"fmt"
"sort"
- "strings"
"sync"
"sync/atomic"
@@ -61,59 +60,6 @@ type Reqs interface {
Previous(m module.Version) (module.Version, error)
}
-// BuildListError decorates an error that occurred gathering requirements
-// while constructing a build list. BuildListError prints the chain
-// of requirements to the module where the error occurred.
-type BuildListError struct {
- Err error
- stack []buildListErrorElem
-}
-
-type buildListErrorElem struct {
- m module.Version
-
- // nextReason is the reason this module depends on the next module in the
- // stack. Typically either "requires", or "upgraded to".
- nextReason string
-}
-
-// Module returns the module where the error occurred. If the module stack
-// is empty, this returns a zero value.
-func (e *BuildListError) Module() module.Version {
- if len(e.stack) == 0 {
- return module.Version{}
- }
- return e.stack[0].m
-}
-
-func (e *BuildListError) Error() string {
- b := &strings.Builder{}
- stack := e.stack
-
- // Don't print modules at the beginning of the chain without a
- // version. These always seem to be the main module or a
- // synthetic module ("target@").
- for len(stack) > 0 && stack[len(stack)-1].m.Version == "" {
- stack = stack[:len(stack)-1]
- }
-
- for i := len(stack) - 1; i >= 1; i-- {
- fmt.Fprintf(b, "%s@%s %s\n\t", stack[i].m.Path, stack[i].m.Version, stack[i].nextReason)
- }
- if len(stack) == 0 {
- b.WriteString(e.Err.Error())
- } else {
- // Ensure that the final module path and version are included as part of the
- // error message.
- if _, ok := e.Err.(*module.ModuleError); ok {
- fmt.Fprintf(b, "%v", e.Err)
- } else {
- fmt.Fprintf(b, "%v", module.VersionError(stack[0].m, e.Err))
- }
- }
- return b.String()
-}
-
// BuildList returns the build list for the target module.
//
// target is the root vertex of a module requirement graph. For cmd/go, this is
@@ -202,18 +148,30 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m
q = q[1:]
if node.err != nil {
- err := &BuildListError{
- Err: node.err,
- stack: []buildListErrorElem{{m: node.m}},
- }
+ pathUpgrade := map[module.Version]module.Version{}
+
+ // Construct the error path reversed (from the error to the main module),
+ // then reverse it to obtain the usual order (from the main module to
+ // the error).
+ errPath := []module.Version{node.m}
for n, prev := neededBy[node], node; n != nil; n, prev = neededBy[n], n {
- reason := "requires"
if n.upgrade == prev.m {
- reason = "updating to"
+ pathUpgrade[n.m] = prev.m
}
- err.stack = append(err.stack, buildListErrorElem{m: n.m, nextReason: reason})
+ errPath = append(errPath, n.m)
}
- return nil, err
+ i, j := 0, len(errPath)-1
+ for i < j {
+ errPath[i], errPath[j] = errPath[j], errPath[i]
+ i++
+ j--
+ }
+
+ isUpgrade := func(from, to module.Version) bool {
+ return pathUpgrade[from] == to
+ }
+
+ return nil, NewBuildListError(node.err, errPath, isUpgrade)
}
neighbors := node.required
diff --git a/src/cmd/go/internal/par/queue.go b/src/cmd/go/internal/par/queue.go
new file mode 100644
index 0000000000..180bc75e34
--- /dev/null
+++ b/src/cmd/go/internal/par/queue.go
@@ -0,0 +1,88 @@
+// 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 par
+
+import "fmt"
+
+// Queue manages a set of work items to be executed in parallel. The number of
+// active work items is limited, and excess items are queued sequentially.
+type Queue struct {
+ maxActive int
+ st chan queueState
+}
+
+type queueState struct {
+ active int // number of goroutines processing work; always nonzero when len(backlog) > 0
+ backlog []func()
+ idle chan struct{} // if non-nil, closed when active becomes 0
+}
+
+// NewQueue returns a Queue that executes up to maxActive items in parallel.
+//
+// maxActive must be positive.
+func NewQueue(maxActive int) *Queue {
+ if maxActive < 1 {
+ panic(fmt.Sprintf("par.NewQueue called with nonpositive limit (%d)", maxActive))
+ }
+
+ q := &Queue{
+ maxActive: maxActive,
+ st: make(chan queueState, 1),
+ }
+ q.st <- queueState{}
+ return q
+}
+
+// Add adds f as a work item in the queue.
+//
+// Add returns immediately, but the queue will be marked as non-idle until after
+// f (and any subsequently-added work) has completed.
+func (q *Queue) Add(f func()) {
+ st := <-q.st
+ if st.active == q.maxActive {
+ st.backlog = append(st.backlog, f)
+ q.st <- st
+ return
+ }
+ if st.active == 0 {
+ // Mark q as non-idle.
+ st.idle = nil
+ }
+ st.active++
+ q.st <- st
+
+ go func() {
+ for {
+ f()
+
+ st := <-q.st
+ if len(st.backlog) == 0 {
+ if st.active--; st.active == 0 && st.idle != nil {
+ close(st.idle)
+ }
+ q.st <- st
+ return
+ }
+ f, st.backlog = st.backlog[0], st.backlog[1:]
+ q.st <- st
+ }
+ }()
+}
+
+// Idle returns a channel that will be closed when q has no (active or enqueued)
+// work outstanding.
+func (q *Queue) Idle() <-chan struct{} {
+ st := <-q.st
+ defer func() { q.st <- st }()
+
+ if st.idle == nil {
+ st.idle = make(chan struct{})
+ if st.active == 0 {
+ close(st.idle)
+ }
+ }
+
+ return st.idle
+}
diff --git a/src/cmd/go/internal/par/queue_test.go b/src/cmd/go/internal/par/queue_test.go
new file mode 100644
index 0000000000..1331e65f98
--- /dev/null
+++ b/src/cmd/go/internal/par/queue_test.go
@@ -0,0 +1,79 @@
+// 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 par
+
+import (
+ "sync"
+ "testing"
+)
+
+func TestQueueIdle(t *testing.T) {
+ q := NewQueue(1)
+ select {
+ case <-q.Idle():
+ default:
+ t.Errorf("NewQueue(1) is not initially idle.")
+ }
+
+ started := make(chan struct{})
+ unblock := make(chan struct{})
+ q.Add(func() {
+ close(started)
+ <-unblock
+ })
+
+ <-started
+ idle := q.Idle()
+ select {
+ case <-idle:
+ t.Errorf("NewQueue(1) is marked idle while processing work.")
+ default:
+ }
+
+ close(unblock)
+ <-idle // Should be closed as soon as the Add callback returns.
+}
+
+func TestQueueBacklog(t *testing.T) {
+ const (
+ maxActive = 2
+ totalWork = 3 * maxActive
+ )
+
+ q := NewQueue(maxActive)
+ t.Logf("q = NewQueue(%d)", maxActive)
+
+ var wg sync.WaitGroup
+ wg.Add(totalWork)
+ started := make([]chan struct{}, totalWork)
+ unblock := make(chan struct{})
+ for i := range started {
+ started[i] = make(chan struct{})
+ i := i
+ q.Add(func() {
+ close(started[i])
+ <-unblock
+ wg.Done()
+ })
+ }
+
+ for i, c := range started {
+ if i < maxActive {
+ <-c // Work item i should be started immediately.
+ } else {
+ select {
+ case <-c:
+ t.Errorf("Work item %d started before previous items finished.", i)
+ default:
+ }
+ }
+ }
+
+ close(unblock)
+ for _, c := range started[maxActive:] {
+ <-c
+ }
+ wg.Wait()
+}
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/flagdefs_test.go b/src/cmd/go/internal/test/flagdefs_test.go
index 7562415298..ab5440b380 100644
--- a/src/cmd/go/internal/test/flagdefs_test.go
+++ b/src/cmd/go/internal/test/flagdefs_test.go
@@ -16,9 +16,14 @@ func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) {
return
}
name := strings.TrimPrefix(f.Name, "test.")
- if name != "testlogfile" && !passFlagToTest[name] {
- t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name)
- t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)")
+ switch name {
+ case "testlogfile", "paniconexit0":
+ // These are internal flags.
+ default:
+ if !passFlagToTest[name] {
+ t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name)
+ t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)")
+ }
}
})
diff --git a/src/cmd/go/internal/test/genflags.go b/src/cmd/go/internal/test/genflags.go
index 512fa1671e..5e83d53980 100644
--- a/src/cmd/go/internal/test/genflags.go
+++ b/src/cmd/go/internal/test/genflags.go
@@ -62,9 +62,10 @@ func testFlags() []string {
}
name := strings.TrimPrefix(f.Name, "test.")
- if name == "testlogfile" {
- // test.testlogfile is “for use only by cmd/go”
- } else {
+ switch name {
+ case "testlogfile", "paniconexit0":
+ // These flags are only for use by cmd/go.
+ default:
names = append(names, name)
}
})
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index 3aee6939d2..1ea6d2881e 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -1164,7 +1164,8 @@ func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.
if !c.disableCache && len(execCmd) == 0 {
testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
}
- args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, testArgs)
+ panicArg := "-test.paniconexit0"
+ args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, testArgs)
if testCoverProfile != "" {
// Write coverage to temporary profile, for merging later.
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 fd37fcb76f..e535998d89 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"
@@ -27,23 +27,23 @@ import (
// 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 +54,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 +63,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 +89,7 @@ type tagCmd struct {
}
// vcsList lists the known version control systems
-var vcsList = []*vcsCmd{
+var vcsList = []*Cmd{
vcsHg,
vcsGit,
vcsSvn,
@@ -97,11 +97,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 +113,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 +146,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 +220,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 +229,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 +257,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 +291,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 +341,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 +364,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 +375,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]
@@ -420,25 +424,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 +453,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 +469,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 +479,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 +497,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 +516,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 +525,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
}
@@ -540,11 +544,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 +556,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 +572,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)
}
}
@@ -593,9 +597,9 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) {
return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
}
-// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS
+// 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 +607,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 +637,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 {
@@ -735,15 +737,15 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths
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 +756,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 +847,21 @@ 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)
+ }
}
rr := &RepoRoot{
Repo: mmi.RepoRoot,
Root: mmi.Prefix,
IsCustom: true,
- VCS: mmi.VCS,
- vcs: vcs,
+ VCS: vcs,
}
return rr, nil
}
@@ -1027,7 +1032,7 @@ var vcsPaths = []*vcsPath{
// Github
{
prefix: "github.com/",
- regexp: lazyregexp.New(`^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`),
+ 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,
@@ -1103,7 +1108,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 +1138,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
}
diff --git a/src/cmd/go/internal/get/vcs_test.go b/src/cmd/go/internal/vcs/vcs_test.go
index 91800baa83..5b874204f1 100644
--- a/src/cmd/go/internal/get/vcs_test.go
+++ b/src/cmd/go/internal/vcs/vcs_test.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 (
"errors"
@@ -28,30 +28,27 @@ func TestRepoRootForImportPath(t *testing.T) {
{
"github.com/golang/groupcache",
&RepoRoot{
- vcs: vcsGit,
+ VCS: vcsGit,
Repo: "https://github.com/golang/groupcache",
},
},
- // Unicode letters in directories (issue 18660).
+ // Unicode letters in directories are not valid.
{
"github.com/user/unicode/испытание",
- &RepoRoot{
- vcs: vcsGit,
- Repo: "https://github.com/user/unicode",
- },
+ nil,
},
// IBM DevOps Services tests
{
"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",
},
},
@@ -92,7 +89,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",
},
},
@@ -105,7 +102,7 @@ func TestRepoRootForImportPath(t *testing.T) {
{
"git.openstack.org/openstack/swift",
&RepoRoot{
- vcs: vcsGit,
+ VCS: vcsGit,
Repo: "https://git.openstack.org/openstack/swift",
},
},
@@ -115,14 +112,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",
},
},
@@ -151,21 +148,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",
},
},
@@ -194,8 +191,8 @@ 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)
}
}
}
@@ -209,7 +206,7 @@ func TestFromDir(t *testing.T) {
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 {
@@ -228,24 +225,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
}{
@@ -270,7 +267,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)
}
@@ -279,7 +276,7 @@ func TestIsSecure(t *testing.T) {
func TestIsSecureGitAllowProtocol(t *testing.T) {
tests := []struct {
- vcs *vcsCmd
+ vcs *Cmd
url string
secure bool
}{
@@ -310,7 +307,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)
}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index d020aa6e9f..e99982ed36 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -240,13 +240,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 +253,10 @@ 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)
}
cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
@@ -275,13 +274,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
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index f1d08e0268..6031897f88 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -259,6 +259,15 @@ 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 cfg.Goarch == "mips" || cfg.Goarch == "mipsle" {
// Define GOMIPS_value from cfg.GOMIPS.
diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go
index dad3b10111..f78020032c 100644
--- a/src/cmd/go/internal/work/init.go
+++ b/src/cmd/go/internal/work/init.go
@@ -252,7 +252,7 @@ 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") {
base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
index 3ee68ac1b4..d2a2697f0f 100644
--- a/src/cmd/go/internal/work/security.go
+++ b/src/cmd/go/internal/work/security.go
@@ -177,6 +177,7 @@ var validLinkerFlags = []*lazyregexp.Regexp{
re(`-Wl,-Bdynamic`),
re(`-Wl,-berok`),
re(`-Wl,-Bstatic`),
+ re(`-Wl,-Bsymbolic-functions`),
re(`-WL,-O([^@,\-][^,]*)?`),
re(`-Wl,-d[ny]`),
re(`-Wl,--disable-new-dtags`),
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
new file mode 100644
index 0000000000..1d8d81071e
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt
@@ -0,0 +1,10 @@
+This version should be retracted, but the go.mod file for the version that would
+contain the retraction is not available.
+-- .mod --
+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_missingmod_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt
new file mode 100644
index 0000000000..bba919ec21
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt
@@ -0,0 +1,4 @@
+The go.mod file at this version will be loaded to check for retractions
+of earlier versions. However, the .mod file is not available.
+-- .info --
+{"Version":"v1.9.0"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt
new file mode 100644
index 0000000000..c4a53e1d80
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt
@@ -0,0 +1,6 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-block"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt
new file mode 100644
index 0000000000..92573b62e3
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt
@@ -0,0 +1,6 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-blockwithcomment"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt
new file mode 100644
index 0000000000..1f0894aa8b
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt
@@ -0,0 +1,8 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-empty"}
+-- empty.go --
+package empty
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt
new file mode 100644
index 0000000000..1b5e753428
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt
@@ -0,0 +1,8 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-long"}
+-- empty.go --
+package empty
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt
new file mode 100644
index 0000000000..b1ffe27225
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt
@@ -0,0 +1,8 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-multiline1"}
+-- empty.go --
+package empty
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt
new file mode 100644
index 0000000000..72f80b3254
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt
@@ -0,0 +1,8 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-multiline2"}
+-- empty.go --
+package empty
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt
new file mode 100644
index 0000000000..1b0450462b
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt
@@ -0,0 +1,6 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-order"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt
new file mode 100644
index 0000000000..949612431e
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt
@@ -0,0 +1,8 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0-unprintable"}
+-- empty.go --
+package empty
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt
new file mode 100644
index 0000000000..3be7d5b56e
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt
@@ -0,0 +1,6 @@
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+-- .info --
+{"Version":"v1.0.1-order"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt
new file mode 100644
index 0000000000..6975d4ebd4
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt
@@ -0,0 +1,48 @@
+Module example.com/retract/description retracts all versions of itself.
+The rationale comments have various problems.
+
+-- .mod --
+module example.com/retract/rationale
+
+go 1.14
+
+retract (
+ v1.0.0-empty
+
+ // short description
+ // more
+ //
+ // detail
+ v1.0.0-multiline1 // suffix
+ // after not included
+)
+
+// short description
+// more
+//
+// detail
+retract v1.0.0-multiline2 // suffix
+
+// loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong
+retract v1.0.0-long
+
+// Ends with a BEL character. Beep!
+retract v1.0.0-unprintable
+
+// block comment
+retract (
+ v1.0.0-block
+
+ // inner comment
+ v1.0.0-blockwithcomment
+)
+
+retract (
+ [v1.0.0-order, v1.0.0-order] // degenerate range
+ v1.0.0-order // single version
+
+ v1.0.1-order // single version
+ [v1.0.1-order, v1.0.1-order] // degenerate range
+)
+-- .info --
+{"Version":"v1.9.0"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt
new file mode 100644
index 0000000000..4dc486b599
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt
@@ -0,0 +1,14 @@
+Module example.com/retract/self/prev is a module that retracts its own
+latest version.
+
+No unretracted versions are available.
+
+-- .mod --
+module example.com/retract/self/all
+
+go 1.15
+
+retract v1.9.0 // bad
+
+-- .info --
+{"Version":"v1.9.0"}
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt
new file mode 100644
index 0000000000..04c28455d7
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt
@@ -0,0 +1,16 @@
+Module example.com/retract/self/prerelease is a module that retracts its own
+latest version and all other release version.
+
+A pre-release version higher than the highest release version is still
+available, and that should be matched by @latest.
+
+-- .mod --
+module example.com/retract/self/prerelease
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt
new file mode 100644
index 0000000000..7c1c047e69
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt
@@ -0,0 +1,19 @@
+Module example.com/retract/self/prerelease is a module that retracts its own
+latest version and all other release version.
+
+A pre-release version higher than the highest release version is still
+available, and that should be matched by @latest.
+
+-- .mod --
+module example.com/retract/self/prerelease
+
+go 1.15
+
+retract v1.0.0 // bad
+retract v1.9.0 // self
+
+-- .info --
+{"Version":"v1.9.0"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt
new file mode 100644
index 0000000000..abf44fdae1
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt
@@ -0,0 +1,16 @@
+Module example.com/retract/self/prerelease is a module that retracts its own
+latest version and all other release version.
+
+A pre-release version higher than the highest release version is still
+available, and that should be matched by @latest.
+
+-- .mod --
+module example.com/retract/self/prerelease
+
+go 1.15
+
+-- .info --
+{"Version":"v1.9.1-pre"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt
new file mode 100644
index 0000000000..095063d69b
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt
@@ -0,0 +1,14 @@
+See example.com_retract_self_prev_v1.9.0.txt.
+
+This version is retracted.
+
+-- .mod --
+module example.com/retract/self/prev
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0-bad"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt
new file mode 100644
index 0000000000..27c3a39065
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt
@@ -0,0 +1,14 @@
+See example.com_retract_self_pref_v1.9.0.txt.
+
+This version is the latest (only) non-retracted version.
+
+-- .mod --
+module example.com/retract/self/prev
+
+go 1.15
+
+-- .info --
+{"Version":"v1.1.0"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt
new file mode 100644
index 0000000000..03d6168f0d
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt
@@ -0,0 +1,18 @@
+Module example.com/retract/self/prev is a module that retracts its own
+latest version, as well as an earlier version.
+
+A previous unretracted release version, v1.1.0, is still available.
+
+-- .mod --
+module example.com/retract/self/prev
+
+go 1.15
+
+retract v1.0.0-bad // bad
+retract v1.9.0 // self
+
+-- .info --
+{"Version":"v1.9.0"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab
new file mode 100644
index 0000000000..f9ab41e88f
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab
@@ -0,0 +1,20 @@
+See example.com_retract_self_pseudo_v1.9.0.txt.
+
+This version is not retracted. It should be returned by the proxy's
+@latest endpoint. It should match the @latest version query.
+
+TODO(golang.org/issue/24031): the proxy and proxy.golang.org both return
+the highest release version from the @latest endpoint, even if that
+version is retracted, so there is no way for the go command to
+discover an unretracted pseudo-version.
+
+-- .mod --
+module example.com/retract/self/pseudo
+
+go 1.15
+
+-- .info --
+{"Version":"v0.0.0-20200325131415-01234567890ab"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt
new file mode 100644
index 0000000000..d47eda0597
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt
@@ -0,0 +1,14 @@
+See example.com_retract_self_pseudo_v1.9.0.txt.
+
+This version is retracted.
+
+-- .mod --
+module example.com/retract/self/pseudo
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0-bad"}
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt
new file mode 100644
index 0000000000..db09cc6a5f
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt
@@ -0,0 +1,16 @@
+Module example.com/retract/self/pseudo is a module that retracts its own
+latest version, as well as an earlier version.
+
+An unretracted pseudo-version is available.
+
+-- .mod --
+module example.com/retract/self/pseudo
+
+go 1.15
+
+retract v1.0.0-bad // bad
+retract v1.9.0 // self
+
+-- .info --
+{"Version":"v1.9.0"}
+
diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt
new file mode 100644
index 0000000000..2f996cfc36
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt
@@ -0,0 +1,10 @@
+-- .mod --
+module example.com/retract
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0-bad"}
+
+-- retract.go --
+package retract
diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt
new file mode 100644
index 0000000000..78152bba4f
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt
@@ -0,0 +1,10 @@
+-- .mod --
+module example.com/retract
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0-good"}
+
+-- retract.go --
+package retract
diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt
new file mode 100644
index 0000000000..3bc9e35b7c
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt
@@ -0,0 +1,10 @@
+-- .mod --
+module example.com/retract
+
+go 1.15
+
+-- .info --
+{"Version":"v1.0.0-unused"}
+
+-- retract.go --
+package retract
diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt
new file mode 100644
index 0000000000..18d6d832e2
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt
@@ -0,0 +1,13 @@
+-- .mod --
+module example.com/retract
+
+go 1.15
+
+retract v1.0.0-bad // bad
+retract v1.0.0-unused // bad
+
+-- .info --
+{"Version":"v1.1.0"}
+
+-- retract.go --
+package retract
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/script/get_insecure_env.txt b/src/cmd/go/testdata/script/get_insecure_env.txt
new file mode 100644
index 0000000000..8d88427c31
--- /dev/null
+++ b/src/cmd/go/testdata/script/get_insecure_env.txt
@@ -0,0 +1,29 @@
+[!net] skip
+[!exec:git] skip
+
+# GOPATH: Set up
+env GO111MODULE=off
+
+# GOPATH: Try go get -d of HTTP-only repo (should fail).
+! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
+
+# GOPATH: Try again with invalid GOINSECURE (should fail).
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/q
+! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
+
+# GOPATH: Try with correct GOINSECURE (should succeed).
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/p
+go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
+
+# GOPATH: Try updating without GOINSECURE (should fail).
+env GOINSECURE=
+! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p
+
+# GOPATH: Try updating with GOINSECURE glob (should succeed).
+env GOINSECURE=*.go-get-*.appspot.com
+go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p
+
+# GOPATH: Try updating with GOINSECURE base URL (should succeed).
+env GOINSECURE=insecure.go-get-issue-15410.appspot.com
+go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p
+
diff --git a/src/cmd/go/testdata/script/get_unicode.txt b/src/cmd/go/testdata/script/get_unicode.txt
deleted file mode 100644
index d3b82bdf25..0000000000
--- a/src/cmd/go/testdata/script/get_unicode.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-env GO111MODULE=off
-
-[!exec:git] skip
-[short] skip
-
-# Construct a repository that imports a non-ASCII path.
-cd $WORK/_origin/example.com/unicode
-exec git init
-exec git config user.name 'Nameless Gopher'
-exec git config user.email 'nobody@golang.org'
-exec git add unicode.go
-exec git commit -m 'add unicode.go'
-
-# Clone the repo into GOPATH so that 'go get -u' can find it.
-mkdir $GOPATH/src/example.com/unicode
-cd $GOPATH/src/example.com/unicode
-exec git clone $WORK/_origin/example.com/unicode .
-
-# Construct the imported repository.
-cd $WORK/_origin/example.com/испытание
-exec git init
-exec git config user.name 'Nameless Gopher'
-exec git config user.email 'nobody@golang.org'
-exec git add испытание.go
-exec git commit -m 'add испытание.go'
-
-# Clone that repo into GOPATH too.
-mkdir $GOPATH/src/example.com/испытание
-cd $GOPATH/src/example.com/испытание
-exec git clone $WORK/_origin/example.com/испытание .
-
-# Upgrading the importer should pull from the non-ASCII repo.
-cd $GOPATH
-go get -u example.com/unicode
-
--- $WORK/_origin/example.com/unicode/unicode.go --
-package unicode
-import _ "example.com/испытание"
--- $WORK/_origin/example.com/испытание/испытание.go --
-package испытание
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_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/mod_all.txt b/src/cmd/go/testdata/script/mod_all.txt
new file mode 100644
index 0000000000..aac66292d6
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_all.txt
@@ -0,0 +1,444 @@
+# This test illustrates the relationship between the 'all' pattern and
+# the dependencies of the main module.
+
+# The package import graph used in this test looks like:
+#
+# main --------- a --------- b
+# | |
+# | a_test ---- c
+# | |
+# | c_test ---- d
+# |
+# main_test ---- t --------- u
+# |
+# t_test ---- w
+# |
+# w_test ---- x
+#
+# main/testonly_test ---- q --------- r
+# |
+# q_test ---- s
+#
+# And the module dependency graph looks like:
+#
+# main --- a.1 ---- b.1
+# \ \ \
+# \ \ c.1 -- d.1
+# \ \
+# \ t.1 ---- u.1
+# \ \
+# \ w.1 -- x.1
+# \
+# q.1 ---- r.1
+# \
+# s.1
+
+env PKGFMT='{{if .Module}}{{.ImportPath}}{{end}}'
+env MODFMT='{{.Path}}'
+
+
+# 'go list -deps' lists packages and tests in the main module,
+# along with their transitive dependencies.
+
+go list -f $PKGFMT -deps ./...
+stdout -count=4 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/main$'
+stdout '^example.com/main/testonly'
+
+
+# 'go list -deps -test' lists transitive imports of tests and non-tests in the
+# main module.
+
+go list -f $PKGFMT -deps -test ./...
+stdout -count=13 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/main$'
+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$'
+stdout '^example.com/main/testonly.test$'
+stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$'
+stdout '^example.com/q$'
+stdout '^example.com/r$'
+stdout '^example.com/t$'
+stdout '^example.com/u$'
+
+
+# 'go list all' lists the fixpoint of iterating 'go list -deps -test' starting
+# with the packages in the main module, then reducing to only the non-test
+# variants of those packages.
+
+go list -f $PKGFMT all
+stdout -count=13 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/c$'
+stdout '^example.com/d$'
+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/x$'
+
+
+# 'go list -test all' is equivalent to 'go list -test $(go list all)'
+# and both should include tests for every package in 'all'.
+
+go list -test -f $PKGFMT example.com/a example.com/b example.com/c example.com/d example.com/main example.com/main/testonly example.com/q example.com/r example.com/s example.com/t example.com/u example.com/w example.com/x
+cp stdout list-test-explicit.txt
+
+go list -test -f $PKGFMT all
+cmp stdout list-test-explicit.txt
+stdout -count=36 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/c$'
+stdout '^example.com/d$'
+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/x$'
+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/c.test$'
+stdout '^example.com/c_test \[example.com/c.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/s.test$'
+stdout '^example.com/s_test \[example.com/s.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\]$'
+stdout '^example.com/w.test$'
+stdout '^example.com/w_test \[example.com/w.test\]$'
+
+
+# 'go list -m all' covers the packages in 'go list -test -deps all'.
+
+go list -m -f $MODFMT all
+stdout -count=12 '^.'
+stdout '^example.com/a$'
+stdout '^example.com/b$'
+stdout '^example.com/c$'
+stdout '^example.com/d$'
+stdout '^example.com/main$'
+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/x$'
+
+
+# 'go mod vendor' copies in only the packages transitively imported by the main
+# module, and omits their tests. As a result, the 'all' and '...' patterns
+# report fewer packages when using '-mod=vendor'.
+
+go mod vendor
+
+go list -f $PKGFMT -mod=vendor 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 -test -f $PKGFMT -mod=vendor all
+stdout -count=13 '^.'
+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/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\]$'
+
+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' with neither -mod=vendor nor -test should
+# match -mod=vendor without -test in 1.15.
+
+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 -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
+
+go 1.15
+
+require (
+ example.com/a v0.1.0
+ example.com/b v0.1.0
+ example.com/q v0.1.0
+ example.com/t v0.1.0
+)
+
+replace (
+ example.com/a v0.1.0 => ./a
+ example.com/b v0.1.0 => ./b
+ example.com/c v0.1.0 => ./c
+ example.com/d v0.1.0 => ./d
+ example.com/q v0.1.0 => ./q
+ example.com/r v0.1.0 => ./r
+ example.com/s v0.1.0 => ./s
+ example.com/t v0.1.0 => ./t
+ example.com/u v0.1.0 => ./u
+ example.com/w v0.1.0 => ./w
+ example.com/x v0.1.0 => ./x
+)
+-- main.go --
+package main
+
+import _ "example.com/a"
+
+func main() {}
+-- main_test.go --
+package main_test
+
+import _ "example.com/t"
+-- testonly/testonly_test.go --
+package testonly_test
+
+import _ "example.com/q"
+-- a/go.mod --
+module example.com/a
+
+go 1.15
+
+require (
+ example.com/b v0.1.0
+ example.com/c v0.1.0
+)
+-- a/a.go --
+package a
+
+import _ "example.com/b"
+-- a/a_test.go --
+package a_test
+
+import _ "example.com/c"
+-- b/go.mod --
+module example.com/b
+
+go 1.15
+-- b/b.go --
+package b
+-- b/b_test.go --
+package b_test
+-- c/go.mod --
+module example.com/c
+
+go 1.15
+
+require example.com/d v0.1.0
+-- c/c.go --
+package c
+-- c/c_test.go --
+package c_test
+
+import _ "example.com/d"
+-- d/go.mod --
+module example.com/d
+
+go 1.15
+-- d/d.go --
+package d
+-- q/go.mod --
+module example.com/q
+
+go 1.15
+
+require (
+ example.com/r v0.1.0
+ example.com/s v0.1.0
+)
+-- q/q.go --
+package q
+import _ "example.com/r"
+-- q/q_test.go --
+package q_test
+import _ "example.com/s"
+-- r/go.mod --
+module example.com/r
+
+go 1.15
+-- r/r.go --
+package r
+-- r/r_test.go --
+package r_test
+-- s/go.mod --
+module example.com/s
+
+go 1.15
+-- s/s.go --
+package s
+-- s/s_test.go --
+package s_test
+-- t/go.mod --
+module example.com/t
+
+go 1.15
+
+require (
+ example.com/u v0.1.0
+ example.com/w v0.1.0
+)
+-- t/t.go --
+package t
+
+import _ "example.com/u"
+-- t/t_test.go --
+package t_test
+
+import _ "example.com/w"
+-- u/go.mod --
+module example.com/u
+
+go 1.15
+-- u/u.go --
+package u
+-- u/u_test.go --
+package u_test
+-- w/go.mod --
+module example.com/w
+
+go 1.15
+
+require example.com/x v0.1.0
+-- w/w.go --
+package w
+-- w/w_test.go --
+package w_test
+
+import _ "example.com/x"
+-- x/go.mod --
+module example.com/x
+
+go 1.15
+-- x/x.go --
+package x
diff --git a/src/cmd/go/testdata/script/mod_auth.txt b/src/cmd/go/testdata/script/mod_auth.txt
index 5bcbcd1a18..544acbc1f8 100644
--- a/src/cmd/go/testdata/script/mod_auth.txt
+++ b/src/cmd/go/testdata/script/mod_auth.txt
@@ -7,7 +7,7 @@ env GOSUMDB=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_filenames.txt b/src/cmd/go/testdata/script/mod_bad_filenames.txt
index 6e0c8bd302..eb556f4c7c 100644
--- a/src/cmd/go/testdata/script/mod_bad_filenames.txt
+++ b/src/cmd/go/testdata/script/mod_bad_filenames.txt
@@ -3,9 +3,9 @@ env GO111MODULE=on
! go get rsc.io/badfile1 rsc.io/badfile2 rsc.io/badfile3 rsc.io/badfile4 rsc.io/badfile5
! stderr 'unzip.*badfile1'
stderr 'unzip.*badfile2[\\/]@v[\\/]v1.0.0.zip:.*malformed file path "☺.go": invalid char ''☺'''
-stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: malformed file path "x\?y.go": invalid char ''\?'''
-stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: case-insensitive file name collision: "x/Y.go" and "x/y.go"'
-stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: case-insensitive file name collision: "x/y" and "x/Y"'
+stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile3@v1.0.0[\\/]x\?y.go: malformed file path "x\?y.go": invalid char ''\?'''
+stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile4@v1.0.0[\\/]x[\\/]y.go: case-insensitive file name collision: "x/Y.go" and "x/y.go"'
+stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile5@v1.0.0[\\/]x[\\/]Y[\\/]zz[\\/]ww.go: case-insensitive file name collision: "x/y" and "x/Y"'
-- go.mod --
module x
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..a6853b5c86 100644
--- a/src/cmd/go/testdata/script/mod_build_info_err.txt
+++ b/src/cmd/go/testdata/script/mod_build_info_err.txt
@@ -2,7 +2,7 @@
# 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 ''🐧'''
+stdout 'bad[/\\]bad.go:3:8: 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..6f8d869c44 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'
@@ -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_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_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_download.txt b/src/cmd/go/testdata/script/mod_download.txt
index bb5c4627db..c53bbe4567 100644
--- a/src/cmd/go/testdata/script/mod_download.txt
+++ b/src/cmd/go/testdata/script/mod_download.txt
@@ -1,13 +1,15 @@
env GO111MODULE=on
-# download with version should print nothing
+# download with version should print nothing.
+# It should not load retractions from the .mod file from the latest version.
go mod download rsc.io/quote@v1.5.0
! stdout .
! stderr .
-
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
# download of an invalid path should report the error
[short] skip
@@ -31,53 +33,59 @@ stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="'
go list -m all
! stdout rsc.io
-# add to go.mod so we can test non-query downloads
-go mod edit -require rsc.io/quote@v1.5.2
-! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
-! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
-! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
-
-# module loading will page in the info and mod files
-go list -m all
+# download query should have downloaded go.mod for the highest release version
+# in order to find retractions when resolving the query '@<=v1.5.0'.
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
+# add to go.mod so we can test non-query downloads
+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.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
+
+# module loading will page in the info and mod files
+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
+
# download will fetch and unpack the zip file
go mod download
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
-exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
+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
+exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1
# download repopulates deleted files and directories independently.
-rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info
go mod download
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
-rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
+exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod
go mod download
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
-rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
+exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip
go mod download
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
-rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
+exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip
+rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1
go mod download
-exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
+exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1
# download reports the locations of downloaded files
go mod download -json
stdout '^\t"Path": "rsc.io/quote"'
-stdout '^\t"Version": "v1.5.2"'
-stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.info"'
-stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.mod"'
-stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.zip"'
-stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.2"'
+stdout '^\t"Version": "v1.5.3-pre1"'
+stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.info"'
+stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.mod"'
+stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.zip"'
+stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.3-pre1"'
# download will follow replacements
-go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.3-pre1
+go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.2
go mod download
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip
-exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip
+exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
# download will not follow replacements for explicit module queries
go mod download -json rsc.io/quote@v1.5.1
@@ -99,6 +107,14 @@ 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'
+# 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
rm go.mod
@@ -114,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_json.txt b/src/cmd/go/testdata/script/mod_download_json.txt
index 26291681ce..9555adf8c4 100644
--- a/src/cmd/go/testdata/script/mod_download_json.txt
+++ b/src/cmd/go/testdata/script/mod_download_json.txt
@@ -3,7 +3,7 @@ env GOSUMDB=$sumdb' '$proxy/sumdb-wrong
# download -json with version should print JSON on sumdb failure
! go mod download -json 'rsc.io/quote@<=v1.5.0'
-stdout '"Error": ".*verifying module'
+stdout '"Error": ".*verifying (module|go.mod)'
-- go.mod --
module m
diff --git a/src/cmd/go/testdata/script/mod_download_partial.txt b/src/cmd/go/testdata/script/mod_download_partial.txt
index 4978982dab..8d31970160 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.
@@ -61,4 +61,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_edit.txt b/src/cmd/go/testdata/script/mod_edit.txt
index 898d8524ac..78485eb86a 100644
--- a/src/cmd/go/testdata/script/mod_edit.txt
+++ b/src/cmd/go/testdata/script/mod_edit.txt
@@ -16,15 +16,19 @@ cmpenv go.mod $WORK/go.mod.init
cmpenv go.mod $WORK/go.mod.init
# go mod edits
-go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z'
+go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
cmpenv go.mod $WORK/go.mod.edit1
-go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0
+go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
cmpenv go.mod $WORK/go.mod.edit2
# go mod edit -json
go mod edit -json
cmpenv stdout $WORK/go.mod.json
+# go mod edit -json (retractions with rationales)
+go mod edit -json $WORK/go.mod.retractrationale
+cmp stdout $WORK/go.mod.retractrationale.json
+
# go mod edit -json (empty mod file)
go mod edit -json $WORK/go.mod.empty
cmp stdout $WORK/go.mod.empty.json
@@ -40,11 +44,11 @@ cmpenv go.mod $WORK/go.mod.edit5
# go mod edit -fmt
cp $WORK/go.mod.badfmt go.mod
go mod edit -fmt -print # -print should avoid writing file
-cmpenv stdout $WORK/go.mod.edit6
+cmpenv stdout $WORK/go.mod.goodfmt
cmp go.mod $WORK/go.mod.badfmt
go mod edit -fmt # without -print, should write file (and nothing to stdout)
! stdout .
-cmpenv go.mod $WORK/go.mod.edit6
+cmpenv go.mod $WORK/go.mod.goodfmt
# go mod edit -module
cd $WORK/m
@@ -84,6 +88,13 @@ replace (
x.1 v1.3.0 => y.1 v1.4.0
x.1 v1.4.0 => ../z
)
+
+retract (
+ v1.6.0
+ [v1.3.0, v1.4.0]
+ [v1.1.0, v1.2.0]
+ v1.0.0
+)
-- $WORK/go.mod.edit2 --
module x.x/y/z
@@ -93,6 +104,11 @@ exclude x.1 v1.2.0
replace x.1 v1.4.0 => ../z
+retract (
+ v1.6.0
+ [v1.3.0, v1.4.0]
+)
+
require x.3 v1.99.0
-- $WORK/go.mod.json --
{
@@ -122,6 +138,16 @@ require x.3 v1.99.0
"Path": "../z"
}
}
+ ],
+ "Retract": [
+ {
+ "Low": "v1.6.0",
+ "High": "v1.6.0"
+ },
+ {
+ "Low": "v1.3.0",
+ "High": "v1.4.0"
+ }
]
}
-- $WORK/go.mod.edit3 --
@@ -136,6 +162,11 @@ replace (
x.1 v1.4.0 => y.1/v2 v2.3.5
)
+retract (
+ v1.6.0
+ [v1.3.0, v1.4.0]
+)
+
require x.3 v1.99.0
-- $WORK/go.mod.edit4 --
module x.x/y/z
@@ -146,6 +177,11 @@ exclude x.1 v1.2.0
replace x.1 => y.1/v2 v2.3.6
+retract (
+ v1.6.0
+ [v1.3.0, v1.4.0]
+)
+
require x.3 v1.99.0
-- $WORK/go.mod.edit5 --
module x.x/y/z
@@ -154,15 +190,10 @@ go $goversion
exclude x.1 v1.2.0
-require x.3 v1.99.0
--- $WORK/go.mod.edit6 --
-module x.x/y/z
-
-go 1.10
-
-exclude x.1 v1.2.0
-
-replace x.1 => y.1/v2 v2.3.6
+retract (
+ v1.6.0
+ [v1.3.0, v1.4.0]
+)
require x.3 v1.99.0
-- $WORK/local/go.mod.edit --
@@ -183,10 +214,64 @@ exclude x.1 v1.2.0
replace x.1 => y.1/v2 v2.3.6
require x.3 v1.99.0
+
+retract [ "v1.8.1" , "v1.8.2" ]
+-- $WORK/go.mod.goodfmt --
+module x.x/y/z
+
+go 1.10
+
+exclude x.1 v1.2.0
+
+replace x.1 => y.1/v2 v2.3.6
+
+require x.3 v1.99.0
+
+retract [v1.8.1, v1.8.2]
-- $WORK/m/go.mod.edit --
module x.x/y/z
go $goversion
+-- $WORK/go.mod.retractrationale --
+module x.x/y/z
+
+go 1.15
+
+// a
+retract v1.0.0
+
+// b
+retract (
+ v1.0.1
+ v1.0.2 // c
+)
+-- $WORK/go.mod.retractrationale.json --
+{
+ "Module": {
+ "Path": "x.x/y/z"
+ },
+ "Go": "1.15",
+ "Require": null,
+ "Exclude": null,
+ "Replace": null,
+ "Retract": [
+ {
+ "Low": "v1.0.0",
+ "High": "v1.0.0",
+ "Rationale": "a"
+ },
+ {
+ "Low": "v1.0.1",
+ "High": "v1.0.1",
+ "Rationale": "b"
+ },
+ {
+ "Low": "v1.0.2",
+ "High": "v1.0.2",
+ "Rationale": "c"
+ }
+ ]
+}
-- $WORK/go.mod.empty --
-- $WORK/go.mod.empty.json --
{
@@ -195,5 +280,6 @@ go $goversion
},
"Require": null,
"Exclude": null,
- "Replace": null
+ "Replace": null,
+ "Retract": null
}
diff --git a/src/cmd/go/testdata/script/mod_find.txt b/src/cmd/go/testdata/script/mod_find.txt
index 7fbe9fb7fe..9468acfd33 100644
--- a/src/cmd/go/testdata/script/mod_find.txt
+++ b/src/cmd/go/testdata/script/mod_find.txt
@@ -19,6 +19,11 @@ go mod init
stderr 'module example.com/x/y$'
rm go.mod
+# go mod init rejects a zero-length go.mod file
+cp $devnull go.mod # can't use touch to create it because Windows
+! go mod init
+stderr 'go.mod already exists'
+
# Module path from Godeps/Godeps.json overrides GOPATH.
cd $GOPATH/src/example.com/x/y/z
go mod init
diff --git a/src/cmd/go/testdata/script/mod_get_incompatible.txt b/src/cmd/go/testdata/script/mod_get_incompatible.txt
index b210715a5d..b28718a694 100644
--- a/src/cmd/go/testdata/script/mod_get_incompatible.txt
+++ b/src/cmd/go/testdata/script/mod_get_incompatible.txt
@@ -1,6 +1,6 @@
env GO111MODULE=on
-go list x
+go get -d x
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_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_retract.txt b/src/cmd/go/testdata/script/mod_get_retract.txt
new file mode 100644
index 0000000000..da6c25523f
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_get_retract.txt
@@ -0,0 +1,49 @@
+# 'go get pkg' should not upgrade to a retracted version.
+cp go.mod.orig go.mod
+go mod edit -require example.com/retract/self/prev@v1.1.0
+go get -d example.com/retract/self/prev
+go list -m example.com/retract/self/prev
+stdout '^example.com/retract/self/prev v1.1.0$'
+
+# 'go get pkg' should not downgrade from a retracted version when no higher
+# version is available.
+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$'
+go list -m example.com/retract/self/prev
+stdout '^example.com/retract/self/prev v1.9.0$'
+
+# 'go get pkg@latest' should downgrade from a retracted version.
+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@latest
+go list -m example.com/retract/self/prev
+stdout '^example.com/retract/self/prev v1.1.0$'
+
+# 'go get pkg@version' should update to a specific version, even if that
+# 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$'
+go list -m example.com/retract
+stdout '^example.com/retract v1.0.0-bad$'
+
+# 'go get -u' should not downgrade from a retracted version when no higher
+# 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 list -m example.com/retract/self/prev
+stdout '^example.com/retract/self/prev v1.9.0$'
+
+-- go.mod.orig --
+module example.com/use
+
+go 1.15
+
+-- use.go --
+package use
+
+import _ "example.com/retract/self/prev"
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..0d9a840e77
--- /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 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_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_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..e98ac63d48
--- /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.QueryPackage 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_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_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_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_path.txt b/src/cmd/go/testdata/script/mod_invalid_path.txt
new file mode 100644
index 0000000000..05a5133571
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_invalid_path.txt
@@ -0,0 +1,40 @@
+# Test that mod files with invalid or missing paths produce an error.
+
+# Test that go list fails on a go.mod with no module declaration.
+cd $WORK/gopath/src/mod
+! go list .
+stderr '^go: no module declaration in go.mod.\n\tRun ''go mod edit -module=example.com/mod'' to specify the module path.$'
+
+# Test that go mod init in GOPATH doesn't add a module declaration
+# with a path that can't possibly be a module path, because
+# it isn't even a valid import path.
+# The single quote and backtick are the only characters we don't allow
+# in checkModulePathLax, but is allowed in a Windows file name.
+# TODO(matloob): choose a different character once
+# module.CheckImportPath is laxened and replaces
+# checkModulePathLax.
+cd $WORK/'gopath/src/m''d'
+! go mod init
+stderr 'cannot determine module path'
+
+# Test that a go.mod file is rejected when its module declaration has a path that can't
+# possibly be a module path, because it isn't even a valid import path
+cd $WORK/gopath/src/badname
+! go list .
+stderr 'invalid module path'
+
+-- mod/go.mod --
+
+-- mod/foo.go --
+package foo
+
+-- m'd/foo.go --
+package mad
+
+-- badname/go.mod --
+
+module .\.
+
+-- badname/foo.go --
+package badname
+
diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt
index 7e1bc9ea4f..f9dfdd6346 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
@@ -18,7 +19,7 @@ cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@14c0d48ead0c
cd outside
! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0: parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
+stderr 'go: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3'
cd ..
go list -m golang.org/x/text
stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
@@ -46,7 +47,7 @@ cp go.mod.orig go.mod
go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c
cd outside
! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0: parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
+stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
cd ..
! go list -m golang.org/x/text
stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2'
diff --git a/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt
new file mode 100644
index 0000000000..4ad8cbf8ee
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt
@@ -0,0 +1,172 @@
+# This test demonstrates dependency resolution when the main module imports a
+# new package from a previously-test-only dependency.
+#
+# When lazy loading is active, the loader will not load dependencies of any
+# module whose packages are *only* imported by tests outside the main module. If
+# the main module is changed to import a package from such a module, the
+# dependencies of that module will need to be reloaded.
+
+# The import graph used in this test looks like:
+#
+# m ---- a
+# \ |
+# \ a_test ---- b/x
+# \
+# --------------b/y (new) ---- c
+#
+# Where b/x and b/y are disjoint packages, but both contained in module b.
+#
+# The module dependency graph initially looks like:
+#
+# m ---- a.1 ---- b.1 ---- c.1
+#
+# This configuration is similar to that used in mod_lazy_new_import,
+# but the new import is from what is initially a test-only dependency.
+
+# Control case: in Go 1.14, the original go.mod is tidy,
+# and the dependency on c is eagerly loaded.
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod.orig go.mod
+
+go list -m all
+stdout '^a v0.1.0 '
+stdout '^b v0.1.0 '
+stdout '^c v0.1.0 '
+
+# After adding a new import of b/y,
+# the import of c from b/y should resolve to the version required by b.
+
+cp m.go m.go.orig
+cp m.go.new m.go
+go mod tidy
+cmp go.mod.new go.mod
+
+go list -m all
+stdout '^a v0.1.0 '
+stdout '^b v0.1.0 '
+stdout '^c v0.1.0 '
+
+# With lazy loading, the go.mod requirements are the same,
+# but the dependency on c is initially pruned out.
+
+cp m.go.orig m.go
+cp go.mod.orig go.mod
+go mod edit -go=1.16
+go mod edit -go=1.16 go.mod.new
+
+cp go.mod go.mod.orig
+go mod tidy
+cmp go.mod.orig go.mod
+
+go list -m all
+stdout '^a v0.1.0 '
+stdout '^b v0.1.0 '
+stdout '^c v0.1.0 ' # TODO(#36460): This should be pruned out.
+
+# After adding a new import of b/y,
+# the import of c from b/y should again resolve to the version required by b.
+
+cp m.go.new m.go
+go mod tidy
+cmp go.mod.new go.mod
+
+go list -m all
+stdout '^a v0.1.0 '
+stdout '^b v0.1.0 '
+stdout '^c v0.1.0 '
+
+-- m.go --
+package main
+
+import (
+ "fmt"
+
+ _ "a" // a_test imports b/x.
+)
+
+func main() {
+}
+-- m.go.new --
+package main
+
+import (
+ "fmt"
+
+ _ "a" // a_test imports b/x.
+ "b/y" // This is a new import, not yet reflected in the go.mod file.
+)
+
+func main() {
+ fmt.Println(b.CVersion())
+}
+-- go.mod --
+module m
+
+go 1.14
+
+require a v0.1.0
+
+replace (
+ a v0.1.0 => ./a1
+ b v0.1.0 => ./b1
+ c v0.1.0 => ./c1
+ c v0.2.0 => ./c2
+)
+-- go.mod.new --
+module m
+
+go 1.14
+
+require (
+ a v0.1.0
+ b v0.1.0
+)
+
+replace (
+ a v0.1.0 => ./a1
+ b v0.1.0 => ./b1
+ c v0.1.0 => ./c1
+ c v0.2.0 => ./c2
+)
+-- a1/go.mod --
+module a
+
+go 1.16
+
+require b v0.1.0
+-- a1/a.go --
+package a
+-- a1/a_test.go --
+package a_test
+
+import _ "b/x"
+-- b1/go.mod --
+module b
+
+go 1.16
+
+require c v0.1.0
+-- b1/x/x.go --
+package x
+-- b1/y/y.go --
+package y
+
+import "c"
+
+func CVersion() string {
+ return c.Version
+}
+-- c1/go.mod --
+module c
+
+go 1.16
+-- c1/c.go --
+package c
+
+const Version = "v0.1.0"
+-- c2/go.mod --
+This file should be unused.
+-- c2/c.go --
+This file should be unused.
diff --git a/src/cmd/go/testdata/script/mod_lazy_new_import.txt b/src/cmd/go/testdata/script/mod_lazy_new_import.txt
new file mode 100644
index 0000000000..02935bf236
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_lazy_new_import.txt
@@ -0,0 +1,107 @@
+# This test illustrates the use of a deepening scan to resolve transitive
+# imports of imports of new packages from within existing dependencies.
+
+# The package import graph used in this test looks like:
+#
+# lazy ---- a/x ---- b
+# \
+# ---- a/y ---- c
+#
+# Where a/x and x/y are disjoint packages, but both contained in module a.
+#
+# The module dependency graph initially looks like:
+#
+# lazy ---- a.1 ---- b.1
+# \
+# c.1
+
+
+cp go.mod go.mod.old
+cp lazy.go lazy.go.old
+go mod tidy
+cmp go.mod go.mod.old
+
+# Before adding a new import, the go.mod file should
+# enumerate modules for all packages already imported.
+go list all
+cmp go.mod go.mod.old
+
+# When we add a new import of a package in an existing dependency,
+# and that dependency is already tidy, its transitive dependencies
+# should already be present.
+cp lazy.go.new lazy.go
+go list all
+go list -m all
+stdout '^example.com/c v0.1.0' # not v0.2.0 as would be be resolved by 'latest'
+cmp go.mod go.mod.old
+
+# TODO(#36460):
+cp lazy.go.old lazy.go
+cp go.mod.old go.mod
+go mod edit -go=1.16
+
+# When a new import is found, we should perform a deepening scan of the existing
+# dependencies and add a requirement on the version required by those
+# dependencies — not re-resolve 'latest'.
+
+
+-- go.mod --
+module example.com/lazy
+
+go 1.15
+
+require example.com/a v0.1.0
+
+replace (
+ example.com/a v0.1.0 => ./a
+ example.com/b v0.1.0 => ./b
+ example.com/c v0.1.0 => ./c1
+ example.com/c v0.2.0 => ./c2
+)
+-- lazy.go --
+package lazy
+
+import (
+ _ "example.com/a/x"
+)
+-- lazy.go.new --
+package lazy
+
+import (
+ _ "example.com/a/x"
+ _ "example.com/a/y"
+)
+-- a/go.mod --
+module example.com/a
+
+go 1.15
+
+require (
+ example.com/b v0.1.0
+ example.com/c v0.1.0
+)
+-- a/x/x.go --
+package x
+import _ "example.com/b"
+-- a/y/y.go --
+package y
+import _ "example.com/c"
+-- b/go.mod --
+module example.com/b
+
+go 1.15
+-- b/b.go --
+package b
+-- c1/go.mod --
+module example.com/c
+
+go 1.15
+-- c1/c.go --
+package c
+-- c2/go.mod --
+module example.com/c
+
+go 1.15
+-- c2/c.go --
+package c
+This file should not be used, so this syntax error should be ignored.
diff --git a/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt
new file mode 100644
index 0000000000..9cdfad79f6
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt
@@ -0,0 +1,131 @@
+# This file demonstrates the effect of lazy loading on the selected
+# versions of test dependencies.
+
+# The package import graph used in this test looks like:
+#
+# m ---- a
+# \ |
+# \ a_test ---- b
+# \ |
+# x b_test
+# | \
+# x_test -------------- c
+#
+# And the module dependency graph looks like:
+#
+# m -- a.1 -- b.1 -- c.2
+# \
+# x.1 ------------ c.1
+
+# Control case: in Go 1.15, the version of c imported by 'go test x' is the
+# version required by module b, even though b_test is not relevant to the main
+# module. (The main module imports a, and a_test imports b, but all of the
+# packages and tests in the main module can be built without b.)
+
+go list -m c
+stdout '^c v0.2.0 '
+
+[!short] go test -v x
+[!short] stdout ' c v0.2.0$'
+
+# With lazy loading, the go.mod requirements are the same,
+# but the irrelevant dependency on c v0.2.0 should be pruned out,
+# leaving only the relevant dependency on c v0.1.0.
+
+go mod edit -go=1.16
+go list -m c
+stdout '^c v0.2.0' # TODO(#36460): v0.1.0
+
+[!short] go test -v x
+[!short] stdout ' c v0.2.0$' # TODO(#36460): v0.1.0
+
+-- m.go --
+package m
+
+import (
+ _ "a"
+ _ "x"
+)
+-- go.mod --
+module m
+
+go 1.15
+
+require (
+ a v0.1.0
+ x v0.1.0
+)
+
+replace (
+ a v0.1.0 => ./a1
+ b v0.1.0 => ./b1
+ c v0.1.0 => ./c1
+ c v0.2.0 => ./c2
+ x v0.1.0 => ./x1
+)
+-- a1/go.mod --
+module a
+
+go 1.16
+
+require b v0.1.0
+-- a1/a.go --
+package a
+-- a1/a_test.go --
+package a_test
+
+import _ "b"
+-- b1/go.mod --
+module b
+
+go 1.16
+
+require c v0.2.0
+-- b1/b.go --
+package b
+-- b1/b_test.go --
+package b_test
+
+import (
+ "c"
+ "testing"
+)
+
+func TestCVersion(t *testing.T) {
+ t.Log(c.Version)
+}
+-- c1/go.mod --
+module c
+
+go 1.16
+-- c1/c.go --
+package c
+
+const Version = "v0.1.0"
+-- c2/go.mod --
+module c
+
+go 1.16
+-- c2/c.go --
+package c
+
+const Version = "v0.2.0"
+-- x1/go.mod --
+module x
+
+go 1.16
+
+require c v0.1.0
+-- x1/x.go --
+package x
+-- x1/x_test.go --
+package x_test
+
+import (
+ "c"
+ "testing"
+)
+
+func TestCVersion(t *testing.T) {
+ t.Log("c", c.Version)
+}
diff --git a/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt
new file mode 100644
index 0000000000..ca6c55040e
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt
@@ -0,0 +1,145 @@
+# This file demonstrates the effect of lazy loading on the reproducibility of
+# tests (and tests of test dependencies) outside the main module.
+#
+# It is similar to the cases in mod_all.txt and mod_lazy_test_horizon.txt, but
+# focuses on the effect of "go test" on specific packages instead of the "all"
+# pattern.
+
+# The package import graph used in this test looks like:
+#
+# lazy ---- a
+# |
+# a_test ---- b
+# |
+# b_test ---- c
+#
+# And the non-lazy module dependency graph looks like:
+#
+# lazy ---- a.1 ---- b.1 ---- c.1
+
+cp go.mod go.mod.old
+go mod tidy
+cmp go.mod go.mod.old
+
+# In Go 1.15 mode, 'go list -m all' includes modules needed by the
+# transitive closure of tests of dependencies of tests of dependencies of ….
+
+go list -m all
+stdout 'example.com/b v0.1.0'
+stdout 'example.com/c v0.1.0'
+cmp go.mod go.mod.old
+
+# 'go test' (or equivalent) of any such dependency, no matter how remote, does
+# not update the go.mod file.
+
+go list -test -deps example.com/a
+stdout example.com/b
+! stdout example.com/c
+
+[!short] go test -c example.com/a
+[!short] cmp go.mod go.mod.old
+
+go list -test -deps example.com/b
+stdout example.com/c
+
+[!short] go test -c example.com/b
+[!short] cmp go.mod go.mod.old
+
+# TODO(#36460):
+
+# After changing to 'go 1.16` uniformly, 'go list -m all' should prune out
+# example.com/c, because it is not imported by any package (or test of a package)
+# transitively imported by the main module.
+#
+# example.com/a is imported,
+# and example.com/b is needed in order to run 'go test example.com/a',
+# but example.com/c is not needed because we don't expect the user to need to run
+# 'go test example.com/b'.
+
+# If we skip directly to adding a new import of c, the dependency is too far
+# away for a deepening scan to find, which is fine because the package whose
+# test imported it wasn't even it "all". It should resolve from the latest
+# version of its module.
+
+# However, if we reach c by running successive tests starting from the main
+# module, we should end up with exactly the version require by c, with an update
+# to the go.mod file as soon as we test a test dependency that is not itself in
+# "all".
+
+-- go.mod --
+module example.com/lazy
+
+go 1.15
+
+require example.com/a v0.1.0
+
+replace (
+ example.com/a v0.1.0 => ./a
+ example.com/b v0.1.0 => ./b1
+ example.com/b v0.2.0 => ./b2
+ example.com/c v0.1.0 => ./c1
+ example.com/c v0.2.0 => ./c2
+)
+-- 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
+
+import (
+ "testing"
+
+ _ "example.com/b"
+)
+
+func TestUsingB(t *testing.T) {
+ // …
+}
+-- 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
+
+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
+This file should not be used, so this syntax error should be ignored.
+-- b2/b_test.go --
+package b
+This file should not be used, so this syntax error should be ignored.
+-- c1/go.mod --
+module example.com/c
+
+go 1.15
+-- c1/c.go --
+package c
+-- c2/go.mod --
+module example.com/c
+
+go 1.15
+-- c2/c.go --
+package c
+This file should not be used, so this syntax error should be ignored.
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..b3e2fff67d 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,10 +29,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 -e -deps should succeed.
+go list -e -deps example.com/indirect
stdout example.com/notfound
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_pseudo.txt b/src/cmd/go/testdata/script/mod_list_pseudo.txt
index 3a10b3a040..056c093128 100644
--- a/src/cmd/go/testdata/script/mod_list_pseudo.txt
+++ b/src/cmd/go/testdata/script/mod_list_pseudo.txt
@@ -10,30 +10,25 @@ go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha
go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e
cmp $GOPATH/pkg/mod/cache/download/github.com/dmitshur-test/modtest5/@v/list $WORK/modtest5.list
+env GOSUMDB=off # don't verify go.mod files when loading retractions
env GOPROXY=file:///$GOPATH/pkg/mod/cache/download
env GOPATH=$WORK/gopath2
mkdir $GOPATH
-go list -m -json github.com/dmitshur-test/modtest5@latest
-cmp stdout $WORK/modtest5.json
+go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' github.com/dmitshur-test/modtest5@latest
+stdout '^github.com/dmitshur-test/modtest5 v0.5.0-alpha 2019-06-18$'
# If the module proxy contains only pseudo-versions, 'latest' should stat
# the version with the most recent timestamp — not the highest semantic
# version — and return its metadata.
env GOPROXY=file:///$WORK/tinyproxy
-go list -m -json dmitri.shuralyov.com/test/modtest3@latest
-cmp stdout $WORK/modtest3.json
+go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' dmitri.shuralyov.com/test/modtest3@latest
+stdout '^dmitri.shuralyov.com/test/modtest3 v0.0.0-20181023043359-a85b471d5412 2018-10-22$'
-- $WORK/modtest5.list --
v0.0.0-20190619020302-197a620e0c9a
v0.5.0-alpha
v0.5.0-alpha.0.20190619023908-3da23a9deb9e
--- $WORK/modtest5.json --
-{
- "Path": "github.com/dmitshur-test/modtest5",
- "Version": "v0.5.0-alpha",
- "Time": "2019-06-18T19:04:46-07:00"
-}
-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/list --
v0.1.0-0.20161023043300-000000000000
v0.0.0-20181023043359-a85b471d5412
@@ -42,9 +37,3 @@ v0.0.0-20181023043359-a85b471d5412
"Version": "v0.0.0-20181023043359-a85b471d5412",
"Time": "2018-10-22T21:33:59-07:00"
}
--- $WORK/modtest3.json --
-{
- "Path": "dmitri.shuralyov.com/test/modtest3",
- "Version": "v0.0.0-20181023043359-a85b471d5412",
- "Time": "2018-10-22T21:33:59-07:00"
-}
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
new file mode 100644
index 0000000000..4e177b3f54
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_list_retract.txt
@@ -0,0 +1,108 @@
+# 'go list -mod=vendor -retracted' reports an error.
+go mod vendor
+! go list -m -retracted -mod=vendor
+stderr '^go list -retracted cannot be used when vendoring is enabled$'
+rm vendor
+
+# 'go list -retracted' reports an error in GOPATH mode.
+env GO111MODULE=off
+! go list -retracted
+stderr '^go list -retracted can only be used in module-aware mode$'
+env GO111MODULE=
+
+# 'go list pkg' does not show retraction.
+go list -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract
+! stdout .
+
+# 'go list -retracted pkg' shows retraction.
+go list -retracted -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract
+stdout retracted
+
+# 'go list -m' does not show retraction.
+go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract
+! stdout .
+
+# 'go list -m -retracted' shows retraction.
+go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract
+
+# 'go list -m mod@version' does not show retraction.
+go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused
+! stdout .
+
+# '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$'
+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$'
+
+# 'go list -m -retracted mod@version' shows retractions.
+go list -m -retracted example.com/retract@v1.0.0-unused
+stdout '^example.com/retract v1.0.0-unused \(retracted\)$'
+go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused
+stdout retracted
+
+# 'go list -m mod@latest' selects a previous release version, not self-retracted latest.
+go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest
+stdout '^v1.1.0$'
+
+# 'go list -m -retracted mod@latest' selects the self-retracted latest version.
+go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest
+stdout '^v1.9.0 retracted$'
+
+# 'go list -m mod@latest' selects a pre-release version if all release versions are retracted.
+go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest
+stdout '^v1.9.1-pre$'
+
+# 'go list -m -retracted mod@latest' selects the self-retracted latest version.
+go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest
+stdout '^v1.9.0 retracted$'
+
+# 'go list -m mod@latest' selects a pseudo-version if all versions are retracted.
+# TODO(golang.org/issue/24031): the proxy does not expose the pseudo-version,
+# even if all release versions are retracted.
+go list -m -e -f '{{.Error.Err}}' example.com/retract/self/pseudo@latest
+stdout '^module example.com/retract/self/pseudo: no matching versions for query "latest"$'
+
+# 'go list -m mod@latest' reports an error if all versions are retracted.
+go list -m -e -f '{{.Error.Err}}' example.com/retract/self/all@latest
+stdout '^module example.com/retract/self/all: no matching versions for query "latest"$'
+
+# 'go list -m mod@<v1.10' selects a previous release version, not self-retracted latest.
+# The @latest query is not special with respect to retractions.
+go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@<v1.10
+stdout '^v1.1.0$'
+
+# 'go list -m -versions' hides retracted versions.
+go list -m -versions example.com/retract
+stdout '^example.com/retract v1.0.0-good v1.1.0$'
+
+# 'go list -m -retracted -versions' shows retracted versions.
+go list -m -retracted -versions example.com/retract
+stdout '^example.com/retract v1.0.0-bad v1.0.0-good v1.0.0-unused v1.1.0$'
+
+# 'go list -m -u -versions' loads retractions and does not show retracted versions.
+go list -m -u -versions example.com/retract
+stdout '^example.com/retract v1.0.0-good v1.1.0$'
+go list -m -u -versions -f '{{with .Retracted}}retracted{{end}}' example.com/retract
+stdout retracted
+
+# 'go list -m -u' shows retraction.
+go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract
+stdout retracted
+
+# 'go list -m -u' does not suggest an update to a self-retracted latest version.
+go list -m -u -f '{{with .Update}}{{.Version}}{{with .Retracted}} retracted{{end}}{{end}}' example.com/retract/self/prev@v1.0.0-bad
+stdout '^v1.1.0$'
+
+-- go.mod --
+module example.com/use
+
+go 1.15
+
+require example.com/retract v1.0.0-bad
+
+-- use.go --
+package use
+
+import _ "example.com/retract"
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_test.txt b/src/cmd/go/testdata/script/mod_list_test.txt
index a99e4f36cd..f697af6c92 100644
--- a/src/cmd/go/testdata/script/mod_list_test.txt
+++ b/src/cmd/go/testdata/script/mod_list_test.txt
@@ -3,9 +3,19 @@ env GO111MODULE=on
# go list -compiled -test must handle test-only packages
# golang.org/issue/27097.
go list -compiled -test
+stdout -count=4 '^.' # 4 lines
stdout '^m$'
stdout '^m\.test$'
stdout '^m \[m\.test\]$'
+stdout '^m_test \[m\.test\]$'
+
+# https://golang.org/issue/39974: test packages should have the Module field populated.
+go list -test -f '{{.ImportPath}}{{with .Module}}: {{.Path}}{{end}}'
+stdout -count=4 '^.' # 4 lines
+stdout '^m: m$'
+stdout '^m\.test: m$'
+stdout '^m \[m\.test\]: m$'
+stdout '^m_test \[m\.test\]: m$'
-- go.mod --
module m
@@ -14,3 +24,7 @@ module m
package x
import "testing"
func Test(t *testing.T) {}
+-- x_x_test.go --
+package x_test
+import "testing"
+func Test(t *testing.T) {}
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..e943179c54 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 --
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 74dbb34b8a..067e209b01 100644
--- a/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt
+++ b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt
@@ -18,6 +18,6 @@ package use
import _ "rsc.io/quote"
-- want --
-go: example.com/quote@v1.5.2: parsing go.mod:
+go: rsc.io/quote@v1.5.2 (replaced by example.com/quote@v1.5.2): parsing go.mod:
module declares its path as: rsc.io/Quote
but was required as: rsc.io/quote
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..d9e9fdec21 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).
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
new file mode 100644
index 0000000000..1657c8d2d0
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_notall.txt
@@ -0,0 +1,99 @@
+# This test demonstrates go commands that combine the 'all' pattern
+# with packages outside of 'all'.
+
+# With -deps, 'all' should include test dependencies of packages in the main
+# 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
+
+stdout '^x/inall$'
+stdout '^x/inall/fromtest$'
+stdout '^x/inall/fromtestinall$'
+stdout '^x/otherroot$'
+stdout '^x/otherdep$'
+
+! stdout '^x/fromotherroottest$'
+! stdout '^y/fromotherdeptest$'
+
+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.
+
+go list -deps -test all x/otherroot
+stdout '^x/inall$'
+stdout '^x/inall/fromtest$'
+stdout '^x/inall/fromtestinall$'
+stdout '^x/otherroot$'
+stdout '^x/otherdep$'
+
+stdout '^x/fromotherroottest$'
+! stdout '^y/fromotherdeptest$'
+
+cmp go.mod go.mod.orig
+
+-- m.go --
+package m
+
+import _ "x/inall"
+-- m_test.go --
+package m_test
+
+import _ "x/inall/fromtest"
+-- go.mod --
+module m
+
+go 1.15
+
+require x v0.1.0
+
+replace (
+ x v0.1.0 => ./x
+ y v0.1.0 => ./y
+)
+-- x/go.mod --
+module x
+
+go 1.15
+-- x/inall/inall.go --
+package inall
+-- x/inall/inall_test.go --
+package inall_test
+
+import _ "x/inall/fromtestinall"
+-- x/inall/fromtest/fromtest.go --
+package fromtest
+-- x/inall/fromtestinall/fromtestinall.go --
+package fromtestinall
+-- x/otherroot/otherroot.go --
+package otherroot
+
+import _ "x/otherdep"
+-- x/otherroot/otherroot_test.go --
+package otherroot_test
+
+import _ "x/fromotherroottest"
+-- x/fromotherroottest/fromotherroottest.go --
+package fromotherroottest
+-- x/otherdep/otherdep.go --
+package otherdep
+-- x/otherdep/otherdep_test.go --
+package otherdep_test
+
+import _ "y/fromotherdeptest"
+-- x/otherroot/testonly/testonly.go --
+package testonly
+-- y/go.mod --
+module y
+
+go 1.15
+-- y/fromotherdeptest/fromotherdeptest.go --
+// Package fromotherdeptest is a test dependency of x/otherdep that is
+// not declared in x/go.mod. If the loader resolves this package,
+// it will add this module to the main module's go.mod file,
+// and we can detect the mistake.
+package fromotherdeptest
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_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_exclude.txt b/src/cmd/go/testdata/script/mod_query_exclude.txt
index a64a8e1086..742c6f17e3 100644
--- a/src/cmd/go/testdata/script/mod_query_exclude.txt
+++ b/src/cmd/go/testdata/script/mod_query_exclude.txt
@@ -1,23 +1,43 @@
env GO111MODULE=on
+# list excluded version
+go list -modfile=go.exclude.mod -m rsc.io/quote@v1.5.0
+stdout '^rsc.io/quote v1.5.0$'
+
+# list versions should not print excluded versions
+go list -m -versions rsc.io/quote
+stdout '\bv1.5.0\b'
+go list -modfile=go.exclude.mod -m -versions rsc.io/quote
+! stdout '\bv1.5.0\b'
+
+# list query with excluded version
+go list -m rsc.io/quote@>=v1.5
+stdout '^rsc.io/quote v1.5.0$'
+go list -modfile=go.exclude.mod -m rsc.io/quote@>=v1.5
+stdout '^rsc.io/quote v1.5.1$'
+
# get excluded version
-cp go.mod1 go.mod
-! go get rsc.io/quote@v1.5.0
-stderr 'rsc.io/quote@v1.5.0 excluded'
+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$'
# get non-excluded version
-cp go.mod1 go.mod
-go get rsc.io/quote@v1.5.1
+cp go.exclude.mod.orig go.exclude.mod
+go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.1
stderr 'rsc.io/quote v1.5.1'
-# get range with excluded version
-cp go.mod1 go.mod
-go get rsc.io/quote@>=v1.5
-go list -m ...quote
+# get query with excluded version
+cp go.exclude.mod.orig go.exclude.mod
+go get -modfile=go.exclude.mod -d rsc.io/quote@>=v1.5
+go list -modfile=go.exclude.mod -m ...quote
stdout 'rsc.io/quote v1.5.[1-9]'
--- go.mod1 --
+-- go.mod --
module x
+
+-- go.exclude.mod --
+module x
+
exclude rsc.io/quote v1.5.0
-- x.go --
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 28c1196284..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
@@ -34,7 +35,7 @@ go list -m gopkg.in/src-d/go-git.v4
# A mismatched gopkg.in path should not be able to replace a different major version.
cd ../3-to-gomod-4
! go list -m gopkg.in/src-d/go-git.v3
-stderr '^go: gopkg\.in/src-d/go-git\.v3@v3.0.0-20190801152248-0d1a009cbb60: invalid version: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
+stderr '^go: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$'
-- 4-to-4/go.mod --
module golang.org/issue/34254
diff --git a/src/cmd/go/testdata/script/mod_replace_import.txt b/src/cmd/go/testdata/script/mod_replace_import.txt
index 54b1a12448..b4de5c50f7 100644
--- a/src/cmd/go/testdata/script/mod_replace_import.txt
+++ b/src/cmd/go/testdata/script/mod_replace_import.txt
@@ -7,6 +7,7 @@ cp go.mod go.mod.orig
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$'
diff --git a/src/cmd/go/testdata/script/mod_require_exclude.txt b/src/cmd/go/testdata/script/mod_require_exclude.txt
index 60f7e3fa91..9156d4ce5d 100644
--- a/src/cmd/go/testdata/script/mod_require_exclude.txt
+++ b/src/cmd/go/testdata/script/mod_require_exclude.txt
@@ -1,16 +1,51 @@
# build with no newer version to satisfy exclude
env GO111MODULE=on
-! go list -m all
-stderr 'no newer version available'
+cp go.mod go.mod.orig
+
+# With the selected version excluded, commands that query that version without
+# updating go.mod should fail.
+
+! go list -mod=readonly -m all
+stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$'
+stderr '^go: updates to go.mod needed, disabled by -mod=readonly$'
+! stdout '^rsc.io/sampler v1.99.99'
+cmp go.mod go.mod.orig
+
+! go list -mod=vendor -m rsc.io/sampler
+stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$'
+stderr '^go list -m: module rsc.io/sampler: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass\.\)$'
+! stdout '^rsc.io/sampler v1.99.99'
+cmp go.mod go.mod.orig
+
+# With the selected version excluded, commands that load only modules should
+# drop the excluded module.
+
+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'
+cmp go.mod go.moddrop
+
+# With the latest version excluded, 'go list' should resolve needed packages
+# from the next-highest version.
+
+cp go.mod.orig go.mod
+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'
+stdout '^rsc.io/sampler v1.3.0'
# build with newer version available
cp go.mod2 go.mod
-go list -m 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 -m all
+go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all
+! stderr '^go: dropping requirement'
stdout 'rsc.io/quote v1.5.1'
-- x.go --
@@ -19,15 +54,28 @@ import _ "rsc.io/quote"
-- go.mod --
module x
-exclude rsc.io/sampler latest
-require rsc.io/sampler latest
+go 1.13
+
+exclude rsc.io/sampler v1.99.99
+require rsc.io/sampler v1.99.99
+-- go.moddrop --
+module x
+
+go 1.13
+
+exclude rsc.io/sampler v1.99.99
-- go.mod2 --
module x
+
+go 1.13
+
exclude rsc.io/quote v1.5.1
require rsc.io/quote v1.5.1
-
-- go.mod3 --
module x
+
+go 1.13
+
exclude rsc.io/quote v1.5.2
require 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
new file mode 100644
index 0000000000..a52e05bc72
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_retract.txt
@@ -0,0 +1,43 @@
+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 .
+cmp go.mod go.mod.orig
+
+# Nor does 'go build'.
+[!short] go build ./use
+[!short] ! stderr .
+[!short] cmp go.mod go.mod.orig
+
+# Neither 'go list' nor 'go build' should download go.mod from the version
+# that would list retractions.
+exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.0.0-bad.mod
+! exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.1.0.mod
+
+# Importing a package from a module with a retracted latest version will
+# select the latest non-retracted version.
+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
+
+-- go.mod --
+module example.com/use
+
+go 1.15
+
+require example.com/retract v1.0.0-bad
+
+-- use/use.go --
+package use
+
+import _ "example.com/retract"
+
+-- use_self_prev/use.go --
+package use_self_prev
+
+import _ "example.com/retract/self/prev"
diff --git a/src/cmd/go/testdata/script/mod_retract_rationale.txt b/src/cmd/go/testdata/script/mod_retract_rationale.txt
new file mode 100644
index 0000000000..584c3a3849
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_retract_rationale.txt
@@ -0,0 +1,79 @@
+# 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$'
+
+# 'go list' should print the same hard-coded message.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
+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 'detail'
+
+# 'go list' should show the full message.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
+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 'detail'
+
+# Same for 'go list'.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
+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\)'
+
+# 'go list' should show the full message.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
+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\)'
+
+# 'go list' should show the full message.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale
+stdout '^\[Ends with a BEL character. Beep!\x07\]$'
+
+
+# When there is a comment on a block, but not on individual retractions within
+# the block, the rationale should come from the block comment.
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-block
+stdout '^\[block comment\]$'
+go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-blockwithcomment
+stdout '^\[inner comment\]$'
+
+
+# When a version is covered by multiple retractions, all retractions should
+# be reported in the order they appear in the file.
+go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.0-order
+stdout '^degenerate range,single version,$'
+go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.1-order
+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$'
+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$'
+
+-- go.mod --
+module m
+
+go 1.14
+
+-- multiline --
+[short description
+more
+
+detail
+suffix]
diff --git a/src/cmd/go/testdata/script/mod_retract_replace.txt b/src/cmd/go/testdata/script/mod_retract_replace.txt
new file mode 100644
index 0000000000..7aec438dda
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_retract_replace.txt
@@ -0,0 +1,61 @@
+# 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$'
+
+# If we replace that version, we should see retractions.
+go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0
+go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract/missingmod
+stdout '^bad version$'
+
+# If we replace the retracted version, we should not see a retraction.
+go mod edit -replace=example.com/retract/missingmod=./missingmod-v1.9.0
+go list -m -retracted -f '{{if not .Retracted}}good version{{end}}' example.com/retract/missingmod
+stdout '^good version$'
+
+
+# If a replacement version is retracted, we should see a retraction.
+# It should appear in both the replaced module and the replacement, as other
+# fields like GoMod do.
+go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract
+! stdout .
+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 -mod=mod -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract
+stdout '^bad$'
+go list -m -mod=mod -retracted -f '{{with .Replace}}{{range .Retracted}}{{.}}{{end}}{{end}}' example.com/retract
+stdout '^bad$'
+
+-- go.mod --
+module m
+
+go 1.14
+
+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
+
+go 1.14
+-- missingmod-v1.9.0/go.mod --
+module example.com/retract/missingmod
+
+go 1.14
+
+// bad version
+retract v1.0.0
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_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_sumdb.txt b/src/cmd/go/testdata/script/mod_sumdb.txt
index caf97e9699..68bbd9c274 100644
--- a/src/cmd/go/testdata/script/mod_sumdb.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb.txt
@@ -15,6 +15,12 @@ stderr 'localhost.localdev/sumdb: h1:wrong'
stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.'
! go get -d rsc.io/sampler
! go get -d golang.org/x/text
+
+go mod edit -require rsc.io/quote@v1.5.2
+! go list all
+stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch'
+stderr 'SECURITY ERROR\n'
+
rm go.sum
# switching to truthful sumdb detects timeline inconsistency
diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
index 40a07fc7e9..cc0b0da474 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
@@ -9,7 +9,7 @@ env GOPROXY=https://proxy.golang.org
go env GOSUMDB
stdout '^sum.golang.org$'
-# download direct from github
+# Download direct from github.
[!net] skip
[!exec:git] skip
env GOSUMDB=sum.golang.org
@@ -17,11 +17,13 @@ env GOPROXY=direct
go get -d rsc.io/quote@v1.5.2
cp go.sum saved.sum
-# download from proxy.golang.org with go.sum entry already
+# Download from proxy.golang.org with go.sum entry already.
+# Use 'go list' instead of 'go get' since the latter may download extra go.mod
+# files not listed in go.sum.
go clean -modcache
env GOSUMDB=
env GOPROXY=
-go get -x -d rsc.io/quote@v1.5.2
+go list -x -deps rsc.io/quote
! stderr github
stderr proxy.golang.org/rsc.io/quote
! stderr sum.golang.org/tile
@@ -32,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 get -x -d rsc.io/quote@v1.5.2
+go list -mod=mod -x rsc.io/quote
! stderr github
! stderr proxy.golang.org/rsc.io/quote
stderr sum.golang.org/tile
@@ -43,7 +45,7 @@ cmp go.sum saved.sum
env TESTGOPROXY404=1
go clean -modcache
rm go.sum
-go get -x -d rsc.io/quote@v1.5.2
+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_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_symlink_dotgo.txt b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt
new file mode 100644
index 0000000000..d4cc143a36
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt
@@ -0,0 +1,17 @@
+env GO111MODULE=on
+[!symlink] skip
+
+symlink dir.go -> dir
+
+# Issue #39841: symlinks to directories should be ignored, not treated as source files.
+go list -f '{{range .GoFiles}}{{.}}{{"\n"}}{{end}}' .
+stdout 'p\.go$'
+! stdout 'dir\.go$'
+
+-- go.mod --
+module example.com
+go 1.15
+-- p.go --
+package p
+-- dir/README.txt --
+This file exists to ensure that dir is a directory.
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_tidy_replace.txt b/src/cmd/go/testdata/script/mod_tidy_replace.txt
index c3158f8610..7b00bf1384 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
diff --git a/src/cmd/go/testdata/script/mod_upgrade_patch.txt b/src/cmd/go/testdata/script/mod_upgrade_patch.txt
index 3939e54c1b..1ef25b9aef 100644
--- a/src/cmd/go/testdata/script/mod_upgrade_patch.txt
+++ b/src/cmd/go/testdata/script/mod_upgrade_patch.txt
@@ -2,6 +2,7 @@ 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'
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_build.txt b/src/cmd/go/testdata/script/mod_vendor_build.txt
index 0c359cea6e..4efda55e08 100644
--- a/src/cmd/go/testdata/script/mod_vendor_build.txt
+++ b/src/cmd/go/testdata/script/mod_vendor_build.txt
@@ -1,6 +1,9 @@
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
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..c0ff4647a7 100644
--- a/src/cmd/go/testdata/script/mod_why.txt
+++ b/src/cmd/go/testdata/script/mod_why.txt
@@ -1,6 +1,9 @@
env GO111MODULE=on
[short] skip
+# Populate go.sum.
+go mod tidy
+
go list -test all
stdout rsc.io/quote
stdout golang.org/x/text/language
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/test_example_goexit.txt b/src/cmd/go/testdata/script/test_example_goexit.txt
new file mode 100644
index 0000000000..59219e3366
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_example_goexit.txt
@@ -0,0 +1,25 @@
+# For issue golang.org/issue/41084
+[short] skip
+
+! go test -v examplegoexit
+stdout '(?s)--- PASS.*--- FAIL.*'
+stdout 'panic: test executed panic\(nil\) or runtime\.Goexit'
+
+-- examplegoexit/example_test.go --
+package main
+
+import (
+ "fmt"
+ "runtime"
+)
+
+func ExamplePass() {
+ fmt.Println("pass")
+ // Output:
+ // pass
+}
+
+func ExampleGoexit() {
+ runtime.Goexit()
+ // Output:
+}
diff --git a/src/cmd/go/testdata/script/test_exit.txt b/src/cmd/go/testdata/script/test_exit.txt
new file mode 100644
index 0000000000..23a2429d1e
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_exit.txt
@@ -0,0 +1,114 @@
+# Builds and runs test binaries, so skip in short mode.
+[short] skip
+
+env GO111MODULE=on
+
+# If a test invoked by 'go test' exits with a zero status code,
+# it will panic.
+! go test ./zero
+! stdout ^ok
+! stdout 'exit status'
+stdout 'panic'
+stdout ^FAIL
+
+# If a test exits with a non-zero status code, 'go test' fails normally.
+! go test ./one
+! stdout ^ok
+stdout 'exit status'
+! stdout 'panic'
+stdout ^FAIL
+
+# Ensure that other flags still do the right thing.
+go test -list=. ./zero
+stdout ExitZero
+
+! go test -bench=. ./zero
+stdout 'panic'
+
+# 'go test' with no args streams output without buffering. Ensure that it still
+# catches a zero exit with missing output.
+cd zero
+! go test
+stdout 'panic'
+cd ../normal
+go test
+stdout ^ok
+cd ..
+
+# If a TestMain exits with a zero status code, 'go test' shouldn't
+# complain about that. It's a common way to skip testing a package
+# entirely.
+go test ./main_zero
+! stdout 'skipping all tests'
+stdout ^ok
+
+# With -v, we'll see the warning from TestMain.
+go test -v ./main_zero
+stdout 'skipping all tests'
+stdout ^ok
+
+# Listing all tests won't actually give a result if TestMain exits. That's okay,
+# because this is how TestMain works. If we decide to support -list even when
+# TestMain is used to skip entire packages, we can change this test case.
+go test -list=. ./main_zero
+stdout 'skipping all tests'
+! stdout TestNotListed
+
+-- go.mod --
+module m
+
+-- ./normal/normal.go --
+package normal
+-- ./normal/normal_test.go --
+package normal
+
+import "testing"
+
+func TestExitZero(t *testing.T) {
+}
+
+-- ./zero/zero.go --
+package zero
+-- ./zero/zero_test.go --
+package zero
+
+import (
+ "os"
+ "testing"
+)
+
+func TestExitZero(t *testing.T) {
+ os.Exit(0)
+}
+
+-- ./one/one.go --
+package one
+-- ./one/one_test.go --
+package one
+
+import (
+ "os"
+ "testing"
+)
+
+func TestExitOne(t *testing.T) {
+ os.Exit(1)
+}
+
+-- ./main_zero/zero.go --
+package zero
+-- ./main_zero/zero_test.go --
+package zero
+
+import (
+ "fmt"
+ "os"
+ "testing"
+)
+
+func TestMain(m *testing.M) {
+ fmt.Println("skipping all tests")
+ os.Exit(0)
+}
+
+func TestNotListed(t *testing.T) {}
diff --git a/src/cmd/go/testdata/script/testing_issue40908.txt b/src/cmd/go/testdata/script/testing_issue40908.txt
new file mode 100644
index 0000000000..4939de080c
--- /dev/null
+++ b/src/cmd/go/testdata/script/testing_issue40908.txt
@@ -0,0 +1,21 @@
+[short] skip
+[!race] skip
+
+go test -race testrace
+
+-- testrace/race_test.go --
+package testrace
+
+import "testing"
+
+func TestRace(t *testing.T) {
+ helperDone := make(chan struct{})
+ go func() {
+ t.Logf("Something happened before cleanup.")
+ close(helperDone)
+ }()
+
+ t.Cleanup(func() {
+ <-helperDone
+ })
+}
diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt
index 0123ac6d53..81ca698620 100644
--- a/src/cmd/go/testdata/script/version.txt
+++ b/src/cmd/go/testdata/script/version.txt
@@ -14,6 +14,7 @@ env GO111MODULE=on
[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/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go
index 5d4a253024..8ec7c481d6 100644
--- a/src/cmd/internal/goobj/objfile.go
+++ b/src/cmd/internal/goobj/objfile.go
@@ -2,7 +2,19 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Go new object file format, reading and writing.
+// This package defines the Go object file format, and provide "low-level" functions
+// for reading and writing object files.
+
+// The object file is understood by the compiler, assembler, linker, and tools. They
+// have "high level" code that operates on object files, handling application-specific
+// logics, and use this package for the actual reading and writing. Specifically, the
+// code below:
+//
+// - cmd/internal/obj/objfile.go (used by cmd/asm and cmd/compile)
+// - cmd/internal/objfile/goobj.go (used cmd/nm, cmd/objdump)
+// - cmd/link/internal/loader package (used by cmd/link)
+//
+// If the object file format changes, they may (or may not) need to change.
package goobj
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index 7b7e42ee2e..269a4223d5 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -644,7 +644,7 @@ func (c *ctxt5) flushpool(p *obj.Prog, skip int, force int) bool {
q := c.newprog()
q.As = AB
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Link
+ q.To.SetTarget(p.Link)
q.Link = c.blitrl
q.Pos = p.Pos
c.blitrl = q
@@ -705,7 +705,7 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
if t.Rel == nil {
for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
if q.Rel == nil && q.To == t.To {
- p.Pcond = q
+ p.Pool = q
return
}
}
@@ -724,8 +724,8 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
c.elitrl = q
c.pool.size += 4
- // Store the link to the pool entry in Pcond.
- p.Pcond = q
+ // Store the link to the pool entry in Pool.
+ p.Pool = q
}
func (c *ctxt5) regoff(a *obj.Addr) int32 {
@@ -1584,8 +1584,8 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
break
}
- if p.Pcond != nil {
- v = int32((p.Pcond.Pc - c.pc) - 8)
+ if p.To.Target() != nil {
+ v = int32((p.To.Target().Pc - c.pc) - 8)
}
o1 |= (uint32(v) >> 2) & 0xffffff
@@ -3023,7 +3023,7 @@ func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
var o1 uint32
- if p.Pcond == nil {
+ if p.Pool == nil {
c.aclass(a)
v := immrot(^uint32(c.instoffset))
if v == 0 {
@@ -3035,7 +3035,7 @@ func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
o1 |= uint32(v)
o1 |= (uint32(dr) & 15) << 12
} else {
- v := int32(p.Pcond.Pc - p.Pc - 8)
+ v := int32(p.Pool.Pc - p.Pc - 8)
o1 = c.olr(v, REGPC, dr, int(p.Scond)&C_SCOND)
}
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index 86831f2b44..4d9187b530 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
mov.To.Reg = REG_R2
// B.NE branch target is MOVW above
- bne.Pcond = mov
+ bne.To.SetTarget(mov)
// ADD $(autosize+4), R13, R3
p = obj.Appendp(mov, newprog)
@@ -428,7 +428,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p = obj.Appendp(p, newprog)
p.As = ABNE
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = end
+ p.To.SetTarget(end)
// ADD $4, R13, R4
p = obj.Appendp(p, newprog)
@@ -452,7 +452,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p = obj.Appendp(p, newprog)
p.As = AB
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = end
+ p.To.SetTarget(end)
// reset for subsequent passes
p = end
@@ -741,7 +741,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
movw.To.Type = obj.TYPE_REG
movw.To.Reg = REG_R3
- bls.Pcond = movw
+ bls.To.SetTarget(movw)
// BL runtime.morestack
call := obj.Appendp(movw, c.newprog)
@@ -762,7 +762,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.Pcond = 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..2839da1437 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -874,6 +874,7 @@ const (
AFLDPS
AFMOVD
AFMOVS
+ AFMOVQ
AFMULD
AFMULS
AFNEGD
@@ -953,6 +954,7 @@ const (
AVADD
AVADDP
AVAND
+ AVBIF
AVCMEQ
AVCNT
AVEOR
@@ -985,11 +987,20 @@ const (
AVEXT
AVRBIT
AVUSHR
+ AVUSHLL
+ AVUSHLL2
+ AVUXTL
+ AVUXTL2
+ AVUZP1
+ AVUZP2
AVSHL
AVSRI
+ AVBSL
+ AVBIT
AVTBL
AVZIP1
AVZIP2
+ AVCMTST
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..48c066abfd 100644
--- a/src/cmd/internal/obj/arm64/anames.go
+++ b/src/cmd/internal/obj/arm64/anames.go
@@ -381,6 +381,7 @@ var Anames = []string{
"FLDPS",
"FMOVD",
"FMOVS",
+ "FMOVQ",
"FMULD",
"FMULS",
"FNEGD",
@@ -460,6 +461,7 @@ var Anames = []string{
"VADD",
"VADDP",
"VAND",
+ "VBIF",
"VCMEQ",
"VCNT",
"VEOR",
@@ -492,10 +494,19 @@ var Anames = []string{
"VEXT",
"VRBIT",
"VUSHR",
+ "VUSHLL",
+ "VUSHLL2",
+ "VUXTL",
+ "VUXTL2",
+ "VUZP1",
+ "VUZP2",
"VSHL",
"VSRI",
+ "VBSL",
+ "VBIT",
"VTBL",
"VZIP1",
"VZIP2",
+ "VCMTST",
"LAST",
}
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 7a5a8ff38c..df4bbbbd35 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -393,6 +393,11 @@ var optab = []Optab{
{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},
+ // Move a large constant to a Vn.
+ {AFMOVQ, C_VCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0},
+ {AFMOVD, C_VCON, C_NONE, C_NONE, C_VREG, 101, 4, 0, LFROM, 0},
+ {AFMOVS, 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},
{ABL, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
@@ -403,12 +408,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 +480,8 @@ 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},
/* conditional operations */
{ACSEL, C_COND, C_REG, C_REG, C_REG, 18, 4, 0, 0, 0},
@@ -977,8 +986,8 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
o = c.oplook(p)
/* very large branches */
- if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
- otxt := p.Pcond.Pc - pc
+ if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.To.Target() != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
+ otxt := p.To.Target().Pc - pc
var toofar bool
switch o.type_ {
case 7, 39: // branch instruction encodes 19 bits
@@ -992,14 +1001,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p.Link = q
q.As = AB
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Pcond
- p.Pcond = q
+ q.To.SetTarget(p.To.Target())
+ p.To.SetTarget(q)
q = c.newprog()
q.Link = p.Link
p.Link = q
q.As = AB
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = q.Link.Link
+ q.To.SetTarget(q.Link.Link)
bflag = 1
}
}
@@ -1123,7 +1132,7 @@ func (c *ctxt7) flushpool(p *obj.Prog, skip int) {
q := c.newprog()
q.As = AB
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Link
+ q.To.SetTarget(p.Link)
q.Link = c.blitrl
q.Pos = p.Pos
c.blitrl = q
@@ -1249,7 +1258,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
if q.To == t.To {
- p.Pcond = q
+ p.Pool = q
return
}
}
@@ -1266,7 +1275,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
c.elitrl = q
c.pool.size = -c.pool.size & (funcAlign - 1)
c.pool.size += uint32(sz)
- p.Pcond = q
+ p.Pool = q
}
func (c *ctxt7) regoff(a *obj.Addr) uint32 {
@@ -2657,7 +2666,7 @@ func buildop(ctxt *obj.Link) {
case AFCSELD:
oprangeset(AFCSELS, t)
- case AFMOVS, AFMOVD:
+ case AFMOVS, AFMOVD, AFMOVQ:
break
case AFCVTZSD:
@@ -2740,6 +2749,12 @@ 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)
@@ -2787,6 +2802,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)
@@ -2898,6 +2919,7 @@ func (c *ctxt7) checkoffset(p *obj.Prog, as obj.As) {
}
opcode := (list >> 12) & 15
q := (list >> 30) & 1
+ size := (list >> 10) & 3
if offset == 0 {
return
}
@@ -2913,8 +2935,16 @@ func (c *ctxt7) checkoffset(p *obj.Prog, as obj.As) {
default:
c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
}
- if !(q == 0 && offset == n*8) && !(q == 1 && offset == n*16) {
- c.ctxt.Diag("invalid post-increment offset: %v", p)
+
+ switch as {
+ case AVLD1R, AVLD2R, AVLD3R, AVLD4R:
+ if offset != n*(1<<uint(size)) {
+ c.ctxt.Diag("invalid post-increment offset: %v", p)
+ }
+ default:
+ if !(q == 0 && offset == n*8) && !(q == 1 && offset == n*16) {
+ c.ctxt.Diag("invalid post-increment offset: %v", p)
+ }
}
switch as {
@@ -4154,7 +4184,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 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)
@@ -4195,17 +4225,24 @@ 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 {
@@ -4801,7 +4838,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
Q = 1
b = 15
} else {
- c.ctxt.Diag("invalid arrangement, should be 8B or 16B: %v", p)
+ c.ctxt.Diag("invalid arrangement, should be B8 or B16: %v", p)
break
}
@@ -5087,6 +5124,47 @@ 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: // FOMVQ/FMOVD $vcon, 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
+ }
+
+ pack := func(q, x, y uint8) uint32 {
+ return uint32(q)<<16 | uint32(x)<<8 | uint32(y)
+ }
+
+ var Q uint8 = uint8(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)
}
out[0] = o1
out[1] = o2
@@ -5653,6 +5731,9 @@ 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
@@ -5715,6 +5796,24 @@ 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
}
c.ctxt.Diag("%v: bad rrr %d %v", p, a, a)
@@ -5913,6 +6012,12 @@ func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
case AVSRI:
return 0x5E<<23 | 17<<10
+
+ case AVUSHLL, AVUXTL:
+ return 1<<29 | 15<<24 | 0x29<<10
+
+ case AVUSHLL2, AVUXTL2:
+ return 3<<29 | 15<<24 | 0x29<<10
}
c.ctxt.Diag("%v: bad irr %v", p, a)
@@ -6042,15 +6147,21 @@ func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
v := int64(0)
t := int64(0)
- if p.Pcond != nil {
- v = (p.Pcond.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
+ q := p.To.Target()
+ if q == nil {
+ // TODO: don't use brdist for this case, as it isn't a branch.
+ // (Calls from omovlit, and maybe adr/adrp opcodes as well.)
+ q = p.Pool
+ }
+ if q != nil {
+ v = (q.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
if (v & ((1 << uint(shift)) - 1)) != 0 {
c.ctxt.Diag("misaligned label\n%v", p)
}
v >>= uint(shift)
t = int64(1) << uint(flen-1)
if v < -t || v >= t {
- c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, p.Pcond)
+ c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, q)
panic("branch too far")
}
}
@@ -6526,7 +6637,7 @@ func (c *ctxt7) oaddi(p *obj.Prog, o1 int32, v int32, r int, rt int) uint32 {
*/
func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
var o1 int32
- if p.Pcond == nil { /* not in literal pool */
+ if p.Pool == nil { /* not in literal pool */
c.aclass(a)
c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
@@ -6551,12 +6662,16 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
fp = 1
w = 1 /* 64-bit SIMD/FP */
+ case AFMOVQ:
+ fp = 1
+ w = 2 /* 128-bit SIMD/FP */
+
case AMOVD:
- if p.Pcond.As == ADWORD {
+ if p.Pool.As == ADWORD {
w = 1 /* 64-bit */
- } else if p.Pcond.To.Offset < 0 {
+ } else if p.Pool.To.Offset < 0 {
w = 2 /* 32-bit, sign-extended to 64-bit */
- } else if p.Pcond.To.Offset >= 0 {
+ } else if p.Pool.To.Offset >= 0 {
w = 0 /* 32-bit, zero-extended to 64-bit */
} else {
c.ctxt.Diag("invalid operand %v in %v", a, p)
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 0d74430053..56da854f16 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -187,9 +187,9 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
movlr.To.Type = obj.TYPE_REG
movlr.To.Reg = REG_R3
if q != nil {
- q.Pcond = movlr
+ q.To.SetTarget(movlr)
}
- bls.Pcond = movlr
+ bls.To.SetTarget(movlr)
debug := movlr
if false {
@@ -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.Pcond = c.cursym.Func.Text.Link
+ jmp.To.SetTarget(c.cursym.Func.Text.Link)
jmp.Spadj = +framesize
return end
@@ -621,7 +621,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd)
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
q1 = obj.Appendp(q1, c.newprog)
q1.Pos = p.Pos
q1.As = AMOVD
@@ -697,7 +697,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
mov.To.Reg = REG_R2
// CBNZ branches to the MOV above
- cbnz.Pcond = mov
+ cbnz.To.SetTarget(mov)
// ADD $(autosize+8), SP, R3
q = obj.Appendp(mov, c.newprog)
@@ -719,7 +719,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q = obj.Appendp(q, c.newprog)
q.As = ABNE
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = end
+ q.To.SetTarget(end)
// ADD $8, SP, R4
q = obj.Appendp(q, c.newprog)
@@ -743,7 +743,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q = obj.Appendp(q, c.newprog)
q.As = AB
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = end
+ q.To.SetTarget(end)
}
case obj.ARET:
@@ -764,7 +764,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p.To.Reg = REGSP
p.Spadj = -c.autosize
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
p = obj.Appendp(p, c.newprog)
p.As = ASUB
p.From.Type = obj.TYPE_CONST
@@ -777,7 +777,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
} else {
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGSP
@@ -865,7 +865,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
case obj.ADUFFCOPY:
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
// ADR ret_addr, R27
// STP (FP, R27), -24(SP)
// SUB 24, SP, FP
@@ -913,12 +913,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q5.Reg = REGSP
q5.To.Type = obj.TYPE_REG
q5.To.Reg = REGFP
- q1.Pcond = q5
+ q1.From.SetTarget(q5)
p = q5
}
case obj.ADUFFZERO:
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
+ if objabi.Framepointer_enabled {
// ADR ret_addr, R27
// STP (FP, R27), -24(SP)
// SUB 24, SP, FP
@@ -966,7 +966,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q5.Reg = REGSP
q5.To.Type = obj.TYPE_REG
q5.To.Reg = REGFP
- q1.Pcond = q5
+ q1.From.SetTarget(q5)
p = q5
}
}
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 311e5ae2e8..1d4217b5f5 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -237,6 +237,19 @@ const (
TYPE_REGLIST
)
+func (a *Addr) Target() *Prog {
+ if a.Type == TYPE_BRANCH && a.Val != nil {
+ return a.Val.(*Prog)
+ }
+ return nil
+}
+func (a *Addr) SetTarget(t *Prog) {
+ if a.Type != TYPE_BRANCH {
+ panic("setting branch target when type is not TYPE_BRANCH")
+ }
+ a.Val = t
+}
+
// Prog describes a single machine instruction.
//
// The general instruction form is:
@@ -255,7 +268,7 @@ const (
// to avoid too much changes in a single swing.
// (1) scheme is enough to express any kind of operand combination.
//
-// Jump instructions use the Pcond field to point to the target instruction,
+// Jump instructions use the To.Val field to point to the target *Prog,
// which must be in the same linked list as the jump instruction.
//
// The Progs for a given function are arranged in a list linked through the Link field.
@@ -274,7 +287,7 @@ type Prog struct {
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)
- Pcond *Prog // target of conditional jump
+ 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
@@ -682,10 +695,9 @@ type Link struct {
GenAbstractFunc func(fn *LSym)
Errors int
- InParallel bool // parallel backend phase in effect
- Framepointer_enabled bool
- UseBASEntries bool // use Base Address Selection Entries in location lists and PC ranges
- IsAsm bool // is the source assembly language, which may contain surprising idioms (e.g., call tables)
+ InParallel bool // parallel backend phase in effect
+ UseBASEntries bool // use Base Address Selection Entries in location lists and PC ranges
+ IsAsm bool // is the source assembly language, which may contain surprising idioms (e.g., call tables)
// state for writing objects
Text []*LSym
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index faa827da9f..6107974745 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -460,8 +460,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
o = c.oplook(p)
// very large conditional branches
- if o.type_ == 6 && p.Pcond != nil {
- otxt = p.Pcond.Pc - pc
+ if o.type_ == 6 && p.To.Target() != nil {
+ otxt = p.To.Target().Pc - pc
if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
q = c.newprog()
q.Link = p.Link
@@ -469,15 +469,15 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q.As = AJMP
q.Pos = p.Pos
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Pcond
- p.Pcond = q
+ q.To.SetTarget(p.To.Target())
+ p.To.SetTarget(q)
q = c.newprog()
q.Link = p.Link
p.Link = q
q.As = AJMP
q.Pos = p.Pos
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = q.Link.Link
+ q.To.SetTarget(q.Link.Link)
c.addnop(p.Link)
c.addnop(p)
@@ -1230,10 +1230,10 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 6: /* beq r1,[r2],sbra */
v := int32(0)
- if p.Pcond == nil {
+ if p.To.Target() == nil {
v = int32(-4) >> 2
} else {
- v = int32(p.Pcond.Pc-p.Pc-4) >> 2
+ v = int32(p.To.Target().Pc-p.Pc-4) >> 2
}
if (v<<16)>>16 != v {
c.ctxt.Diag("short branch too far\n%v", p)
@@ -1285,25 +1285,25 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
// use PC-relative branch for short branches
// BEQ R0, R0, sbra
- if p.Pcond == nil {
+ if p.To.Target() == nil {
v = int32(-4) >> 2
} else {
- v = int32(p.Pcond.Pc-p.Pc-4) >> 2
+ v = int32(p.To.Target().Pc-p.Pc-4) >> 2
}
if (v<<16)>>16 == v {
o1 = OP_IRR(c.opirr(ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO))
break
}
}
- if p.Pcond == nil {
+ if p.To.Target() == nil {
v = int32(p.Pc) >> 2
} else {
- v = int32(p.Pcond.Pc) >> 2
+ v = int32(p.To.Target().Pc) >> 2
}
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.Offset = p.Pcond.Pc
+ p.To.Offset = p.To.Target().Pc
}
rel := obj.Addrel(c.cursym)
rel.Off = int32(c.pc)
diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go
index 77cad979a6..f19facc00c 100644
--- a/src/cmd/internal/obj/mips/obj0.go
+++ b/src/cmd/internal/obj/mips/obj0.go
@@ -227,11 +227,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
} else {
p.Mark |= BRANCH
}
- q1 := p.Pcond
+ q1 := p.To.Target()
if q1 != nil {
for q1.As == obj.ANOP {
q1 = q1.Link
- p.Pcond = q1
+ p.To.SetTarget(q1)
}
if q1.Mark&LEAF == 0 {
@@ -424,8 +424,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q = obj.Appendp(q, newprog)
q.As = obj.ANOP
- p1.Pcond = q
- p2.Pcond = q
+ p1.To.SetTarget(q)
+ p2.To.SetTarget(q)
}
case ARET:
@@ -778,7 +778,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
if q != nil {
- q.Pcond = p
+ q.To.SetTarget(p)
p.Mark |= LABEL
}
@@ -805,14 +805,14 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.As = AJMP
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = c.cursym.Func.Text.Link
+ p.To.SetTarget(c.cursym.Func.Text.Link)
p.Mark |= BRANCH
// placeholder for q1's jump target
p = obj.Appendp(p, c.newprog)
p.As = obj.ANOP // zero-width place holder
- q1.Pcond = p
+ q1.To.SetTarget(p)
return p
}
diff --git a/src/cmd/internal/obj/pass.go b/src/cmd/internal/obj/pass.go
index 4f156d969b..09d520b4e9 100644
--- a/src/cmd/internal/obj/pass.go
+++ b/src/cmd/internal/obj/pass.go
@@ -36,8 +36,8 @@ package obj
// In the case of an infinite loop, brloop returns nil.
func brloop(p *Prog) *Prog {
c := 0
- for q := p; q != nil; q = q.Pcond {
- if q.As != AJMP || q.Pcond == nil {
+ for q := p; q != nil; q = q.To.Target() {
+ if q.As != AJMP || q.To.Target() == nil {
return q
}
c++
@@ -132,8 +132,6 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
continue
}
if p.To.Val != nil {
- // TODO: Remove To.Val.(*Prog) in favor of p->pcond.
- p.Pcond = p.To.Val.(*Prog)
continue
}
@@ -158,8 +156,7 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
p.To.Type = TYPE_NONE
}
- p.To.Val = q
- p.Pcond = q
+ p.To.SetTarget(q)
}
if !ctxt.Flag_optimize {
@@ -168,12 +165,12 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
// Collapse series of jumps to jumps.
for p := sym.Func.Text; p != nil; p = p.Link {
- if p.Pcond == nil {
+ if p.To.Target() == nil {
continue
}
- p.Pcond = brloop(p.Pcond)
- if p.Pcond != nil && p.To.Type == TYPE_BRANCH {
- p.To.Offset = p.Pcond.Pc
+ p.To.SetTarget(brloop(p.To.Target()))
+ if p.To.Target() != nil && p.To.Type == TYPE_BRANCH {
+ p.To.Offset = p.To.Target().Pc
}
}
}
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index 3c82477fc4..98b453de6c 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -725,22 +725,22 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
o = c.oplook(p)
// very large conditional branches
- if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
- otxt = p.Pcond.Pc - pc
+ if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
+ otxt = p.To.Target().Pc - pc
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
q = c.newprog()
q.Link = p.Link
p.Link = q
q.As = ABR
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = p.Pcond
- p.Pcond = q
+ q.To.SetTarget(p.To.Target())
+ p.To.SetTarget(q)
q = c.newprog()
q.Link = p.Link
p.Link = q
q.As = ABR
q.To.Type = obj.TYPE_BRANCH
- q.Pcond = q.Link.Link
+ q.To.SetTarget(q.Link.Link)
//addnop(p->link);
//addnop(p);
@@ -2630,8 +2630,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 11: /* br/bl lbra */
v := int32(0)
- if p.Pcond != nil {
- v = int32(p.Pcond.Pc - p.Pc)
+ if p.To.Target() != nil {
+ v = int32(p.To.Target().Pc - p.Pc)
if v&03 != 0 {
c.ctxt.Diag("odd branch target address\n%v", p)
v &^= 03
@@ -2781,8 +2781,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
}
}
v := int32(0)
- if p.Pcond != nil {
- v = int32(p.Pcond.Pc - p.Pc)
+ if p.To.Target() != nil {
+ v = int32(p.To.Target().Pc - p.Pc)
}
if v&03 != 0 {
c.ctxt.Diag("odd branch target address\n%v", p)
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index 749f7066de..c012762a18 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -556,7 +556,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
ABVS:
p.Mark |= BRANCH
q = p
- q1 = p.Pcond
+ q1 = p.To.Target()
if q1 != nil {
// NOPs are not removed due to #40689.
@@ -841,8 +841,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q = obj.Appendp(q, c.newprog)
q.As = obj.ANOP
- p1.Pcond = q
- p2.Pcond = q
+ p1.To.SetTarget(q)
+ p2.To.SetTarget(q)
}
case obj.ARET:
@@ -1153,7 +1153,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R5
if q != nil {
- q.Pcond = p
+ q.To.SetTarget(p)
}
p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog)
@@ -1248,13 +1248,13 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p = obj.Appendp(p, c.newprog)
p.As = ABR
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = p0.Link
+ p.To.SetTarget(p0.Link)
// placeholder for q1's jump target
p = obj.Appendp(p, c.newprog)
p.As = obj.ANOP // zero-width place holder
- q1.Pcond = p
+ q1.To.SetTarget(p)
return p
}
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 2eb2935b31..77d383b290 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -634,7 +634,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
getargp.Reg = 0
getargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12}
- bneadj.Pcond = getargp
+ bneadj.To.SetTarget(getargp)
calcargp := obj.Appendp(getargp, newprog)
calcargp.As = AADDI
@@ -647,7 +647,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
testargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12}
testargp.Reg = REG_X13
testargp.To.Type = obj.TYPE_BRANCH
- testargp.Pcond = endadj
+ testargp.To.SetTarget(endadj)
adjargp := obj.Appendp(testargp, newprog)
adjargp.As = AADDI
@@ -665,7 +665,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
godone.As = AJAL
godone.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
godone.To.Type = obj.TYPE_BRANCH
- godone.Pcond = endadj
+ godone.To.SetTarget(endadj)
}
// Update stack-based offsets.
@@ -890,27 +890,27 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
if p.To.Type != obj.TYPE_BRANCH {
panic("assemble: instruction with branch-like opcode lacks destination")
}
- offset := p.Pcond.Pc - p.Pc
+ offset := p.To.Target().Pc - p.Pc
if offset < -4096 || 4096 <= offset {
// Branch is long. Replace it with a jump.
jmp := obj.Appendp(p, newprog)
jmp.As = AJAL
jmp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
jmp.To = obj.Addr{Type: obj.TYPE_BRANCH}
- jmp.Pcond = p.Pcond
+ jmp.To.SetTarget(p.To.Target())
p.As = InvertBranch(p.As)
- p.Pcond = jmp.Link
+ p.To.SetTarget(jmp.Link)
// We may have made previous branches too long,
// so recheck them.
rescan = true
}
case AJAL:
- if p.Pcond == nil {
+ if p.To.Target() == nil {
panic("intersymbol jumps should be expressed as AUIPC+JALR")
}
- offset := p.Pcond.Pc - p.Pc
+ offset := p.To.Target().Pc - p.Pc
if offset < -(1<<20) || (1<<20) <= offset {
// Replace with 2-instruction sequence. This assumes
// that TMP is not live across J instructions, since
@@ -925,6 +925,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
// fixed up in the next loop.
p.As = AAUIPC
p.From = obj.Addr{Type: obj.TYPE_BRANCH, Sym: p.From.Sym}
+ p.From.SetTarget(p.To.Target())
p.Reg = 0
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
@@ -946,16 +947,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ, AJAL:
switch p.To.Type {
case obj.TYPE_BRANCH:
- p.To.Type, p.To.Offset = obj.TYPE_CONST, p.Pcond.Pc-p.Pc
+ p.To.Type, p.To.Offset = obj.TYPE_CONST, p.To.Target().Pc-p.Pc
case obj.TYPE_MEM:
panic("unhandled type")
}
case AAUIPC:
if p.From.Type == obj.TYPE_BRANCH {
- low, high, err := Split32BitImmediate(p.Pcond.Pc - p.Pc)
+ low, high, err := Split32BitImmediate(p.From.Target().Pc - p.Pc)
if err != nil {
- ctxt.Diag("%v: jump displacement %d too large", p, p.Pcond.Pc-p.Pc)
+ ctxt.Diag("%v: jump displacement %d too large", p, p.To.Target().Pc-p.Pc)
}
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high, Sym: cursym}
p.Link.From.Offset = low
@@ -1098,7 +1099,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
p.To.Sym = ctxt.Lookup("runtime.morestack")
}
if to_more != nil {
- to_more.Pcond = p
+ to_more.To.SetTarget(p)
}
p = jalrToSym(ctxt, p, newprog, REG_X5)
@@ -1107,12 +1108,12 @@ 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.Pcond = cursym.Func.Text.Link
+ p.To.SetTarget(cursym.Func.Text.Link)
// placeholder for to_done's jump target
p = obj.Appendp(p, newprog)
p.As = obj.ANOP // zero-width place holder
- to_done.Pcond = p
+ to_done.To.SetTarget(p)
return p
}
diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
index 29182ea805..68f01f1c5d 100644
--- a/src/cmd/internal/obj/s390x/asmz.go
+++ b/src/cmd/internal/obj/s390x/asmz.go
@@ -3001,8 +3001,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
case 11: // br/bl
v := int32(0)
- if p.Pcond != nil {
- v = int32((p.Pcond.Pc - p.Pc) >> 1)
+ if p.To.Target() != nil {
+ v = int32((p.To.Target().Pc - p.Pc) >> 1)
}
if p.As == ABR && p.To.Sym == nil && int32(int16(v)) == v {
@@ -3122,8 +3122,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
case 16: // conditional branch
v := int32(0)
- if p.Pcond != nil {
- v = int32((p.Pcond.Pc - p.Pc) >> 1)
+ if p.To.Target() != nil {
+ v = int32((p.To.Target().Pc - p.Pc) >> 1)
}
mask := uint32(c.branchMask(p))
if p.To.Sym == nil && int32(int16(v)) == v {
@@ -3440,7 +3440,7 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
case 41: // branch on count
r1 := p.From.Reg
- ri2 := (p.Pcond.Pc - p.Pc) >> 1
+ ri2 := (p.To.Target().Pc - p.Pc) >> 1
if int64(int16(ri2)) != ri2 {
c.ctxt.Diag("branch target too far away")
}
@@ -3885,8 +3885,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
case 89: // compare and branch reg reg
var v int32
- if p.Pcond != nil {
- v = int32((p.Pcond.Pc - p.Pc) >> 1)
+ if p.To.Target() != nil {
+ v = int32((p.To.Target().Pc - p.Pc) >> 1)
}
// Some instructions take a mask as the first argument.
@@ -3930,8 +3930,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
case 90: // compare and branch reg $constant
var v int32
- if p.Pcond != nil {
- v = int32((p.Pcond.Pc - p.Pc) >> 1)
+ if p.To.Target() != nil {
+ v = int32((p.To.Target().Pc - p.Pc) >> 1)
}
// Some instructions take a mask as the first argument.
diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go
index ef6335d849..625bb0f7b4 100644
--- a/src/cmd/internal/obj/s390x/objz.go
+++ b/src/cmd/internal/obj/s390x/objz.go
@@ -454,8 +454,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q = obj.Appendp(q, c.newprog)
q.As = obj.ANOP
- p1.Pcond = q
- p2.Pcond = q
+ p1.To.SetTarget(q)
+ p2.To.SetTarget(q)
}
case obj.ARET:
@@ -679,14 +679,14 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
// MOVD LR, R5
p = obj.Appendp(pcdata, c.newprog)
- pPre.Pcond = p
+ pPre.To.SetTarget(p)
p.As = AMOVD
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_LR
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R5
if pPreempt != nil {
- pPreempt.Pcond = p
+ pPreempt.To.SetTarget(p)
}
// BL runtime.morestack(SB)
@@ -709,7 +709,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
p.As = ABR
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = c.cursym.Func.Text.Link
+ p.To.SetTarget(c.cursym.Func.Text.Link)
return p
}
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 34f61b7f62..d58877ee15 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -53,7 +53,6 @@ func Linknew(arch *LinkArch) *Link {
}
ctxt.Flag_optimize = true
- ctxt.Framepointer_enabled = objabi.Framepointer_enabled(objabi.GOOS, arch.Name)
return ctxt
}
diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go
index d020026445..a30ccf0564 100644
--- a/src/cmd/internal/obj/util.go
+++ b/src/cmd/internal/obj/util.go
@@ -251,10 +251,8 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) {
case TYPE_BRANCH:
if a.Sym != nil {
fmt.Fprintf(w, "%s(SB)", a.Sym.Name)
- } else if p != nil && p.Pcond != nil {
- fmt.Fprint(w, p.Pcond.Pc)
- } else if a.Val != nil {
- fmt.Fprint(w, a.Val.(*Prog).Pc)
+ } else if a.Target() != nil {
+ fmt.Fprint(w, a.Target().Pc)
} else {
fmt.Fprintf(w, "%d(PC)", a.Offset)
}
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index 82a2e6adc4..fb99c620ad 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -1855,7 +1855,7 @@ func spadjop(ctxt *obj.Link, l, q obj.As) obj.As {
// 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.Pcond != nil || p.As == obj.AJMP || p.As == obj.ACALL ||
+ 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
}
@@ -1867,7 +1867,7 @@ func lookForJCC(p *obj.Prog) *obj.Prog {
for q = p.Link; q != nil && (q.As == obj.APCDATA || q.As == obj.AFUNCDATA || q.As == obj.ANOP); q = q.Link {
}
- if q == nil || q.Pcond == nil || p.As == obj.AJMP || p.As == obj.ACALL {
+ if q == nil || q.To.Target() == nil || p.As == obj.AJMP || p.As == obj.ACALL {
return nil
}
@@ -2051,8 +2051,8 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
}
for p := s.Func.Text; p != nil; p = p.Link {
- if p.To.Type == obj.TYPE_BRANCH && p.Pcond == nil {
- p.Pcond = p
+ if p.To.Type == obj.TYPE_BRANCH && p.To.Target() == nil {
+ p.To.SetTarget(p)
}
if p.As == AADJSP {
p.To.Type = obj.TYPE_REG
@@ -2088,7 +2088,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
for p := s.Func.Text; p != nil; p = p.Link {
count++
p.Back = branchShort // use short branches first time through
- if q := p.Pcond; q != nil && (q.Back&branchShort != 0) {
+ if q := p.To.Target(); q != nil && (q.Back&branchShort != 0) {
p.Back |= branchBackwards
q.Back |= branchLoopHead
}
@@ -4833,12 +4833,12 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ctxt.Diag("directly calling duff when dynamically linking Go")
}
- if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
+ if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
// Maintain BP around call, since duffcopy/duffzero can't do it
// (the call jumps into the middle of the function).
// This makes it possible to see call sites for duffcopy/duffzero in
// BP-based profiling tools like Linux perf (which is the
- // whole point of obj.Framepointer_enabled).
+ // whole point of maintaining frame pointers in Go).
// MOVQ BP, -16(SP)
// LEAQ -16(SP), BP
ab.Put(bpduff1)
@@ -4852,7 +4852,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
r.Siz = 4
ab.PutInt32(0)
- if ctxt.Framepointer_enabled && yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
+ if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
// Pop BP pushed above.
// MOVQ 0(BP), BP
ab.Put(bpduff2)
@@ -4886,7 +4886,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
// TODO: Check in input, preserve in brchain.
// Fill in backward jump now.
- q = p.Pcond
+ q = p.To.Target()
if q == nil {
ctxt.Diag("jmp/branch/loop without target")
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index c1e5bea055..18a6afcd77 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -582,7 +582,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
var bpsize int
- if ctxt.Arch.Family == sys.AMD64 && ctxt.Framepointer_enabled &&
+ if ctxt.Arch.Family == sys.AMD64 &&
!p.From.Sym.NoFrame() && // (1) below
!(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below
!(autoffset == 0 && !hasCall) { // (3) below
@@ -765,7 +765,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
// Set jne branch target.
- jne.Pcond = p
+ jne.To.SetTarget(p)
// CMPQ panic_argp(BX), DI
p = obj.Appendp(p, newprog)
@@ -783,7 +783,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p = obj.Appendp(p, newprog)
p.As = AJNE
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = end
+ p.To.SetTarget(end)
// MOVQ SP, panic_argp(BX)
p = obj.Appendp(p, newprog)
@@ -801,7 +801,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p = obj.Appendp(p, newprog)
p.As = obj.AJMP
p.To.Type = obj.TYPE_BRANCH
- p.Pcond = end
+ p.To.SetTarget(end)
// Reset p for following code.
p = end
@@ -1144,12 +1144,12 @@ 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.Pcond = cursym.Func.Text.Link
+ jmp.To.SetTarget(cursym.Func.Text.Link)
jmp.Spadj = +framesize
- jls.Pcond = call
+ jls.To.SetTarget(call)
if q1 != nil {
- q1.Pcond = call
+ q1.To.SetTarget(call)
}
return end
diff --git a/src/cmd/internal/objabi/doc.go b/src/cmd/internal/objabi/doc.go
deleted file mode 100644
index 08e922b11f..0000000000
--- a/src/cmd/internal/objabi/doc.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 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.
-
-// NOTE: There are *three* independent implementations of this object
-// file format in the Go source tree:
-//
-// - cmd/internal/goobj/read.go (used by cmd/addr2line, cmd/nm, cmd/objdump, cmd/pprof)
-// - cmd/internal/obj/objfile.go (used by cmd/asm and cmd/compile)
-// - cmd/link/internal/objfile.go (used by cmd/link)
-//
-// When changing the object file format, remember to change all three.
-
-// Originally, Go object files were Plan 9 object files, but no longer.
-// Now they are more like standard object files, in that each symbol is defined
-// by an associated memory image (bytes) and a list of relocations to apply
-// during linking. We do not (yet?) use a standard file format, however.
-// For now, the format is chosen to be as simple as possible to read and write.
-// It may change for reasons of efficiency, or we may even switch to a
-// standard file format if there are compelling benefits to doing so.
-// See golang.org/s/go13linker for more background.
-//
-// The file format is:
-//
-// - magic header: "\x00go114ld"
-// - byte 1 - version number
-// - sequence of strings giving dependencies (imported packages)
-// - empty string (marks end of sequence)
-// - number of entries in the following sequence
-// - sequence of filename strings to generate debug information
-// - sequence of symbol references used by the defined symbols
-// - byte 0xff (marks end of sequence)
-// - sequence of integer lengths:
-// - total data length
-// - total number of relocations
-// - total number of pcdata
-// - total number of automatics
-// - total number of funcdata
-// - total number of files
-// - data, the content of the defined symbols
-// - sequence of defined symbols
-// - byte 0xff (marks end of sequence)
-// - magic footer: "\xffgo114ld"
-//
-// All integers are stored in a zigzag varint format.
-// See golang.org/s/go12symtab for a definition.
-//
-// Data blocks and strings are both stored as an integer
-// followed by that many bytes.
-//
-// A symbol reference is a string name followed by an ABI or -1 for static.
-//
-// A symbol points to other symbols using an index into the symbol
-// reference sequence. Index 0 corresponds to a nil symbol pointer.
-// In the symbol layout described below "symref index" stands for this
-// index.
-//
-// Each symbol is laid out as the following fields:
-//
-// - byte 0xfe (sanity check for synchronization)
-// - type [byte]
-// - name & ABI [symref index]
-// - flags [int]
-// 1<<0 dupok
-// 1<<1 local
-// 1<<2 add to typelink table
-// - size [int]
-// - gotype [symref index]
-// - p [data block]
-// - nr [int]
-// - r [nr relocations, sorted by off]
-//
-// If type == STEXT, there are a few more fields:
-//
-// - args [int]
-// - locals [int]
-// - nosplit [int]
-// - flags [int]
-// 1<<0 leaf
-// 1<<1 C function
-// 1<<2 function may call reflect.Type.Method
-// 1<<3 function compiled with -shared
-// - nlocal [int]
-// - local [nlocal automatics]
-// - pcln [pcln table]
-//
-// Each relocation has the encoding:
-//
-// - off [int]
-// - siz [int]
-// - type [int]
-// - add [int]
-// - sym [symref index]
-//
-// Each local has the encoding:
-//
-// - asym [symref index]
-// - offset [int]
-// - type [int]
-// - gotype [symref index]
-//
-// The pcln table has the encoding:
-//
-// - pcsp [data block]
-// - pcfile [data block]
-// - pcline [data block]
-// - pcinline [data block]
-// - npcdata [int]
-// - pcdata [npcdata data blocks]
-// - nfuncdata [int]
-// - funcdata [nfuncdata symref index]
-// - funcdatasym [nfuncdata ints]
-// - nfile [int]
-// - file [nfile symref index]
-// - ninlinedcall [int]
-// - inlinedcall [ninlinedcall int symref int symref]
-//
-// The file layout and meaning of type integers are architecture-independent.
-//
-// TODO(rsc): The file format is good for a first pass but needs work.
-// - There are SymID in the object file that should really just be strings.
-package objabi
diff --git a/src/cmd/internal/objabi/funcdata.go b/src/cmd/internal/objabi/funcdata.go
index d5bacb5900..c9480bf2f0 100644
--- a/src/cmd/internal/objabi/funcdata.go
+++ b/src/cmd/internal/objabi/funcdata.go
@@ -35,7 +35,7 @@ const (
// PCDATA_RegMapIndex values.
//
// Only if !go115ReduceLiveness.
- PCDATA_RegMapUnsafe = -2 // Unsafe for async preemption
+ PCDATA_RegMapUnsafe = PCDATA_UnsafePointUnsafe // Unsafe for async preemption
// PCDATA_UnsafePoint values.
PCDATA_UnsafePointSafe = -1 // Safe for async preemption
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index f7873a42b9..d2d6fdbda8 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -131,12 +131,16 @@ func init() {
addexp(f)
}
}
-}
-func Framepointer_enabled(goos, goarch string) bool {
- return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin"))
+ // regabi is only supported on amd64.
+ if GOARCH != "amd64" {
+ Regabi_enabled = 0
+ }
}
+// Note: must agree with runtime.framepointer_enabled.
+var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin")
+
func addexp(s string) {
// Could do general integer parsing here, but the runtime copy doesn't yet.
v := 1
@@ -159,10 +163,10 @@ func addexp(s string) {
}
var (
- framepointer_enabled int = 1
Fieldtrack_enabled int
Preemptibleloops_enabled int
Staticlockranking_enabled int
+ Regabi_enabled int
)
// Toolchain experiments.
@@ -174,9 +178,9 @@ var exper = []struct {
val *int
}{
{"fieldtrack", &Fieldtrack_enabled},
- {"framepointer", &framepointer_enabled},
{"preemptibleloops", &Preemptibleloops_enabled},
{"staticlockranking", &Staticlockranking_enabled},
+ {"regabi", &Regabi_enabled},
}
var defaultExpstring = Expstring()
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/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index 37b72b6c37..a980cfee52 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -105,7 +105,7 @@ func archinit(ctxt *ld.Link) {
*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
}
if *ld.FlagRound == -1 {
- *ld.FlagRound = 4096
+ *ld.FlagRound = 16384 // 16K page alignment
}
}
}
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index dc7096ea8c..a730125cf2 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -930,7 +930,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 {
@@ -1308,9 +1308,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 +1706,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
@@ -1786,7 +1786,8 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
culprit := ldr.SymName(state.data[sym.STEXT][0])
Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit)
}
- state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 04)
+ state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05)
+ state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05)
/* read-only data */
sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
@@ -1810,7 +1811,6 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
/* read-only ELF, Mach-O sections */
state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
- state.allocateSingleSymSections(segro, sym.SMACHOPLT, sym.SRODATA, 04)
// There is some data that are conceptually read-only but are written to by
// relocations. On GNU systems, we can arrange for the dynamic linker to
@@ -1826,13 +1826,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 +1848,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]
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index 0269429723..35545f950e 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -209,7 +209,7 @@ 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 {
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 09c7bbfb53..4295b2a660 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -775,14 +775,6 @@ func (ctxt *Link) linksetup() {
sb.SetSize(0)
sb.AddUint8(uint8(objabi.GOARM))
}
-
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
- fpe := ctxt.loader.LookupOrCreateSym("runtime.framepointer_enabled", 0)
- sb := ctxt.loader.MakeSymbolUpdater(fpe)
- sb.SetType(sym.SNOPTRDATA)
- sb.SetSize(0)
- sb.AddUint8(1)
- }
} else {
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
@@ -1246,15 +1238,23 @@ func (ctxt *Link) hostlink() {
}
}
+ // On darwin, whether to combine DWARF into executable.
+ // Only macOS supports unmapped segments such as our __DWARF segment.
+ combineDwarf := ctxt.IsDarwin() && !*FlagS && !*FlagW && !debug_s && machoPlatform == PLATFORM_MACOS
+
switch ctxt.HeadType {
case objabi.Hdarwin:
- if machoPlatform == PLATFORM_MACOS {
+ if combineDwarf {
+ // Leave room for DWARF combining.
// -headerpad is incompatible with -fembed-bitcode.
argv = append(argv, "-Wl,-headerpad,1144")
}
if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
argv = append(argv, "-Wl,-flat_namespace")
}
+ if !combineDwarf {
+ argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols
+ }
case objabi.Hopenbsd:
argv = append(argv, "-Wl,-nopie")
case objabi.Hwindows:
@@ -1288,7 +1288,7 @@ func (ctxt *Link) hostlink() {
switch ctxt.BuildMode {
case BuildModeExe:
if ctxt.HeadType == objabi.Hdarwin {
- if machoPlatform == PLATFORM_MACOS {
+ if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() {
argv = append(argv, "-Wl,-no_pie")
argv = append(argv, "-Wl,-pagezero_size,4000000")
}
@@ -1525,7 +1525,7 @@ func (ctxt *Link) hostlink() {
// does not work, the resulting programs will not run. See
// issue #17847. To avoid this problem pass -no-pie to the
// toolchain if it is supported.
- if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
+ if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
// GCC uses -no-pie, clang uses -nopie.
for _, nopie := range []string{"-no-pie", "-nopie"} {
if linkerFlagSupported(argv[0], altLinker, nopie) {
@@ -1594,11 +1594,16 @@ func (ctxt *Link) hostlink() {
ctxt.Logf("%s", out)
}
- if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
+ if combineDwarf {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("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 {
+ Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
+ }
// Skip combining if `dsymutil` didn't generate a file. See #11994.
if _, err := os.Stat(dsym); os.IsNotExist(err) {
return
@@ -1614,15 +1619,12 @@ func (ctxt *Link) hostlink() {
if err != nil {
Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
}
- // Only macOS supports unmapped segments such as our __DWARF segment.
- if machoPlatform == PLATFORM_MACOS {
- if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
- Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
- }
- os.Remove(*flagOutfile)
- if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
- Exitf("%s: %v", os.Args[0], err)
- }
+ if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
+ Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
+ }
+ os.Remove(*flagOutfile)
+ if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
+ Exitf("%s: %v", os.Args[0], err)
}
}
}
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index f6356729a6..9765ce18d3 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -499,16 +499,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)
@@ -633,13 +624,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
@@ -695,7 +701,7 @@ func asmbMacho(ctxt *Link) {
if ctxt.LinkMode != LinkExternal {
ms := newMachoSeg("__LINKEDIT", 0)
- ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
+ ms.vaddr = uint64(Rnd(int64(Segdata.Vaddr+Segdata.Length), int64(*FlagRound)))
ms.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4)
ms.fileoffset = uint64(linkoff)
ms.filesize = ms.vsize
@@ -1008,7 +1014,7 @@ func doMachoLink(ctxt *Link) int64 {
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))
@@ -1086,6 +1092,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)
}
diff --git a/src/cmd/link/internal/ld/macho_combine_dwarf.go b/src/cmd/link/internal/ld/macho_combine_dwarf.go
index 9d9f916b8e..77ee8a4d62 100644
--- a/src/cmd/link/internal/ld/macho_combine_dwarf.go
+++ b/src/cmd/link/internal/ld/macho_combine_dwarf.go
@@ -16,10 +16,6 @@ import (
"unsafe"
)
-const (
- pageAlign = 12 // 4096 = 1 << 12
-)
-
type loadCmd struct {
Cmd macho.LoadCmd
Len uint32
@@ -138,7 +134,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
// Now copy the dwarf data into the output.
// Kernel requires all loaded segments to be page-aligned in the file,
// even though we mark this one as being 0 bytes of virtual address space.
- dwarfstart := machoCalcStart(realdwarf.Offset, linkseg.Offset, pageAlign)
+ dwarfstart := Rnd(int64(linkseg.Offset), int64(*FlagRound))
if _, err := outf.Seek(dwarfstart, 0); err != nil {
return err
}
@@ -166,7 +162,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
if _, err := exef.Seek(int64(linkseg.Offset), 0); err != nil {
return err
}
- linkstart := machoCalcStart(linkseg.Offset, uint64(dwarfstart)+dwarfsize, pageAlign)
+ linkstart := Rnd(dwarfstart+int64(dwarfsize), int64(*FlagRound))
if _, err := outf.Seek(linkstart, 0); err != nil {
return err
}
@@ -217,9 +213,9 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
linkoffset := uint64(linkstart) - linkseg.Offset
switch cmd.Cmd {
case macho.LoadCmdSegment64:
- err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment64{}, &macho.Section64{})
+ err = machoUpdateSegment(reader, linkseg, linkoffset)
case macho.LoadCmdSegment:
- err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment32{}, &macho.Section32{})
+ panic("unexpected 32-bit segment")
case LC_DYLD_INFO, LC_DYLD_INFO_ONLY:
err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &dyldInfoCmd{}, "RebaseOff", "BindOff", "WeakBindOff", "LazyBindOff", "ExportOff")
case macho.LoadCmdSymtab:
@@ -313,70 +309,56 @@ func machoCompressSection(sectBytes []byte) (compressed bool, contents []byte, e
// machoUpdateSegment updates the load command for a moved segment.
// Only the linkedit segment should move, and it should have 0 sections.
-// seg should be a macho.Segment32 or macho.Segment64 as appropriate.
-// sect should be a macho.Section32 or macho.Section64 as appropriate.
-func machoUpdateSegment(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, seg, sect interface{}) error {
- if err := r.ReadAt(0, seg); err != nil {
+func machoUpdateSegment(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64) error {
+ var seg macho.Segment64
+ if err := r.ReadAt(0, &seg); err != nil {
return err
}
- segValue := reflect.ValueOf(seg)
- offset := reflect.Indirect(segValue).FieldByName("Offset")
// Only the linkedit segment moved, anything before that is fine.
- if offset.Uint() < linkseg.Offset {
+ if seg.Offset < linkseg.Offset {
return nil
}
- offset.SetUint(offset.Uint() + linkoffset)
- if err := r.WriteAt(0, seg); err != nil {
+ seg.Offset += linkoffset
+ if err := r.WriteAt(0, &seg); err != nil {
return err
}
// There shouldn't be any sections, but just to make sure...
- return machoUpdateSections(r, segValue, reflect.ValueOf(sect), linkoffset, nil)
+ return machoUpdateSections(r, &seg, linkoffset, nil)
}
-func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset uint64, compressedSects []*macho.Section) error {
- iseg := reflect.Indirect(seg)
- nsect := iseg.FieldByName("Nsect").Uint()
+func machoUpdateSections(r loadCmdReader, seg *macho.Segment64, deltaOffset uint64, compressedSects []*macho.Section) error {
+ nsect := seg.Nsect
if nsect == 0 {
return nil
}
- sectOffset := int64(iseg.Type().Size())
-
- isect := reflect.Indirect(sect)
- offsetField := isect.FieldByName("Offset")
- reloffField := isect.FieldByName("Reloff")
- addrField := isect.FieldByName("Addr")
- nameField := isect.FieldByName("Name")
- sizeField := isect.FieldByName("Size")
- sectSize := int64(isect.Type().Size())
- for i := uint64(0); i < nsect; i++ {
- if err := r.ReadAt(sectOffset, sect.Interface()); err != nil {
+ sectOffset := int64(unsafe.Sizeof(*seg))
+
+ var sect macho.Section64
+ sectSize := int64(unsafe.Sizeof(sect))
+ for i := uint32(0); i < nsect; i++ {
+ if err := r.ReadAt(sectOffset, &sect); err != nil {
return err
}
if compressedSects != nil {
cSect := compressedSects[i]
- var name [16]byte
- copy(name[:], []byte(cSect.Name))
- nameField.Set(reflect.ValueOf(name))
- sizeField.SetUint(cSect.Size)
+ copy(sect.Name[:], cSect.Name)
+ sect.Size = cSect.Size
if cSect.Offset != 0 {
- offsetField.SetUint(uint64(cSect.Offset) + deltaOffset)
+ sect.Offset = cSect.Offset + uint32(deltaOffset)
}
if cSect.Addr != 0 {
- addrField.SetUint(cSect.Addr)
+ sect.Addr = cSect.Addr
}
} else {
- if offsetField.Uint() != 0 {
- offsetField.SetUint(offsetField.Uint() + deltaOffset)
- }
- if reloffField.Uint() != 0 {
- reloffField.SetUint(reloffField.Uint() + deltaOffset)
+ if sect.Offset != 0 {
+ sect.Offset += uint32(deltaOffset)
}
- if addrField.Uint() != 0 {
- addrField.SetUint(addrField.Uint())
+ if sect.Reloff != 0 {
+ sect.Reloff += uint32(deltaOffset)
}
}
- if err := r.WriteAt(sectOffset, sect.Interface()); err != nil {
+ if err := r.WriteAt(sectOffset, &sect); err != nil {
return err
}
sectOffset += sectSize
@@ -386,32 +368,27 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset u
// machoUpdateDwarfHeader updates the DWARF segment load command.
func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section, dwarfsize uint64, dwarfstart int64, realdwarf *macho.Segment) error {
- var seg, sect interface{}
cmd, err := r.Next()
if err != nil {
return err
}
- if cmd.Cmd == macho.LoadCmdSegment64 {
- seg = new(macho.Segment64)
- sect = new(macho.Section64)
- } else {
- seg = new(macho.Segment32)
- sect = new(macho.Section32)
+ if cmd.Cmd != macho.LoadCmdSegment64 {
+ panic("not a Segment64")
}
- if err := r.ReadAt(0, seg); err != nil {
+ var seg macho.Segment64
+ if err := r.ReadAt(0, &seg); err != nil {
return err
}
- segv := reflect.ValueOf(seg).Elem()
- segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
+ seg.Offset = uint64(dwarfstart)
if compressedSects != nil {
var segSize uint64
for _, newSect := range compressedSects {
segSize += newSect.Size
}
- segv.FieldByName("Filesz").SetUint(segSize)
+ seg.Filesz = segSize
} else {
- segv.FieldByName("Filesz").SetUint(dwarfsize)
+ seg.Filesz = dwarfsize
}
// We want the DWARF segment to be considered non-loadable, so
@@ -424,14 +401,14 @@ func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section,
// in ImageLoaderMachO.cpp (various versions can be found online, see
// https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
// as one example).
- segv.FieldByName("Addr").SetUint(0)
- segv.FieldByName("Memsz").SetUint(0)
- segv.FieldByName("Prot").SetUint(0)
+ seg.Addr = 0
+ seg.Memsz = 0
+ seg.Prot = 0
- if err := r.WriteAt(0, seg); err != nil {
+ if err := r.WriteAt(0, &seg); err != nil {
return err
}
- return machoUpdateSections(*r, segv, reflect.ValueOf(sect), uint64(dwarfstart)-realdwarf.Offset, compressedSects)
+ return machoUpdateSections(*r, &seg, uint64(dwarfstart)-realdwarf.Offset, compressedSects)
}
func machoUpdateLoadCommand(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, cmd interface{}, fields ...string) error {
@@ -451,12 +428,3 @@ func machoUpdateLoadCommand(r loadCmdReader, linkseg *macho.Segment, linkoffset
}
return nil
}
-
-func machoCalcStart(origAddr, newAddr uint64, alignExp uint32) int64 {
- align := uint64(1 << alignExp)
- origMod, newMod := origAddr%align, newAddr%align
- if origMod == newMod {
- return int64(newAddr)
- }
- return int64(newAddr + align + origMod - newMod)
-}
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index bc880955b8..56363cdaae 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -681,8 +681,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/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 8fd10b0848..43a0352e0b 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -93,11 +93,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 +220,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
@@ -331,7 +332,7 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor
objSyms: make([]objSym, 1, 100000), // reserve index 0 for nil symbol
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 +371,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
@@ -635,12 +636,7 @@ func (l *Loader) resolve(r *oReader, s goobj.SymRef) Sym {
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)
}
@@ -2195,6 +2191,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)
diff --git a/src/cmd/link/internal/sym/symkind.go b/src/cmd/link/internal/sym/symkind.go
index 3e47d9a8e4..c176d5e208 100644
--- a/src/cmd/link/internal/sym/symkind.go
+++ b/src/cmd/link/internal/sym/symkind.go
@@ -41,6 +41,7 @@ const (
Sxxx SymKind = iota
STEXT
SELFRXSECT
+ SMACHOPLT
// Read-only sections.
STYPE
@@ -52,7 +53,6 @@ const (
SFUNCTAB
SELFROSECT
- SMACHOPLT
// Read-only sections with relocations.
//
diff --git a/src/cmd/link/internal/sym/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go
index 47b2406e28..34cb314bd5 100644
--- a/src/cmd/link/internal/sym/symkind_string.go
+++ b/src/cmd/link/internal/sym/symkind_string.go
@@ -1,4 +1,4 @@
-// Code generated by "stringer -type=SymKindstringer -type=SymKind"; DO NOT EDIT.
+// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
package sym
@@ -11,15 +11,15 @@ func _() {
_ = x[Sxxx-0]
_ = x[STEXT-1]
_ = x[SELFRXSECT-2]
- _ = x[STYPE-3]
- _ = x[SSTRING-4]
- _ = x[SGOSTRING-5]
- _ = x[SGOFUNC-6]
- _ = x[SGCBITS-7]
- _ = x[SRODATA-8]
- _ = x[SFUNCTAB-9]
- _ = x[SELFROSECT-10]
- _ = x[SMACHOPLT-11]
+ _ = x[SMACHOPLT-3]
+ _ = x[STYPE-4]
+ _ = x[SSTRING-5]
+ _ = x[SGOSTRING-6]
+ _ = x[SGOFUNC-7]
+ _ = x[SGCBITS-8]
+ _ = x[SRODATA-9]
+ _ = x[SFUNCTAB-10]
+ _ = x[SELFROSECT-11]
_ = x[STYPERELRO-12]
_ = x[SSTRINGRELRO-13]
_ = x[SGOSTRINGRELRO-14]
@@ -68,9 +68,9 @@ func _() {
_ = x[SABIALIAS-57]
}
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
+const _SymKind_name = "SxxxSTEXTSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
-var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 426, 434, 443, 453, 465, 476, 485, 497, 507, 516, 527, 536, 547, 556}
+var _SymKind_index = [...]uint16{0, 4, 9, 19, 28, 33, 40, 49, 56, 63, 70, 78, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 426, 434, 443, 453, 465, 476, 485, 497, 507, 516, 527, 536, 547, 556}
func (i SymKind) String() string {
if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 3b5efdf7a3..4e60996d8e 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -1,3 +1,7 @@
+// 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 (
@@ -455,9 +459,7 @@ func TestIssue34788Android386TLSSequence(t *testing.T) {
cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src)
cmd.Env = append(os.Environ(), "GOARCH=386", "GOOS=android")
if out, err := cmd.CombinedOutput(); err != nil {
- if err != nil {
- t.Fatalf("failed to compile blah.go: %v, output: %s\n", err, out)
- }
+ t.Fatalf("failed to compile blah.go: %v, output: %s\n", err, out)
}
// Run objdump on the resulting object.
@@ -798,3 +800,17 @@ 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)
+ }
+}
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/vendor/golang.org/x/mod/modfile/read.go b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
index c1f2008ee4..2a961ca81c 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/read.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
@@ -477,9 +477,17 @@ func (in *input) startToken() {
// endToken marks the end of an input token.
// It records the actual token string in tok.text.
+// A single trailing newline (LF or CRLF) will be removed from comment tokens.
func (in *input) endToken(kind tokenKind) {
in.token.kind = kind
text := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)])
+ if kind.isComment() {
+ if strings.HasSuffix(text, "\r\n") {
+ text = text[:len(text)-2]
+ } else {
+ text = strings.TrimSuffix(text, "\n")
+ }
+ }
in.token.text = text
in.token.endPos = in.pos
}
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
index 91ca6828df..83398dda5d 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
@@ -30,6 +30,7 @@ import (
"golang.org/x/mod/internal/lazyregexp"
"golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
)
// A File is the parsed, interpreted form of a go.mod file.
@@ -39,6 +40,7 @@ type File struct {
Require []*Require
Exclude []*Exclude
Replace []*Replace
+ Retract []*Retract
Syntax *FileSyntax
}
@@ -75,6 +77,21 @@ type Replace struct {
Syntax *Line
}
+// A Retract is a single retract statement.
+type Retract struct {
+ VersionInterval
+ Rationale string
+ Syntax *Line
+}
+
+// A VersionInterval represents a range of versions with upper and lower bounds.
+// Intervals are closed: both bounds are included. When Low is equal to High,
+// the interval may refer to a single version ('v1.2.3') or an interval
+// ('[v1.2.3, v1.2.3]'); both have the same representation.
+type VersionInterval struct {
+ Low, High string
+}
+
func (f *File) AddModuleStmt(path string) error {
if f.Syntax == nil {
f.Syntax = new(FileSyntax)
@@ -138,7 +155,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
for _, x := range fs.Stmt {
switch x := x.(type) {
case *Line:
- f.add(&errs, x, x.Token[0], x.Token[1:], fix, strict)
+ f.add(&errs, nil, x, x.Token[0], x.Token[1:], fix, strict)
case *LineBlock:
if len(x.Token) > 1 {
@@ -161,9 +178,9 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
})
}
continue
- case "module", "require", "exclude", "replace":
+ case "module", "require", "exclude", "replace", "retract":
for _, l := range x.Line {
- f.add(&errs, l, x.Token[0], l.Token, fix, strict)
+ f.add(&errs, x, l, x.Token[0], l.Token, fix, strict)
}
}
}
@@ -177,7 +194,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
-func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
+func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
// If strict is false, this module is a dependency.
// We ignore all unknown directives as well as main-module-only
// directives like replace and exclude. It will work better for
@@ -186,7 +203,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix
// and simply ignore those statements.
if !strict {
switch verb {
- case "module", "require", "go":
+ case "go", "module", "retract", "require":
// want these even for dependency go.mods
default:
return
@@ -232,6 +249,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix
f.Go = &Go{Syntax: line}
f.Go.Version = args[0]
+
case "module":
if f.Module != nil {
errorf("repeated module statement")
@@ -248,6 +266,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix
return
}
f.Module.Mod = module.Version{Path: s}
+
case "require", "exclude":
if len(args) != 2 {
errorf("usage: %s module/path v1.2.3", verb)
@@ -284,6 +303,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix
Syntax: line,
})
}
+
case "replace":
arrow := 2
if len(args) >= 2 && args[1] == "=>" {
@@ -347,6 +367,33 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix
New: module.Version{Path: ns, Version: nv},
Syntax: line,
})
+
+ case "retract":
+ rationale := parseRetractRationale(block, line)
+ vi, err := parseVersionInterval(verb, &args, fix)
+ if err != nil {
+ if strict {
+ wrapError(err)
+ return
+ } else {
+ // Only report errors parsing intervals in the main module. We may
+ // support additional syntax in the future, such as open and half-open
+ // intervals. Those can't be supported now, because they break the
+ // go.mod parser, even in lax mode.
+ return
+ }
+ }
+ if len(args) > 0 && strict {
+ // In the future, there may be additional information after the version.
+ errorf("unexpected token after version: %q", args[0])
+ return
+ }
+ retract := &Retract{
+ VersionInterval: vi,
+ Rationale: rationale,
+ Syntax: line,
+ }
+ f.Retract = append(f.Retract, retract)
}
}
@@ -444,6 +491,53 @@ func AutoQuote(s string) string {
return s
}
+func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (VersionInterval, error) {
+ toks := *args
+ if len(toks) == 0 || toks[0] == "(" {
+ return VersionInterval{}, fmt.Errorf("expected '[' or version")
+ }
+ if toks[0] != "[" {
+ v, err := parseVersion(verb, "", &toks[0], fix)
+ if err != nil {
+ return VersionInterval{}, err
+ }
+ *args = toks[1:]
+ return VersionInterval{Low: v, High: v}, nil
+ }
+ toks = toks[1:]
+
+ if len(toks) == 0 {
+ return VersionInterval{}, fmt.Errorf("expected version after '['")
+ }
+ low, err := parseVersion(verb, "", &toks[0], fix)
+ if err != nil {
+ return VersionInterval{}, err
+ }
+ toks = toks[1:]
+
+ if len(toks) == 0 || toks[0] != "," {
+ return VersionInterval{}, fmt.Errorf("expected ',' after version")
+ }
+ toks = toks[1:]
+
+ if len(toks) == 0 {
+ return VersionInterval{}, fmt.Errorf("expected version after ','")
+ }
+ high, err := parseVersion(verb, "", &toks[0], fix)
+ if err != nil {
+ return VersionInterval{}, err
+ }
+ toks = toks[1:]
+
+ if len(toks) == 0 || toks[0] != "]" {
+ return VersionInterval{}, fmt.Errorf("expected ']' after version")
+ }
+ toks = toks[1:]
+
+ *args = toks
+ return VersionInterval{Low: low, High: high}, nil
+}
+
func parseString(s *string) (string, error) {
t := *s
if strings.HasPrefix(t, `"`) {
@@ -461,6 +555,27 @@ func parseString(s *string) (string, error) {
return t, nil
}
+// parseRetractRationale extracts the rationale for a retract directive from the
+// surrounding comments. If the line does not have comments and is part of a
+// block that does have comments, the block's comments are used.
+func parseRetractRationale(block *LineBlock, line *Line) string {
+ comments := line.Comment()
+ if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 {
+ comments = block.Comment()
+ }
+ groups := [][]Comment{comments.Before, comments.Suffix}
+ var lines []string
+ for _, g := range groups {
+ for _, c := range g {
+ if !strings.HasPrefix(c.Token, "//") {
+ continue // blank line
+ }
+ lines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, "//")))
+ }
+ }
+ return strings.Join(lines, "\n")
+}
+
type ErrorList []Error
func (e ErrorList) Error() string {
@@ -494,6 +609,8 @@ func (e *Error) Error() string {
var directive string
if e.ModPath != "" {
directive = fmt.Sprintf("%s %s: ", e.Verb, e.ModPath)
+ } else if e.Verb != "" {
+ directive = fmt.Sprintf("%s: ", e.Verb)
}
return pos + directive + e.Err.Error()
@@ -585,6 +702,15 @@ func (f *File) Cleanup() {
}
f.Replace = f.Replace[:w]
+ w = 0
+ for _, r := range f.Retract {
+ if r.Low != "" || r.High != "" {
+ f.Retract[w] = r
+ w++
+ }
+ }
+ f.Retract = f.Retract[:w]
+
f.Syntax.Cleanup()
}
@@ -778,6 +904,34 @@ func (f *File) DropReplace(oldPath, oldVers string) error {
return nil
}
+func (f *File) AddRetract(vi VersionInterval, rationale string) error {
+ r := &Retract{
+ VersionInterval: vi,
+ }
+ if vi.Low == vi.High {
+ r.Syntax = f.Syntax.addLine(nil, "retract", AutoQuote(vi.Low))
+ } else {
+ r.Syntax = f.Syntax.addLine(nil, "retract", "[", AutoQuote(vi.Low), ",", AutoQuote(vi.High), "]")
+ }
+ if rationale != "" {
+ for _, line := range strings.Split(rationale, "\n") {
+ com := Comment{Token: "// " + line}
+ r.Syntax.Comment().Before = append(r.Syntax.Comment().Before, com)
+ }
+ }
+ return nil
+}
+
+func (f *File) DropRetract(vi VersionInterval) error {
+ for _, r := range f.Retract {
+ if r.VersionInterval == vi {
+ f.Syntax.removeLine(r.Syntax)
+ *r = Retract{}
+ }
+ }
+ return nil
+}
+
func (f *File) SortBlocks() {
f.removeDups() // otherwise sorting is unsafe
@@ -786,28 +940,38 @@ func (f *File) SortBlocks() {
if !ok {
continue
}
- sort.Slice(block.Line, func(i, j int) bool {
- li := block.Line[i]
- lj := block.Line[j]
- for k := 0; k < len(li.Token) && k < len(lj.Token); k++ {
- if li.Token[k] != lj.Token[k] {
- return li.Token[k] < lj.Token[k]
- }
- }
- return len(li.Token) < len(lj.Token)
+ less := lineLess
+ if block.Token[0] == "retract" {
+ less = lineRetractLess
+ }
+ sort.SliceStable(block.Line, func(i, j int) bool {
+ return less(block.Line[i], block.Line[j])
})
}
}
+// removeDups removes duplicate exclude and replace directives.
+//
+// Earlier exclude directives take priority.
+//
+// Later replace directives take priority.
+//
+// require directives are not de-duplicated. That's left up to higher-level
+// logic (MVS).
+//
+// retract directives are not de-duplicated since comments are
+// meaningful, and versions may be retracted multiple times.
func (f *File) removeDups() {
- have := make(map[module.Version]bool)
kill := make(map[*Line]bool)
+
+ // Remove duplicate excludes.
+ haveExclude := make(map[module.Version]bool)
for _, x := range f.Exclude {
- if have[x.Mod] {
+ if haveExclude[x.Mod] {
kill[x.Syntax] = true
continue
}
- have[x.Mod] = true
+ haveExclude[x.Mod] = true
}
var excl []*Exclude
for _, x := range f.Exclude {
@@ -817,15 +981,16 @@ func (f *File) removeDups() {
}
f.Exclude = excl
- have = make(map[module.Version]bool)
+ // Remove duplicate replacements.
// Later replacements take priority over earlier ones.
+ haveReplace := make(map[module.Version]bool)
for i := len(f.Replace) - 1; i >= 0; i-- {
x := f.Replace[i]
- if have[x.Old] {
+ if haveReplace[x.Old] {
kill[x.Syntax] = true
continue
}
- have[x.Old] = true
+ haveReplace[x.Old] = true
}
var repl []*Replace
for _, x := range f.Replace {
@@ -835,6 +1000,9 @@ func (f *File) removeDups() {
}
f.Replace = repl
+ // Duplicate require and retract directives are not removed.
+
+ // Drop killed statements from the syntax tree.
var stmts []Expr
for _, stmt := range f.Syntax.Stmt {
switch stmt := stmt.(type) {
@@ -858,3 +1026,38 @@ func (f *File) removeDups() {
}
f.Syntax.Stmt = stmts
}
+
+// lineLess returns whether li should be sorted before lj. It sorts
+// lexicographically without assigning any special meaning to tokens.
+func lineLess(li, lj *Line) bool {
+ for k := 0; k < len(li.Token) && k < len(lj.Token); k++ {
+ if li.Token[k] != lj.Token[k] {
+ return li.Token[k] < lj.Token[k]
+ }
+ }
+ return len(li.Token) < len(lj.Token)
+}
+
+// lineRetractLess returns whether li should be sorted before lj for lines in
+// a "retract" block. It treats each line as a version interval. Single versions
+// are compared as if they were intervals with the same low and high version.
+// Intervals are sorted in descending order, first by low version, then by
+// high version, using semver.Compare.
+func lineRetractLess(li, lj *Line) bool {
+ interval := func(l *Line) VersionInterval {
+ if len(l.Token) == 1 {
+ return VersionInterval{Low: l.Token[0], High: l.Token[0]}
+ } else if len(l.Token) == 5 && l.Token[0] == "[" && l.Token[2] == "," && l.Token[4] == "]" {
+ return VersionInterval{Low: l.Token[1], High: l.Token[3]}
+ } else {
+ // Line in unknown format. Treat as an invalid version.
+ return VersionInterval{}
+ }
+ }
+ vii := interval(li)
+ vij := interval(lj)
+ if cmp := semver.Compare(vii.Low, vij.Low); cmp != 0 {
+ return cmp > 0
+ }
+ return semver.Compare(vii.High, vij.High) > 0
+}
diff --git a/src/cmd/vendor/golang.org/x/mod/module/module.go b/src/cmd/vendor/golang.org/x/mod/module/module.go
index 3a8b080c7b..c1c5263c42 100644
--- a/src/cmd/vendor/golang.org/x/mod/module/module.go
+++ b/src/cmd/vendor/golang.org/x/mod/module/module.go
@@ -225,13 +225,13 @@ func firstPathOK(r rune) bool {
}
// pathOK reports whether r can appear in an import path element.
-// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~.
+// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
// This matches what "go get" has historically recognized in import paths.
// TODO(rsc): We would like to allow Unicode letters, but that requires additional
// care in the safe encoding (see "escaped paths" above).
func pathOK(r rune) bool {
if r < utf8.RuneSelf {
- return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' ||
+ return r == '-' || r == '.' || r == '_' || r == '~' ||
'0' <= r && r <= '9' ||
'A' <= r && r <= 'Z' ||
'a' <= r && r <= 'z'
@@ -314,11 +314,13 @@ func CheckPath(path string) error {
// separated by slashes (U+002F). (It must not begin with nor end in a slash.)
//
// A valid path element is a non-empty string made up of
-// ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~.
+// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
//
// The element prefix up to the first dot must not be a reserved file name
-// on Windows, regardless of case (CON, com1, NuL, and so on).
+// on Windows, regardless of case (CON, com1, NuL, and so on). The element
+// must not have a suffix of a tilde followed by one or more ASCII digits
+// (to exclude paths elements that look like Windows short-names).
//
// CheckImportPath may be less restrictive in the future, but see the
// top-level package documentation for additional information about
@@ -403,6 +405,29 @@ func checkElem(elem string, fileName bool) error {
return fmt.Errorf("%q disallowed as path element component on Windows", short)
}
}
+
+ if fileName {
+ // don't check for Windows short-names in file names. They're
+ // only an issue for import paths.
+ return nil
+ }
+
+ // Reject path components that look like Windows short-names.
+ // Those usually end in a tilde followed by one or more ASCII digits.
+ if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 {
+ suffix := short[tilde+1:]
+ suffixIsDigits := true
+ for _, r := range suffix {
+ if r < '0' || r > '9' {
+ suffixIsDigits = false
+ break
+ }
+ }
+ if suffixIsDigits {
+ return fmt.Errorf("trailing tilde and digits in path element")
+ }
+ }
+
return nil
}
diff --git a/src/cmd/vendor/golang.org/x/mod/zip/zip.go b/src/cmd/vendor/golang.org/x/mod/zip/zip.go
index 6865895b3d..5b401ad4d8 100644
--- a/src/cmd/vendor/golang.org/x/mod/zip/zip.go
+++ b/src/cmd/vendor/golang.org/x/mod/zip/zip.go
@@ -48,6 +48,7 @@ package zip
import (
"archive/zip"
"bytes"
+ "errors"
"fmt"
"io"
"io/ioutil"
@@ -92,40 +93,134 @@ type File interface {
Open() (io.ReadCloser, error)
}
-// Create builds a zip archive for module m from an abstract list of files
-// and writes it to w.
+// CheckedFiles reports whether a set of files satisfy the name and size
+// constraints required by module zip files. The constraints are listed in the
+// package documentation.
//
-// Create verifies the restrictions described in the package documentation
-// and should not produce an archive that Unzip cannot extract. Create does not
-// include files in the output archive if they don't belong in the module zip.
-// In particular, Create will not include files in modules found in
-// subdirectories, most files in vendor directories, or irregular files (such
-// as symbolic links) in the output archive.
-func Create(w io.Writer, m module.Version, files []File) (err error) {
- defer func() {
- if err != nil {
- err = &zipError{verb: "create zip", err: err}
- }
- }()
+// Functions that produce this report may include slightly different sets of
+// files. See documentation for CheckFiles, CheckDir, and CheckZip for details.
+type CheckedFiles struct {
+ // Valid is a list of file paths that should be included in a zip file.
+ Valid []string
+
+ // Omitted is a list of files that are ignored when creating a module zip
+ // file, along with the reason each file is ignored.
+ Omitted []FileError
+
+ // Invalid is a list of files that should not be included in a module zip
+ // file, along with the reason each file is invalid.
+ Invalid []FileError
+
+ // SizeError is non-nil if the total uncompressed size of the valid files
+ // exceeds the module zip size limit or if the zip file itself exceeds the
+ // limit.
+ SizeError error
+}
- // Check that the version is canonical, the module path is well-formed, and
- // the major version suffix matches the major version.
- if vers := module.CanonicalVersion(m.Version); vers != m.Version {
- return fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers)
+// Err returns an error if CheckedFiles does not describe a valid module zip
+// file. SizeError is returned if that field is set. A FileErrorList is returned
+// if there are one or more invalid files. Other errors may be returned in the
+// future.
+func (cf CheckedFiles) Err() error {
+ if cf.SizeError != nil {
+ return cf.SizeError
}
- if err := module.Check(m.Path, m.Version); err != nil {
- return err
+ if len(cf.Invalid) > 0 {
+ return FileErrorList(cf.Invalid)
+ }
+ return nil
+}
+
+type FileErrorList []FileError
+
+func (el FileErrorList) Error() string {
+ buf := &strings.Builder{}
+ sep := ""
+ for _, e := range el {
+ buf.WriteString(sep)
+ buf.WriteString(e.Error())
+ sep = "\n"
+ }
+ return buf.String()
+}
+
+type FileError struct {
+ Path string
+ Err error
+}
+
+func (e FileError) Error() string {
+ return fmt.Sprintf("%s: %s", e.Path, e.Err)
+}
+
+func (e FileError) Unwrap() error {
+ return e.Err
+}
+
+var (
+ // Predefined error messages for invalid files. Not exhaustive.
+ errPathNotClean = errors.New("file path is not clean")
+ errPathNotRelative = errors.New("file path is not relative")
+ errGoModCase = errors.New("go.mod files must have lowercase names")
+ errGoModSize = fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod)
+ errLICENSESize = fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE)
+
+ // Predefined error messages for omitted files. Not exhaustive.
+ errVCS = errors.New("directory is a version control repository")
+ errVendored = errors.New("file is in vendor directory")
+ errSubmoduleFile = errors.New("file is in another module")
+ errSubmoduleDir = errors.New("directory is in another module")
+ errHgArchivalTxt = errors.New("file is inserted by 'hg archive' and is always omitted")
+ errSymlink = errors.New("file is a symbolic link")
+ errNotRegular = errors.New("not a regular file")
+)
+
+// CheckFiles reports whether a list of files satisfy the name and size
+// constraints listed in the package documentation. The returned CheckedFiles
+// record contains lists of valid, invalid, and omitted files. Every file in
+// the given list will be included in exactly one of those lists.
+//
+// CheckFiles returns an error if the returned CheckedFiles does not describe
+// a valid module zip file (according to CheckedFiles.Err). The returned
+// CheckedFiles is still populated when an error is returned.
+//
+// Note that CheckFiles will not open any files, so Create may still fail when
+// CheckFiles is successful due to I/O errors and reported size differences.
+func CheckFiles(files []File) (CheckedFiles, error) {
+ cf, _, _ := checkFiles(files)
+ return cf, cf.Err()
+}
+
+// checkFiles implements CheckFiles and also returns lists of valid files and
+// their sizes, corresponding to cf.Valid. These lists are used in Crewate to
+// avoid repeated calls to File.Lstat.
+func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []int64) {
+ errPaths := make(map[string]struct{})
+ addError := func(path string, omitted bool, err error) {
+ if _, ok := errPaths[path]; ok {
+ return
+ }
+ errPaths[path] = struct{}{}
+ fe := FileError{Path: path, Err: err}
+ if omitted {
+ cf.Omitted = append(cf.Omitted, fe)
+ } else {
+ cf.Invalid = append(cf.Invalid, fe)
+ }
}
// Find directories containing go.mod files (other than the root).
+ // Files in these directories will be omitted.
// These directories will not be included in the output zip.
haveGoMod := make(map[string]bool)
for _, f := range files {
- dir, base := path.Split(f.Path())
+ p := f.Path()
+ dir, base := path.Split(p)
if strings.EqualFold(base, "go.mod") {
info, err := f.Lstat()
if err != nil {
- return err
+ addError(p, false, err)
+ continue
}
if info.Mode().IsRegular() {
haveGoMod[dir] = true
@@ -146,77 +241,292 @@ func Create(w io.Writer, m module.Version, files []File) (err error) {
}
}
- // Create the module zip file.
- zw := zip.NewWriter(w)
- prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version)
-
- addFile := func(f File, path string, size int64) error {
- rc, err := f.Open()
- if err != nil {
- return err
- }
- defer rc.Close()
- w, err := zw.Create(prefix + path)
- if err != nil {
- return err
- }
- lr := &io.LimitedReader{R: rc, N: size + 1}
- if _, err := io.Copy(w, lr); err != nil {
- return err
- }
- if lr.N <= 0 {
- return fmt.Errorf("file %q is larger than declared size", path)
- }
- return nil
- }
-
collisions := make(collisionChecker)
maxSize := int64(MaxZipFile)
for _, f := range files {
p := f.Path()
if p != path.Clean(p) {
- return fmt.Errorf("file path %s is not clean", p)
+ addError(p, false, errPathNotClean)
+ continue
}
if path.IsAbs(p) {
- return fmt.Errorf("file path %s is not relative", p)
+ addError(p, false, errPathNotRelative)
+ continue
+ }
+ if isVendoredPackage(p) {
+ addError(p, true, errVendored)
+ continue
}
- if isVendoredPackage(p) || inSubmodule(p) {
+ if inSubmodule(p) {
+ addError(p, true, errSubmoduleFile)
continue
}
if p == ".hg_archival.txt" {
// Inserted by hg archive.
// The go command drops this regardless of the VCS being used.
+ addError(p, true, errHgArchivalTxt)
continue
}
if err := module.CheckFilePath(p); err != nil {
- return err
+ addError(p, false, err)
+ continue
}
if strings.ToLower(p) == "go.mod" && p != "go.mod" {
- return fmt.Errorf("found file named %s, want all lower-case go.mod", p)
+ addError(p, false, errGoModCase)
+ continue
}
info, err := f.Lstat()
if err != nil {
- return err
+ addError(p, false, err)
+ continue
}
if err := collisions.check(p, info.IsDir()); err != nil {
- return err
+ addError(p, false, err)
+ continue
}
- if !info.Mode().IsRegular() {
+ if info.Mode()&os.ModeType == os.ModeSymlink {
// Skip symbolic links (golang.org/issue/27093).
+ addError(p, true, errSymlink)
+ continue
+ }
+ if !info.Mode().IsRegular() {
+ addError(p, true, errNotRegular)
continue
}
size := info.Size()
- if size < 0 || maxSize < size {
- return fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile)
+ if size >= 0 && size <= maxSize {
+ maxSize -= size
+ } else if cf.SizeError == nil {
+ cf.SizeError = fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile)
}
- maxSize -= size
if p == "go.mod" && size > MaxGoMod {
- return fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod)
+ addError(p, false, errGoModSize)
+ continue
}
if p == "LICENSE" && size > MaxLICENSE {
- return fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE)
+ addError(p, false, errLICENSESize)
+ continue
+ }
+
+ cf.Valid = append(cf.Valid, p)
+ validFiles = append(validFiles, f)
+ validSizes = append(validSizes, info.Size())
+ }
+
+ return cf, validFiles, validSizes
+}
+
+// CheckDir reports whether the files in dir satisfy the name and size
+// constraints listed in the package documentation. The returned CheckedFiles
+// record contains lists of valid, invalid, and omitted files. If a directory is
+// omitted (for example, a nested module or vendor directory), it will appear in
+// the omitted list, but its files won't be listed.
+//
+// CheckDir returns an error if it encounters an I/O error or if the returned
+// CheckedFiles does not describe a valid module zip file (according to
+// CheckedFiles.Err). The returned CheckedFiles is still populated when such
+// an error is returned.
+//
+// Note that CheckDir will not open any files, so CreateFromDir may still fail
+// when CheckDir is successful due to I/O errors.
+func CheckDir(dir string) (CheckedFiles, error) {
+ // List files (as CreateFromDir would) and check which ones are omitted
+ // or invalid.
+ files, omitted, err := listFilesInDir(dir)
+ if err != nil {
+ return CheckedFiles{}, err
+ }
+ cf, cfErr := CheckFiles(files)
+ _ = cfErr // ignore this error; we'll generate our own after rewriting paths.
+
+ // Replace all paths with file system paths.
+ // Paths returned by CheckFiles will be slash-separated paths relative to dir.
+ // That's probably not appropriate for error messages.
+ for i := range cf.Valid {
+ cf.Valid[i] = filepath.Join(dir, cf.Valid[i])
+ }
+ cf.Omitted = append(cf.Omitted, omitted...)
+ for i := range cf.Omitted {
+ cf.Omitted[i].Path = filepath.Join(dir, cf.Omitted[i].Path)
+ }
+ for i := range cf.Invalid {
+ cf.Invalid[i].Path = filepath.Join(dir, cf.Invalid[i].Path)
+ }
+ return cf, cf.Err()
+}
+
+// CheckZip reports whether the files contained in a zip file satisfy the name
+// and size constraints listed in the package documentation.
+//
+// CheckZip returns an error if the returned CheckedFiles does not describe
+// a valid module zip file (according to CheckedFiles.Err). The returned
+// CheckedFiles is still populated when an error is returned. CheckZip will
+// also return an error if the module path or version is malformed or if it
+// encounters an error reading the zip file.
+//
+// Note that CheckZip does not read individual files, so Unzip may still fail
+// when CheckZip is successful due to I/O errors.
+func CheckZip(m module.Version, zipFile string) (CheckedFiles, error) {
+ f, err := os.Open(zipFile)
+ if err != nil {
+ return CheckedFiles{}, err
+ }
+ defer f.Close()
+ _, cf, err := checkZip(m, f)
+ return cf, err
+}
+
+// checkZip implements checkZip and also returns the *zip.Reader. This is
+// used in Unzip to avoid redundant I/O.
+func checkZip(m module.Version, f *os.File) (*zip.Reader, CheckedFiles, error) {
+ // Make sure the module path and version are valid.
+ if vers := module.CanonicalVersion(m.Version); vers != m.Version {
+ return nil, CheckedFiles{}, fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers)
+ }
+ if err := module.Check(m.Path, m.Version); err != nil {
+ return nil, CheckedFiles{}, err
+ }
+
+ // Check the total file size.
+ info, err := f.Stat()
+ if err != nil {
+ return nil, CheckedFiles{}, err
+ }
+ zipSize := info.Size()
+ if zipSize > MaxZipFile {
+ cf := CheckedFiles{SizeError: fmt.Errorf("module zip file is too large (%d bytes; limit is %d bytes)", zipSize, MaxZipFile)}
+ return nil, cf, cf.Err()
+ }
+
+ // Check for valid file names, collisions.
+ var cf CheckedFiles
+ addError := func(zf *zip.File, err error) {
+ cf.Invalid = append(cf.Invalid, FileError{Path: zf.Name, Err: err})
+ }
+ z, err := zip.NewReader(f, zipSize)
+ if err != nil {
+ return nil, CheckedFiles{}, err
+ }
+ prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version)
+ collisions := make(collisionChecker)
+ var size int64
+ for _, zf := range z.File {
+ if !strings.HasPrefix(zf.Name, prefix) {
+ addError(zf, fmt.Errorf("path does not have prefix %q", prefix))
+ continue
}
+ name := zf.Name[len(prefix):]
+ if name == "" {
+ continue
+ }
+ isDir := strings.HasSuffix(name, "/")
+ if isDir {
+ name = name[:len(name)-1]
+ }
+ if path.Clean(name) != name {
+ addError(zf, errPathNotClean)
+ continue
+ }
+ if err := module.CheckFilePath(name); err != nil {
+ addError(zf, err)
+ continue
+ }
+ if err := collisions.check(name, isDir); err != nil {
+ addError(zf, err)
+ continue
+ }
+ if isDir {
+ continue
+ }
+ if base := path.Base(name); strings.EqualFold(base, "go.mod") {
+ if base != name {
+ addError(zf, fmt.Errorf("go.mod file not in module root directory"))
+ continue
+ }
+ if name != "go.mod" {
+ addError(zf, errGoModCase)
+ continue
+ }
+ }
+ sz := int64(zf.UncompressedSize64)
+ if sz >= 0 && MaxZipFile-size >= sz {
+ size += sz
+ } else if cf.SizeError == nil {
+ cf.SizeError = fmt.Errorf("total uncompressed size of module contents too large (max size is %d bytes)", MaxZipFile)
+ }
+ if name == "go.mod" && sz > MaxGoMod {
+ addError(zf, fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod))
+ continue
+ }
+ if name == "LICENSE" && sz > MaxLICENSE {
+ addError(zf, fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE))
+ continue
+ }
+ cf.Valid = append(cf.Valid, zf.Name)
+ }
+ return z, cf, cf.Err()
+}
+
+// Create builds a zip archive for module m from an abstract list of files
+// and writes it to w.
+//
+// Create verifies the restrictions described in the package documentation
+// and should not produce an archive that Unzip cannot extract. Create does not
+// include files in the output archive if they don't belong in the module zip.
+// In particular, Create will not include files in modules found in
+// subdirectories, most files in vendor directories, or irregular files (such
+// as symbolic links) in the output archive.
+func Create(w io.Writer, m module.Version, files []File) (err error) {
+ defer func() {
+ if err != nil {
+ err = &zipError{verb: "create zip", err: err}
+ }
+ }()
+
+ // Check that the version is canonical, the module path is well-formed, and
+ // the major version suffix matches the major version.
+ if vers := module.CanonicalVersion(m.Version); vers != m.Version {
+ return fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers)
+ }
+ if err := module.Check(m.Path, m.Version); err != nil {
+ return err
+ }
+
+ // Check whether files are valid, not valid, or should be omitted.
+ // Also check that the valid files don't exceed the maximum size.
+ cf, validFiles, validSizes := checkFiles(files)
+ if err := cf.Err(); err != nil {
+ return err
+ }
+
+ // Create the module zip file.
+ zw := zip.NewWriter(w)
+ prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version)
+
+ addFile := func(f File, path string, size int64) error {
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close()
+ w, err := zw.Create(prefix + path)
+ if err != nil {
+ return err
+ }
+ lr := &io.LimitedReader{R: rc, N: size + 1}
+ if _, err := io.Copy(w, lr); err != nil {
+ return err
+ }
+ if lr.N <= 0 {
+ return fmt.Errorf("file %q is larger than declared size", path)
+ }
+ return nil
+ }
+
+ for i, f := range validFiles {
+ p := f.Path()
+ size := validSizes[i]
if err := addFile(f, p, size); err != nil {
return err
}
@@ -245,61 +555,7 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
}
}()
- var files []File
- err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- relPath, err := filepath.Rel(dir, filePath)
- if err != nil {
- return err
- }
- slashPath := filepath.ToSlash(relPath)
-
- if info.IsDir() {
- if filePath == dir {
- // Don't skip the top-level directory.
- return nil
- }
-
- // Skip VCS directories.
- // fossil repos are regular files with arbitrary names, so we don't try
- // to exclude them.
- switch filepath.Base(filePath) {
- case ".bzr", ".git", ".hg", ".svn":
- return filepath.SkipDir
- }
-
- // Skip some subdirectories inside vendor, but maintain bug
- // golang.org/issue/31562, described in isVendoredPackage.
- // We would like Create and CreateFromDir to produce the same result
- // for a set of files, whether expressed as a directory tree or zip.
- if isVendoredPackage(slashPath) {
- return filepath.SkipDir
- }
-
- // Skip submodules (directories containing go.mod files).
- if goModInfo, err := os.Lstat(filepath.Join(filePath, "go.mod")); err == nil && !goModInfo.IsDir() {
- return filepath.SkipDir
- }
- return nil
- }
-
- if info.Mode().IsRegular() {
- if !isVendoredPackage(slashPath) {
- files = append(files, dirFile{
- filePath: filePath,
- slashPath: slashPath,
- info: info,
- })
- }
- return nil
- }
-
- // Not a regular file or a directory. Probably a symbolic link.
- // Irregular files are ignored, so skip it.
- return nil
- })
+ files, _, err := listFilesInDir(dir)
if err != nil {
return err
}
@@ -356,89 +612,28 @@ func Unzip(dir string, m module.Version, zipFile string) (err error) {
}
}()
- if vers := module.CanonicalVersion(m.Version); vers != m.Version {
- return fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers)
- }
- if err := module.Check(m.Path, m.Version); err != nil {
- return err
- }
-
// Check that the directory is empty. Don't create it yet in case there's
// an error reading the zip.
- files, _ := ioutil.ReadDir(dir)
- if len(files) > 0 {
+ if files, _ := ioutil.ReadDir(dir); len(files) > 0 {
return fmt.Errorf("target directory %v exists and is not empty", dir)
}
- // Open the zip file and ensure it's under the size limit.
+ // Open the zip and check that it satisfies all restrictions.
f, err := os.Open(zipFile)
if err != nil {
return err
}
defer f.Close()
- info, err := f.Stat()
+ z, cf, err := checkZip(m, f)
if err != nil {
return err
}
- zipSize := info.Size()
- if zipSize > MaxZipFile {
- return fmt.Errorf("module zip file is too large (%d bytes; limit is %d bytes)", zipSize, MaxZipFile)
- }
-
- z, err := zip.NewReader(f, zipSize)
- if err != nil {
+ if err := cf.Err(); err != nil {
return err
}
- // Check total size, valid file names.
- collisions := make(collisionChecker)
+ // Unzip, enforcing sizes declared in the zip file.
prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version)
- var size int64
- for _, zf := range z.File {
- if !strings.HasPrefix(zf.Name, prefix) {
- return fmt.Errorf("unexpected file name %s", zf.Name)
- }
- name := zf.Name[len(prefix):]
- if name == "" {
- continue
- }
- isDir := strings.HasSuffix(name, "/")
- if isDir {
- name = name[:len(name)-1]
- }
- if path.Clean(name) != name {
- return fmt.Errorf("invalid file name %s", zf.Name)
- }
- if err := module.CheckFilePath(name); err != nil {
- return err
- }
- if err := collisions.check(name, isDir); err != nil {
- return err
- }
- if isDir {
- continue
- }
- if base := path.Base(name); strings.EqualFold(base, "go.mod") {
- if base != name {
- return fmt.Errorf("found go.mod file not in module root directory (%s)", zf.Name)
- } else if name != "go.mod" {
- return fmt.Errorf("found file named %s, want all lower-case go.mod", zf.Name)
- }
- }
- s := int64(zf.UncompressedSize64)
- if s < 0 || MaxZipFile-size < s {
- return fmt.Errorf("total uncompressed size of module contents too large (max size is %d bytes)", MaxZipFile)
- }
- size += s
- if name == "go.mod" && s > MaxGoMod {
- return fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod)
- }
- if name == "LICENSE" && s > MaxLICENSE {
- return fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE)
- }
- }
-
- // Unzip, enforcing sizes checked earlier.
if err := os.MkdirAll(dir, 0777); err != nil {
return err
}
@@ -515,6 +710,72 @@ func (cc collisionChecker) check(p string, isDir bool) error {
return nil
}
+// listFilesInDir walks the directory tree rooted at dir and returns a list of
+// files, as well as a list of directories and files that were skipped (for
+// example, nested modules and symbolic links).
+func listFilesInDir(dir string) (files []File, omitted []FileError, err error) {
+ err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ relPath, err := filepath.Rel(dir, filePath)
+ if err != nil {
+ return err
+ }
+ slashPath := filepath.ToSlash(relPath)
+
+ // Skip some subdirectories inside vendor, but maintain bug
+ // golang.org/issue/31562, described in isVendoredPackage.
+ // We would like Create and CreateFromDir to produce the same result
+ // for a set of files, whether expressed as a directory tree or zip.
+ if isVendoredPackage(slashPath) {
+ omitted = append(omitted, FileError{Path: slashPath, Err: errVendored})
+ return nil
+ }
+
+ if info.IsDir() {
+ if filePath == dir {
+ // Don't skip the top-level directory.
+ return nil
+ }
+
+ // Skip VCS directories.
+ // fossil repos are regular files with arbitrary names, so we don't try
+ // to exclude them.
+ switch filepath.Base(filePath) {
+ case ".bzr", ".git", ".hg", ".svn":
+ omitted = append(omitted, FileError{Path: slashPath, Err: errVCS})
+ return filepath.SkipDir
+ }
+
+ // Skip submodules (directories containing go.mod files).
+ if goModInfo, err := os.Lstat(filepath.Join(filePath, "go.mod")); err == nil && !goModInfo.IsDir() {
+ omitted = append(omitted, FileError{Path: slashPath, Err: errSubmoduleDir})
+ return filepath.SkipDir
+ }
+ return nil
+ }
+
+ // Skip irregular files and files in vendor directories.
+ // Irregular files are ignored. They're typically symbolic links.
+ if !info.Mode().IsRegular() {
+ omitted = append(omitted, FileError{Path: slashPath, Err: errNotRegular})
+ return nil
+ }
+
+ files = append(files, dirFile{
+ filePath: filePath,
+ slashPath: slashPath,
+ info: info,
+ })
+ return nil
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+ return files, omitted, nil
+}
+
type zipError struct {
verb, path string
err error
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..f0b15051c5 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
}
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/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/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 7272f04ff3..c827365400 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -29,7 +29,7 @@ golang.org/x/arch/x86/x86asm
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.20200625141748-0b26df4a2231
+# golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449
## explicit
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile
@@ -45,7 +45,7 @@ golang.org/x/mod/zip
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-20200901153117-6e59e24738da
## explicit
golang.org/x/tools/go/analysis
golang.org/x/tools/go/analysis/internal/analysisflags
@@ -84,6 +84,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/tools/internal/lsp/fuzzy
# golang.org/x/xerrors v0.0.0-20200806184451-1a77d5e9f316
## explicit
golang.org/x/xerrors
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 8ce57fb1ec..49ac059a0e 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -14,7 +14,6 @@ import (
"crypto/elliptic"
"crypto/rsa"
"crypto/sha1"
- _ "crypto/sha1"
_ "crypto/sha256"
_ "crypto/sha512"
"crypto/x509/pkix"
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 0b85db66b9..e3580698fd 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -869,6 +869,13 @@ func (db *DB) maxIdleConnsLocked() int {
}
func (db *DB) shortestIdleTimeLocked() time.Duration {
+ if db.maxIdleTime <= 0 {
+ return db.maxLifetime
+ }
+ if db.maxLifetime <= 0 {
+ return db.maxIdleTime
+ }
+
min := db.maxIdleTime
if min > db.maxLifetime {
min = db.maxLifetime
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 1e863ef78e..cd5bf8fab0 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -628,23 +628,14 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
}
}
-// relocSymbolTargetOK decides whether we should try to apply a
+// canApplyRelocation reports whether we should try to apply a
// relocation to a DWARF data section, given a pointer to the symbol
-// targeted by the relocation. Most relocations in DWARF data tend to
-// be section-relative, but some target non-section symbols (for
-// example, low_PC attrs on subprogram or compilation unit DIEs that
-// target function symbols), and we need to include these as well.
-// Return value is a pair (X,Y) where X is a boolean indicating
-// whether the relocation is needed, and Y is the symbol value in the
-// case of a non-section relocation that needs to be applied.
-func relocSymbolTargetOK(sym *Symbol) (bool, uint64) {
- if ST_TYPE(sym.Info) == STT_SECTION {
- return true, 0
- }
- if sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE {
- return true, sym.Value
- }
- return false, 0
+// targeted by the relocation.
+// Most relocations in DWARF data tend to be section-relative, but
+// some target non-section symbols (for example, low_PC attrs on
+// subprogram or compilation unit DIEs that target function symbols).
+func canApplyRelocation(sym *Symbol) bool {
+ return sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE
}
func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
@@ -670,8 +661,7 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -684,13 +674,13 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_X86_64_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -796,8 +786,7 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -810,13 +799,13 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := uint64(val) + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_AARCH64_ABS32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -847,8 +836,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -857,7 +845,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -888,8 +876,7 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -898,13 +885,13 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_PPC64_ADDR32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -980,8 +967,7 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -990,13 +976,13 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_MIPS_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1027,8 +1013,7 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1037,13 +1022,13 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_RISCV_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1074,8 +1059,7 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1084,13 +1068,13 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_390_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1121,8 +1105,7 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1131,13 +1114,13 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_SPARC_32, R_SPARC_UA32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go
index b13d13ebf0..24948e696a 100644
--- a/src/debug/elf/file_test.go
+++ b/src/debug/elf/file_test.go
@@ -293,6 +293,7 @@ func decompress(gz string) (io.ReaderAt, error) {
type relocationTestEntry struct {
entryNumber int
entry *dwarf.Entry
+ pcRanges [][2]uint64
}
type relocationTest struct {
@@ -304,367 +305,481 @@ var relocationTests = []relocationTest{
{
"testdata/go-relocation-test-gcc441-x86-64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x6}},
+ },
},
},
{
"testdata/go-relocation-test-gcc441-x86.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x5}},
+ },
},
},
{
"testdata/go-relocation-test-gcc424-x86-64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x6}},
+ },
},
},
{
"testdata/go-relocation-test-gcc482-aarch64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x24}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-arm.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x28}},
+ },
},
},
{
"testdata/go-relocation-test-clang-arm.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x30}},
+ },
},
},
{
"testdata/go-relocation-test-gcc5-ppc.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x44}},
+ },
},
},
{
"testdata/go-relocation-test-gcc482-ppc64le.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x24}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-mips64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x64}},
+ },
},
},
{
"testdata/go-relocation-test-gcc531-s390x.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x3a}},
+ },
},
},
{
"testdata/go-relocation-test-gcc620-sparc64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x2c}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-mipsle.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x58}},
+ },
},
},
{
"testdata/go-relocation-test-gcc540-mips.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x5c}},
+ },
},
},
{
"testdata/go-relocation-test-gcc493-mips64le.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x64}},
+ },
},
},
{
"testdata/go-relocation-test-gcc720-riscv64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x2c}},
+ },
},
},
{
"testdata/go-relocation-test-clang-x86.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ },
},
- }},
+ },
},
},
{
"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
[]relocationTestEntry{
- {203, &dwarf.Entry{
- Offset: 0xc62,
- Tag: dwarf.TagMember,
- Children: false,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
- {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
- {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
+ {
+ entryNumber: 203,
+ entry: &dwarf.Entry{
+ Offset: 0xc62,
+ Tag: dwarf.TagMember,
+ Children: false,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
+ {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
+ },
},
- }},
- {204, &dwarf.Entry{
- Offset: 0xc70,
- Tag: dwarf.TagMember,
- Children: false,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
- {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
- {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
+ },
+ {
+ entryNumber: 204,
+ entry: &dwarf.Entry{
+ Offset: 0xc70,
+ Tag: dwarf.TagMember,
+ Children: false,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
+ {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
+ },
},
- }},
+ },
+ },
+ },
+ {
+ "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64",
+ []relocationTestEntry{
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
+ },
+ pcRanges: [][2]uint64{
+ {0x765, 0x777},
+ {0x7e1, 0x7ec},
+ },
+ },
+ },
+ },
+ {
+ "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64",
+ []relocationTestEntry{
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
+ },
+ pcRanges: [][2]uint64{
+ {0x765, 0x777},
+ {0x7e1, 0x7ec},
+ },
+ },
},
},
}
func TestDWARFRelocations(t *testing.T) {
- for i, test := range relocationTests {
- f, err := Open(test.file)
- if err != nil {
- t.Error(err)
- continue
- }
- dwarf, err := f.DWARF()
- if err != nil {
- t.Error(err)
- continue
- }
- for _, testEntry := range test.entries {
- reader := dwarf.Reader()
- for j := 0; j < testEntry.entryNumber; j++ {
- entry, err := reader.Next()
- if entry == nil || err != nil {
- t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
- continue
- }
+ for _, test := range relocationTests {
+ test := test
+ t.Run(test.file, func(t *testing.T) {
+ t.Parallel()
+ f, err := Open(test.file)
+ if err != nil {
+ t.Fatal(err)
}
- entry, err := reader.Next()
+ dwarf, err := f.DWARF()
if err != nil {
- t.Error(err)
- continue
+ t.Fatal(err)
}
- if !reflect.DeepEqual(testEntry.entry, entry) {
- t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
- continue
+ reader := dwarf.Reader()
+ idx := 0
+ for _, testEntry := range test.entries {
+ if testEntry.entryNumber < idx {
+ t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx)
+ }
+ for ; idx < testEntry.entryNumber; idx++ {
+ entry, err := reader.Next()
+ if entry == nil || err != nil {
+ t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
+ }
+ }
+ entry, err := reader.Next()
+ idx++
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(testEntry.entry, entry) {
+ t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry)
+ }
+ pcRanges, err := dwarf.Ranges(entry)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
+ t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges)
+ }
}
- }
+ })
}
}
diff --git a/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64 b/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64
new file mode 100644
index 0000000000..c013f3e081
--- /dev/null
+++ b/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64
Binary files differ
diff --git a/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64 b/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64
new file mode 100644
index 0000000000..51e03aa7b0
--- /dev/null
+++ b/src/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64
Binary files differ
diff --git a/src/debug/elf/testdata/multiple-code-sections.c b/src/debug/elf/testdata/multiple-code-sections.c
new file mode 100644
index 0000000000..03b9d53ab9
--- /dev/null
+++ b/src/debug/elf/testdata/multiple-code-sections.c
@@ -0,0 +1,28 @@
+// 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 with:
+// gcc -g multiple-code-sections.c -Wl,--emit-relocs -Wl,--discard-none -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-with-rela-x86-64
+// gcc -g multiple-code-sections.c -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-no-rela-x86-64
+// Strip with:
+// strip --only-keep-debug \
+// --remove-section=.eh_frame \
+// --remove-section=.eh_frame_hdr \
+// --remove-section=.shstrtab \
+// --remove-section=.strtab \
+// --remove-section=.symtab \
+// --remove-section=.note.gnu.build-id \
+// --remove-section=.note.ABI-tag \
+// --remove-section=.dynamic \
+// --remove-section=.gnu.hash \
+// --remove-section=.interp \
+// --remove-section=.rodata
+__attribute__((section(".separate_section"))) // To get GCC to emit a DW_AT_ranges attribute for the CU.
+int func(void) {
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/src/encoding/binary/varint.go b/src/encoding/binary/varint.go
index 38af61075c..1fa325dec7 100644
--- a/src/encoding/binary/varint.go
+++ b/src/encoding/binary/varint.go
@@ -62,7 +62,7 @@ func Uvarint(buf []byte) (uint64, int) {
var s uint
for i, b := range buf {
if b < 0x80 {
- if i > 9 || i == 9 && b > 1 {
+ if i >= MaxVarintLen64 || i == MaxVarintLen64-1 && b > 1 {
return 0, -(i + 1) // overflow
}
return x | uint64(b)<<s, i + 1
@@ -112,7 +112,7 @@ func ReadUvarint(r io.ByteReader) (uint64, error) {
return x, err
}
if b < 0x80 {
- if i == 9 && b > 1 {
+ if i == MaxVarintLen64-1 && b > 1 {
return x, overflow
}
return x | uint64(b)<<s, nil
diff --git a/src/go.mod b/src/go.mod
index b002f8e516..0d5892f178 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -4,7 +4,7 @@ go 1.15
require (
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
- golang.org/x/net v0.0.0-20200707034311-ab3426394381
+ golang.org/x/net v0.0.0-20200904194848-62affa334b73
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
golang.org/x/text v0.3.3-0.20200430171850-afb9336c4530 // indirect
)
diff --git a/src/go.sum b/src/go.sum
index 528f7e460e..52907d313f 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -2,8 +2,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
+golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
index 81c64589d0..1061f1d3ce 100644
--- a/src/go/ast/ast.go
+++ b/src/go/ast/ast.go
@@ -285,6 +285,12 @@ type (
}
// A BasicLit node represents a literal of basic type.
+ //
+ // Note that for the CHAR and STRING kinds, the literal is stored
+ // with its quotes. For example, for a double-quoted STRING, the
+ // first and the last rune in the Value field will be ". The
+ // Unquote and UnquoteChar functions in the strconv package can be
+ // used to unquote STRING and CHAR values, respectively.
BasicLit struct {
ValuePos token.Pos // literal position
Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
diff --git a/src/go/build/build.go b/src/go/build/build.go
index 4a5da308a0..39bc3591a7 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -793,6 +793,12 @@ Found:
if d.IsDir() {
continue
}
+ if (d.Mode() & os.ModeSymlink) != 0 {
+ if fi, err := os.Stat(filepath.Join(p.Dir, d.Name())); err == nil && fi.IsDir() {
+ // Symlinks to directories are not source files.
+ continue
+ }
+ }
name := d.Name()
ext := nameExt(name)
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index 798c09bbff..75cebc9826 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -1243,6 +1243,9 @@ func TestConvertibleTo(t *testing.T) {
{newDefined(new(Struct)), new(Struct), true},
{newDefined(Typ[Int]), new(Struct), false},
{Typ[UntypedInt], Typ[Int], true},
+ // Untyped string values are not permitted by the spec, so the below
+ // behavior is undefined.
+ {Typ[UntypedString], Typ[String], true},
} {
if got := ConvertibleTo(test.v, test.t); got != test.want {
t.Errorf("ConvertibleTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want)
@@ -1260,6 +1263,12 @@ func TestAssignableTo(t *testing.T) {
{newDefined(Typ[Int]), Typ[Int], false},
{newDefined(new(Struct)), new(Struct), true},
{Typ[UntypedBool], Typ[Bool], true},
+ {Typ[UntypedString], Typ[Bool], false},
+ // Neither untyped string nor untyped numeric assignments arise during
+ // normal type checking, so the below behavior is technically undefined by
+ // the spec.
+ {Typ[UntypedString], Typ[String], true},
+ {Typ[UntypedInt], Typ[Int], true},
} {
if got := AssignableTo(test.v, test.t); got != test.want {
t.Errorf("AssignableTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want)
diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go
index 34a9d7843d..4e8ec278fc 100644
--- a/src/go/types/assignments.go
+++ b/src/go/types/assignments.go
@@ -7,6 +7,7 @@
package types
import (
+ "errors"
"go/ast"
"go/token"
)
@@ -33,8 +34,8 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
// spec: "If an untyped constant is assigned to a variable of interface
// type or the blank identifier, the constant is first converted to type
// bool, rune, int, float64, complex128 or string respectively, depending
- // on whether the value is a boolean, rune, integer, floating-point, complex,
- // or string constant."
+ // on whether the value is a boolean, rune, integer, floating-point,
+ // complex, or string constant."
if T == nil || IsInterface(T) {
if T == nil && x.typ == Typ[UntypedNil] {
check.errorf(x.pos(), "use of untyped nil in %s", context)
@@ -43,8 +44,16 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
}
target = Default(x.typ)
}
- check.convertUntyped(x, target)
- if x.mode == invalid {
+ if err := check.canConvertUntyped(x, target); err != nil {
+ var internalErr Error
+ var msg string
+ if errors.As(err, &internalErr) {
+ msg = internalErr.Msg
+ } else {
+ msg = err.Error()
+ }
+ check.errorf(x.pos(), "cannot use %s as %s value in %s: %v", x, target, context, msg)
+ x.mode = invalid
return
}
}
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index 89122d75ff..e01c3de13b 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -34,6 +34,7 @@ import (
"go/token"
"internal/testenv"
"io/ioutil"
+ "path/filepath"
"regexp"
"strings"
"testing"
@@ -93,11 +94,6 @@ var tests = [][]string{
{"testdata/issues.src"},
{"testdata/blank.src"},
{"testdata/issue25008b.src", "testdata/issue25008a.src"}, // order (b before a) is crucial!
- {"testdata/issue26390.src"}, // stand-alone test to ensure case is triggered
- {"testdata/issue23203a.src"},
- {"testdata/issue23203b.src"},
- {"testdata/issue28251.src"},
- {"testdata/issue6977.src"},
}
var fset = token.NewFileSet()
@@ -259,7 +255,7 @@ func checkFiles(t *testing.T, testfiles []string) {
// typecheck and collect typechecker errors
var conf Config
// special case for importC.src
- if len(testfiles) == 1 && testfiles[0] == "testdata/importC.src" {
+ if len(testfiles) == 1 && strings.HasSuffix(testfiles[0], "importC.src") {
conf.FakeImportC = true
}
conf.Importer = importer.Default()
@@ -316,3 +312,27 @@ func TestCheck(t *testing.T) {
checkFiles(t, files)
}
}
+
+func TestFixedBugs(t *testing.T) { testDir(t, "fixedbugs") }
+
+func testDir(t *testing.T, dir string) {
+ testenv.MustHaveGoBuild(t)
+
+ fis, err := ioutil.ReadDir(dir)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, fi := range fis {
+ testname := filepath.Base(fi.Name())
+ testname = strings.TrimSuffix(testname, filepath.Ext(testname))
+ t.Run(testname, func(t *testing.T) {
+ filename := filepath.Join(dir, fi.Name())
+ if fi.IsDir() {
+ t.Errorf("skipped directory %q", filename)
+ return
+ }
+ checkFiles(t, []string{filename})
+ })
+ }
+}
diff --git a/src/go/types/errors.go b/src/go/types/errors.go
index 91b077163c..88e41c5713 100644
--- a/src/go/types/errors.go
+++ b/src/go/types/errors.go
@@ -7,6 +7,7 @@
package types
import (
+ "errors"
"fmt"
"go/ast"
"go/token"
@@ -72,22 +73,33 @@ func (check *Checker) dump(format string, args ...interface{}) {
fmt.Println(check.sprintf(format, args...))
}
-func (check *Checker) err(pos token.Pos, msg string, soft bool) {
+func (check *Checker) err(err error) {
+ if err == nil {
+ return
+ }
+ var e Error
+ isInternal := errors.As(err, &e)
// Cheap trick: Don't report errors with messages containing
// "invalid operand" or "invalid type" as those tend to be
// follow-on errors which don't add useful information. Only
// exclude them if these strings are not at the beginning,
// and only if we have at least one error already reported.
- if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) {
+ isInvalidErr := isInternal && (strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0)
+ if check.firstErr != nil && isInvalidErr {
return
}
- err := Error{check.fset, pos, msg, soft}
if check.firstErr == nil {
check.firstErr = err
}
if trace {
+ pos := e.Pos
+ msg := e.Msg
+ if !isInternal {
+ msg = err.Error()
+ pos = token.NoPos
+ }
check.trace(pos, "ERROR: %s", msg)
}
@@ -99,15 +111,30 @@ func (check *Checker) err(pos token.Pos, msg string, soft bool) {
}
func (check *Checker) error(pos token.Pos, msg string) {
- check.err(pos, msg, false)
+ check.err(Error{Fset: check.fset, Pos: pos, Msg: msg})
+}
+
+// newErrorf creates a new Error, but does not handle it.
+func (check *Checker) newErrorf(pos token.Pos, format string, args ...interface{}) error {
+ return Error{
+ Fset: check.fset,
+ Pos: pos,
+ Msg: check.sprintf(format, args...),
+ Soft: false,
+ }
}
func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) {
- check.err(pos, check.sprintf(format, args...), false)
+ check.error(pos, check.sprintf(format, args...))
}
func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
- check.err(pos, check.sprintf(format, args...), true)
+ check.err(Error{
+ Fset: check.fset,
+ Pos: pos,
+ Msg: check.sprintf(format, args...),
+ Soft: true,
+ })
}
func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index d1e892a9b7..94d98f0fbb 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -329,8 +329,16 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
return false
}
-// representable checks that a constant operand is representable in the given basic type.
+// representable checks that a constant operand is representable in the given
+// basic type.
func (check *Checker) representable(x *operand, typ *Basic) {
+ if err := check.isRepresentable(x, typ); err != nil {
+ x.mode = invalid
+ check.err(err)
+ }
+}
+
+func (check *Checker) isRepresentable(x *operand, typ *Basic) error {
assert(x.mode == constant_)
if !representableConst(x.val, check, typ, &x.val) {
var msg string
@@ -350,9 +358,9 @@ func (check *Checker) representable(x *operand, typ *Basic) {
} else {
msg = "cannot convert %s to %s"
}
- check.errorf(x.pos(), msg, x, typ)
- x.mode = invalid
+ return check.newErrorf(x.pos(), msg, x, typ)
}
+ return nil
}
// updateExprType updates the type of x to typ and invokes itself
@@ -488,12 +496,16 @@ func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
// convertUntyped attempts to set the type of an untyped value to the target type.
func (check *Checker) convertUntyped(x *operand, target Type) {
- if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
- return
+ if err := check.canConvertUntyped(x, target); err != nil {
+ x.mode = invalid
+ check.err(err)
}
+}
- // TODO(gri) Sloppy code - clean up. This function is central
- // to assignment and expression checking.
+func (check *Checker) canConvertUntyped(x *operand, target Type) error {
+ if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
+ return nil
+ }
if isUntyped(target) {
// both x and target are untyped
@@ -505,82 +517,91 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
check.updateExprType(x.expr, target, false)
}
} else if xkind != tkind {
- goto Error
+ return check.newErrorf(x.pos(), "cannot convert %s to %s", x, target)
}
- return
+ return nil
+ }
+
+ if t, ok := target.Underlying().(*Basic); ok && x.mode == constant_ {
+ if err := check.isRepresentable(x, t); err != nil {
+ return err
+ }
+ // Expression value may have been rounded - update if needed.
+ check.updateExprVal(x.expr, x.val)
+ } else {
+ newTarget := check.implicitType(x, target)
+ if newTarget == nil {
+ return check.newErrorf(x.pos(), "cannot convert %s to %s", x, target)
+ }
+ target = newTarget
}
+ x.typ = target
+ // Even though implicitType can return UntypedNil, this value is final: the
+ // predeclared identifier nil has no type.
+ check.updateExprType(x.expr, target, true)
+ return nil
+}
- // typed target
+// implicitType returns the implicit type of x when used in a context where the
+// target type is expected. If no such implicit conversion is possible, it
+// returns nil.
+func (check *Checker) implicitType(x *operand, target Type) Type {
+ assert(isUntyped(x.typ))
switch t := target.Underlying().(type) {
case *Basic:
- if x.mode == constant_ {
- check.representable(x, t)
- if x.mode == invalid {
- return
+ assert(x.mode != constant_)
+ // Non-constant untyped values may appear as the
+ // result of comparisons (untyped bool), intermediate
+ // (delayed-checked) rhs operands of shifts, and as
+ // the value nil.
+ switch x.typ.(*Basic).kind {
+ case UntypedBool:
+ if !isBoolean(target) {
+ return nil
}
- // expression value may have been rounded - update if needed
- check.updateExprVal(x.expr, x.val)
- } else {
- // Non-constant untyped values may appear as the
- // result of comparisons (untyped bool), intermediate
- // (delayed-checked) rhs operands of shifts, and as
- // the value nil.
- switch x.typ.(*Basic).kind {
- case UntypedBool:
- if !isBoolean(target) {
- goto Error
- }
- case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
- if !isNumeric(target) {
- goto Error
- }
- case UntypedString:
- // Non-constant untyped string values are not
- // permitted by the spec and should not occur.
- unreachable()
- case UntypedNil:
- // Unsafe.Pointer is a basic type that includes nil.
- if !hasNil(target) {
- goto Error
- }
- default:
- goto Error
+ case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
+ if !isNumeric(target) {
+ return nil
+ }
+ case UntypedString:
+ // Non-constant untyped string values are not permitted by the spec and
+ // should not occur during normal typechecking passes, but this path is
+ // reachable via the AssignableTo API.
+ if !isString(target) {
+ return nil
+ }
+ case UntypedNil:
+ // Unsafe.Pointer is a basic type that includes nil.
+ if !hasNil(target) {
+ return nil
}
+ default:
+ return nil
}
case *Interface:
- // Update operand types to the default type rather then
- // the target (interface) type: values must have concrete
- // dynamic types. If the value is nil, keep it untyped
- // (this is important for tools such as go vet which need
- // the dynamic type for argument checking of say, print
+ // Values must have concrete dynamic types. If the value is nil,
+ // keep it untyped (this is important for tools such as go vet which
+ // need the dynamic type for argument checking of say, print
// functions)
if x.isNil() {
- target = Typ[UntypedNil]
- } else {
- // cannot assign untyped values to non-empty interfaces
- check.completeInterface(t)
- if !t.Empty() {
- goto Error
- }
- target = Default(x.typ)
+ return Typ[UntypedNil]
+ }
+ // cannot assign untyped values to non-empty interfaces
+ check.completeInterface(t)
+ if !t.Empty() {
+ return nil
}
+ return Default(x.typ)
case *Pointer, *Signature, *Slice, *Map, *Chan:
if !x.isNil() {
- goto Error
+ return nil
}
- // keep nil untyped - see comment for interfaces, above
- target = Typ[UntypedNil]
+ // Keep nil untyped - see comment for interfaces, above.
+ return Typ[UntypedNil]
default:
- goto Error
+ return nil
}
-
- x.typ = target
- check.updateExprType(x.expr, target, true) // UntypedNils are final
- return
-
-Error:
- check.errorf(x.pos(), "cannot convert %s to %s", x, target)
- x.mode = invalid
+ return target
}
func (check *Checker) comparison(x, y *operand, op token.Token) {
diff --git a/src/go/types/testdata/issue23203a.src b/src/go/types/fixedbugs/issue23203a.src
index 48cb5889cd..48cb5889cd 100644
--- a/src/go/types/testdata/issue23203a.src
+++ b/src/go/types/fixedbugs/issue23203a.src
diff --git a/src/go/types/testdata/issue23203b.src b/src/go/types/fixedbugs/issue23203b.src
index 638ec6c5ce..638ec6c5ce 100644
--- a/src/go/types/testdata/issue23203b.src
+++ b/src/go/types/fixedbugs/issue23203b.src
diff --git a/src/go/types/testdata/issue26390.src b/src/go/types/fixedbugs/issue26390.src
index b8e67e9bdd..9e0101f581 100644
--- a/src/go/types/testdata/issue26390.src
+++ b/src/go/types/fixedbugs/issue26390.src
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// stand-alone test to ensure case is triggered
+
package issue26390
type A = T
diff --git a/src/go/types/testdata/issue28251.src b/src/go/types/fixedbugs/issue28251.src
index cd79e0e8b5..cd79e0e8b5 100644
--- a/src/go/types/testdata/issue28251.src
+++ b/src/go/types/fixedbugs/issue28251.src
diff --git a/src/go/types/testdata/issue6977.src b/src/go/types/fixedbugs/issue6977.src
index 8f4e9ba2b2..8f4e9ba2b2 100644
--- a/src/go/types/testdata/issue6977.src
+++ b/src/go/types/fixedbugs/issue6977.src
diff --git a/src/go/types/operand.go b/src/go/types/operand.go
index 80d11e2f21..6fbfe09627 100644
--- a/src/go/types/operand.go
+++ b/src/go/types/operand.go
@@ -205,15 +205,11 @@ func (x *operand) isNil() bool {
return x.mode == value && x.typ == Typ[UntypedNil]
}
-// TODO(gri) The functions operand.assignableTo, checker.convertUntyped,
-// checker.representable, and checker.assignment are
-// overlapping in functionality. Need to simplify and clean up.
-
-// assignableTo reports whether x is assignable to a variable of type T.
-// If the result is false and a non-nil reason is provided, it may be set
-// to a more detailed explanation of the failure (result != "").
-// The check parameter may be nil if assignableTo is invoked through
-// an exported API call, i.e., when all methods have been type-checked.
+// assignableTo reports whether x is assignable to a variable of type T. If the
+// result is false and a non-nil reason is provided, it may be set to a more
+// detailed explanation of the failure (result != ""). The check parameter may
+// be nil if assignableTo is invoked through an exported API call, i.e., when
+// all methods have been type-checked.
func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool {
if x.mode == invalid || T == Typ[Invalid] {
return true // avoid spurious errors
@@ -229,34 +225,17 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool {
Vu := V.Underlying()
Tu := T.Underlying()
- // x is an untyped value representable by a value of type T
- // TODO(gri) This is borrowing from checker.convertUntyped and
- // checker.representable. Need to clean up.
+ // x is an untyped value representable by a value of type T.
if isUntyped(Vu) {
- switch t := Tu.(type) {
- case *Basic:
- if x.isNil() && t.kind == UnsafePointer {
- return true
- }
- if x.mode == constant_ {
- return representableConst(x.val, check, t, nil)
- }
- // The result of a comparison is an untyped boolean,
- // but may not be a constant.
- if Vb, _ := Vu.(*Basic); Vb != nil {
- return Vb.kind == UntypedBool && isBoolean(Tu)
- }
- case *Interface:
- check.completeInterface(t)
- return x.isNil() || t.Empty()
- case *Pointer, *Signature, *Slice, *Map, *Chan:
- return x.isNil()
+ if t, ok := Tu.(*Basic); ok && x.mode == constant_ {
+ return representableConst(x.val, check, t, nil)
}
+ return check.implicitType(x, Tu) != nil
}
// Vu is typed
- // x's type V and T have identical underlying types
- // and at least one of V or T is not a named type
+ // x's type V and T have identical underlying types and at least one of V or
+ // T is not a named type.
if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
return true
}
diff --git a/src/go/types/self_test.go b/src/go/types/self_test.go
index 10ad06fbca..04c9cd3458 100644
--- a/src/go/types/self_test.go
+++ b/src/go/types/self_test.go
@@ -47,8 +47,13 @@ func TestBenchmark(t *testing.T) {
// We're not using testing's benchmarking mechanism directly
// because we want custom output.
- for _, p := range []string{"types", "constant", filepath.Join("internal", "gcimporter")} {
- path := filepath.Join("..", p)
+ for _, p := range []string{
+ "net/http",
+ "go/parser",
+ "go/constant",
+ filepath.Join("go", "internal", "gcimporter"),
+ } {
+ path := filepath.Join("..", "..", p)
runbench(t, path, false)
runbench(t, path, true)
fmt.Println()
@@ -64,8 +69,13 @@ func runbench(t *testing.T, path string, ignoreFuncBodies bool) {
b := testing.Benchmark(func(b *testing.B) {
for i := 0; i < b.N; i++ {
- conf := Config{IgnoreFuncBodies: ignoreFuncBodies}
- conf.Check(path, fset, files, nil)
+ conf := Config{
+ IgnoreFuncBodies: ignoreFuncBodies,
+ Importer: importer.Default(),
+ }
+ if _, err := conf.Check(path, fset, files, nil); err != nil {
+ t.Fatal(err)
+ }
}
})
@@ -77,10 +87,9 @@ func runbench(t *testing.T, path string, ignoreFuncBodies bool) {
})
d := time.Duration(b.NsPerOp())
- fmt.Printf(
- "%s: %s for %d lines (%d lines/s), ignoreFuncBodies = %v\n",
- filepath.Base(path), d, lines, int64(float64(lines)/d.Seconds()), ignoreFuncBodies,
- )
+ fmt.Printf("%s (ignoreFuncBodies = %v):\n", filepath.Base(path), ignoreFuncBodies)
+ fmt.Printf("\t%s for %d lines (%.0f lines/s)\n", d, lines, float64(lines)/d.Seconds())
+ fmt.Printf("\t%s\n", b.MemString())
}
func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) {
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index 51ee0b1c36..f5a3273fa1 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -27,22 +27,21 @@ import (
. "go/types"
)
-var (
- pkgCount int // number of packages processed
- start time.Time
-
- // Use the same importer for all std lib tests to
- // avoid repeated importing of the same packages.
- stdLibImporter = importer.Default()
-)
+// Use the same importer for all std lib tests to
+// avoid repeated importing of the same packages.
+var stdLibImporter = importer.Default()
func TestStdlib(t *testing.T) {
testenv.MustHaveGoBuild(t)
- start = time.Now()
- walkDirs(t, filepath.Join(runtime.GOROOT(), "src"))
+ pkgCount := 0
+ duration := walkPkgDirs(filepath.Join(runtime.GOROOT(), "src"), func(dir string, filenames []string) {
+ typecheck(t, dir, filenames)
+ pkgCount++
+ }, t.Error)
+
if testing.Verbose() {
- fmt.Println(pkgCount, "packages typechecked in", time.Since(start))
+ fmt.Println(pkgCount, "packages typechecked in", duration)
}
}
@@ -235,7 +234,6 @@ func typecheck(t *testing.T, path string, filenames []string) {
}
info := Info{Uses: make(map[*ast.Ident]Object)}
conf.Check(path, fset, files, &info)
- pkgCount++
// Perform checks of API invariants.
@@ -278,39 +276,48 @@ func pkgFilenames(dir string) ([]string, error) {
return filenames, nil
}
-// Note: Could use filepath.Walk instead of walkDirs but that wouldn't
-// necessarily be shorter or clearer after adding the code to
-// terminate early for -short tests.
+func walkPkgDirs(dir string, pkgh func(dir string, filenames []string), errh func(args ...interface{})) time.Duration {
+ w := walker{time.Now(), 10 * time.Millisecond, pkgh, errh}
+ w.walk(dir)
+ return time.Since(w.start)
+}
-func walkDirs(t *testing.T, dir string) {
+type walker struct {
+ start time.Time
+ dmax time.Duration
+ pkgh func(dir string, filenames []string)
+ errh func(args ...interface{})
+}
+
+func (w *walker) walk(dir string) {
// limit run time for short tests
- if testing.Short() && time.Since(start) >= 10*time.Millisecond {
+ if testing.Short() && time.Since(w.start) >= w.dmax {
return
}
fis, err := ioutil.ReadDir(dir)
if err != nil {
- t.Error(err)
+ w.errh(err)
return
}
- // typecheck package in directory
+ // apply pkgh to the files in directory dir
// but ignore files directly under $GOROOT/src (might be temporary test files).
if dir != filepath.Join(runtime.GOROOT(), "src") {
files, err := pkgFilenames(dir)
if err != nil {
- t.Error(err)
+ w.errh(err)
return
}
if files != nil {
- typecheck(t, dir, files)
+ w.pkgh(dir, files)
}
}
// traverse subdirectories, but don't walk into testdata
for _, fi := range fis {
if fi.IsDir() && fi.Name() != "testdata" {
- walkDirs(t, filepath.Join(dir, fi.Name()))
+ w.walk(filepath.Join(dir, fi.Name()))
}
}
}
diff --git a/src/go/types/testdata/shifts.src b/src/go/types/testdata/shifts.src
index ebc95ba4d7..c9a38ae169 100644
--- a/src/go/types/testdata/shifts.src
+++ b/src/go/types/testdata/shifts.src
@@ -193,14 +193,27 @@ func shifts6() {
_ = float32(1.0 /* ERROR "must be integer" */ <<s)
_ = float32(1.1 /* ERROR "must be integer" */ <<s)
+ _ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
+ // TODO(rfindley) Eliminate the redundant error here.
+ _ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
+
+ _ = int(1+0i<<0)
+ _ = int((1+0i)<<s)
+ _ = int(1.0<<s)
+ _ = int(complex(1, 0)<<s)
+ _ = int(float32/* ERROR "must be integer" */(1.0) <<s)
+ _ = int(1.1 /* ERROR must be integer */ <<s)
+ _ = int(( /* ERROR "must be integer" */ 1+1i) <<s)
+
+ _ = complex(1 /* ERROR "must be integer" */ <<s, 0)
+
var b []int
_ = append(b, 1<<s)
_ = append(b, 1.0<<s)
+ _ = append(b, (1+0i)<<s)
_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
-
- _ = append(b, 1<<s)
- _ = append(b, 1.0<<s) // should fail - see TODO in append code
- _ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
+ _ = append(b, (1 + 0i) <<s)
+ _ = append(b, ( /* ERROR "must be integer" */ 1 + 1i) <<s)
_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
@@ -379,4 +392,4 @@ func issue22969() {
var _ int8 = 0xff /* ERROR "overflows int8" */ << s
var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
-} \ No newline at end of file
+}
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
index f12dafa870..8739735cb7 100644
--- a/src/html/template/escape.go
+++ b/src/html/template/escape.go
@@ -124,6 +124,8 @@ func (e *escaper) escape(c context, n parse.Node) context {
switch n := n.(type) {
case *parse.ActionNode:
return e.escapeAction(c, n)
+ case *parse.CommentNode:
+ return c
case *parse.IfNode:
return e.escapeBranch(c, &n.BranchNode, "if")
case *parse.ListNode:
diff --git a/src/html/template/template_test.go b/src/html/template/template_test.go
index 86bd4db444..1f2c888bbe 100644
--- a/src/html/template/template_test.go
+++ b/src/html/template/template_test.go
@@ -10,6 +10,7 @@ import (
. "html/template"
"strings"
"testing"
+ "text/template/parse"
)
func TestTemplateClone(t *testing.T) {
@@ -160,6 +161,21 @@ func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) {
}
}
+func TestSkipEscapeComments(t *testing.T) {
+ c := newTestCase(t)
+ tr := parse.New("root")
+ tr.Mode = parse.ParseComments
+ newT, err := tr.Parse("{{/* A comment */}}{{ 1 }}{{/* Another comment */}}", "", "", make(map[string]*parse.Tree))
+ if err != nil {
+ t.Fatalf("Cannot parse template text: %v", err)
+ }
+ c.root, err = c.root.AddParseTree("root", newT)
+ if err != nil {
+ t.Fatalf("Cannot add parse tree to template: %v", err)
+ }
+ c.mustExecute(c.root, nil, "1")
+}
+
type testCase struct {
t *testing.T
root *Template
diff --git a/src/image/gif/writer_test.go b/src/image/gif/writer_test.go
index 5d1b2c439e..1e622b3674 100644
--- a/src/image/gif/writer_test.go
+++ b/src/image/gif/writer_test.go
@@ -658,27 +658,27 @@ func TestEncodeWrappedImage(t *testing.T) {
}
func BenchmarkEncodeRandomPaletted(b *testing.B) {
- img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette.Plan9)
+ paletted := image.NewPaletted(image.Rect(0, 0, 640, 480), palette.Plan9)
rnd := rand.New(rand.NewSource(123))
- for i := range img.Pix {
- img.Pix[i] = uint8(rnd.Intn(256))
+ for i := range paletted.Pix {
+ paletted.Pix[i] = uint8(rnd.Intn(256))
}
b.SetBytes(640 * 480 * 1)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- Encode(ioutil.Discard, img, nil)
+ Encode(ioutil.Discard, paletted, nil)
}
}
func BenchmarkEncodeRandomRGBA(b *testing.B) {
- img := image.NewRGBA(image.Rect(0, 0, 640, 480))
- bo := img.Bounds()
+ rgba := image.NewRGBA(image.Rect(0, 0, 640, 480))
+ bo := rgba.Bounds()
rnd := rand.New(rand.NewSource(123))
for y := bo.Min.Y; y < bo.Max.Y; y++ {
for x := bo.Min.X; x < bo.Max.X; x++ {
- img.SetRGBA(x, y, color.RGBA{
+ rgba.SetRGBA(x, y, color.RGBA{
uint8(rnd.Intn(256)),
uint8(rnd.Intn(256)),
uint8(rnd.Intn(256)),
@@ -691,24 +691,24 @@ func BenchmarkEncodeRandomRGBA(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- Encode(ioutil.Discard, img, nil)
+ Encode(ioutil.Discard, rgba, nil)
}
}
func BenchmarkEncodeRealisticPaletted(b *testing.B) {
- rgba, err := readImg("../testdata/video-001.png")
+ img, err := readImg("../testdata/video-001.png")
if err != nil {
b.Fatalf("readImg: %v", err)
}
- bo := rgba.Bounds()
- img := image.NewPaletted(bo, palette.Plan9)
- draw.Draw(img, bo, rgba, bo.Min, draw.Src)
+ bo := img.Bounds()
+ paletted := image.NewPaletted(bo, palette.Plan9)
+ draw.Draw(paletted, bo, img, bo.Min, draw.Src)
b.SetBytes(int64(bo.Dx() * bo.Dy() * 1))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- Encode(ioutil.Discard, img, nil)
+ Encode(ioutil.Discard, paletted, nil)
}
}
@@ -718,11 +718,17 @@ func BenchmarkEncodeRealisticRGBA(b *testing.B) {
b.Fatalf("readImg: %v", err)
}
bo := img.Bounds()
+ // Converting img to rgba is redundant for video-001.png, which is already
+ // in the RGBA format, but for those copy/pasting this benchmark (but
+ // changing the source image), the conversion ensures that we're still
+ // benchmarking encoding an RGBA image.
+ rgba := image.NewRGBA(bo)
+ draw.Draw(rgba, bo, img, bo.Min, draw.Src)
b.SetBytes(int64(bo.Dx() * bo.Dy() * 4))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- Encode(ioutil.Discard, img, nil)
+ Encode(ioutil.Discard, rgba, nil)
}
}
diff --git a/src/internal/testlog/exit.go b/src/internal/testlog/exit.go
new file mode 100644
index 0000000000..e15defdb5b
--- /dev/null
+++ b/src/internal/testlog/exit.go
@@ -0,0 +1,33 @@
+// 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 testlog
+
+import "sync"
+
+// PanicOnExit0 reports whether to panic on a call to os.Exit(0).
+// This is in the testlog package because, like other definitions in
+// package testlog, it is a hook between the testing package and the
+// os package. This is used to ensure that an early call to os.Exit(0)
+// does not cause a test to pass.
+func PanicOnExit0() bool {
+ panicOnExit0.mu.Lock()
+ defer panicOnExit0.mu.Unlock()
+ return panicOnExit0.val
+}
+
+// panicOnExit0 is the flag used for PanicOnExit0. This uses a lock
+// because the value can be cleared via a timer call that may race
+// with calls to os.Exit
+var panicOnExit0 struct {
+ mu sync.Mutex
+ val bool
+}
+
+// SetPanicOnExit0 sets panicOnExit0 to v.
+func SetPanicOnExit0(v bool) {
+ panicOnExit0.mu.Lock()
+ defer panicOnExit0.mu.Unlock()
+ panicOnExit0.val = v
+}
diff --git a/src/make.bash b/src/make.bash
index 880a0f43d5..3a84658c72 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -162,16 +162,16 @@ IFS=$'\n'; for go_exe in $(type -ap go); do
fi
fi
done; unset IFS
-GOROOT_BOOTSTRAP_VERSION=$($GOROOT_BOOTSTRAP/bin/go version | sed 's/go version //')
-echo "Building Go cmd/dist using $GOROOT_BOOTSTRAP. ($GOROOT_BOOTSTRAP_VERSION)"
-if $verbose; then
- echo cmd/dist
-fi
if [ ! -x "$GOROOT_BOOTSTRAP/bin/go" ]; then
echo "ERROR: Cannot find $GOROOT_BOOTSTRAP/bin/go." >&2
echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
exit 1
fi
+GOROOT_BOOTSTRAP_VERSION=$($GOROOT_BOOTSTRAP/bin/go version | sed 's/go version //')
+echo "Building Go cmd/dist using $GOROOT_BOOTSTRAP. ($GOROOT_BOOTSTRAP_VERSION)"
+if $verbose; then
+ echo cmd/dist
+fi
if [ "$GOROOT_BOOTSTRAP" = "$GOROOT" ]; then
echo "ERROR: \$GOROOT_BOOTSTRAP must not be set to \$GOROOT" >&2
echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
diff --git a/src/math/big/arith_arm64.s b/src/math/big/arith_arm64.s
index 18e513e2c3..da6e408e19 100644
--- a/src/math/big/arith_arm64.s
+++ b/src/math/big/arith_arm64.s
@@ -109,13 +109,59 @@ done:
MOVD R0, c+72(FP)
RET
+#define vwOneOp(instr, op1) \
+ MOVD.P 8(R1), R4; \
+ instr op1, R4; \
+ MOVD.P R4, 8(R3);
+
+// handle the first 1~4 elements before starting iteration in addVW/subVW
+#define vwPreIter(instr1, instr2, counter, target) \
+ vwOneOp(instr1, R2); \
+ SUB $1, counter; \
+ CBZ counter, target; \
+ vwOneOp(instr2, $0); \
+ SUB $1, counter; \
+ CBZ counter, target; \
+ vwOneOp(instr2, $0); \
+ SUB $1, counter; \
+ CBZ counter, target; \
+ vwOneOp(instr2, $0);
+
+// do one iteration of add or sub in addVW/subVW
+#define vwOneIter(instr, counter, exit) \
+ CBZ counter, exit; \ // careful not to touch the carry flag
+ LDP.P 32(R1), (R4, R5); \
+ LDP -16(R1), (R6, R7); \
+ instr $0, R4, R8; \
+ instr $0, R5, R9; \
+ instr $0, R6, R10; \
+ instr $0, R7, R11; \
+ STP.P (R8, R9), 32(R3); \
+ STP (R10, R11), -16(R3); \
+ SUB $4, counter;
+
+// do one iteration of copy in addVW/subVW
+#define vwOneIterCopy(counter, exit) \
+ CBZ counter, exit; \
+ LDP.P 32(R1), (R4, R5); \
+ LDP -16(R1), (R6, R7); \
+ STP.P (R4, R5), 32(R3); \
+ STP (R6, R7), -16(R3); \
+ SUB $4, counter;
// func addVW(z, x []Word, y Word) (c Word)
+// The 'large' branch handles large 'z'. It checks the carry flag on every iteration
+// and switches to copy if we are done with carries. The copying is skipped as well
+// if 'x' and 'z' happen to share the same underlying storage.
+// The overhead of the checking and branching is visible when 'z' are small (~5%),
+// so set a threshold of 32, and remain the small-sized part entirely untouched.
TEXT ·addVW(SB),NOSPLIT,$0
MOVD z+0(FP), R3
MOVD z_len+8(FP), R0
MOVD x+24(FP), R1
MOVD y+48(FP), R2
+ CMP $32, R0
+ BGE large // large-sized 'z' and 'x'
CBZ R0, len0 // the length of z is 0
MOVD.P 8(R1), R4
ADDS R2, R4 // z[0] = x[0] + y, set carry
@@ -135,29 +181,46 @@ two: // do it twice
STP.P (R8, R9), 16(R3)
SUB $2, R0
loop: // do four times per round
- CBZ R0, len1 // careful not to touch the carry flag
- LDP.P 32(R1), (R4, R5)
- LDP -16(R1), (R6, R7)
- ADCS $0, R4, R8
- ADCS $0, R5, R9
- ADCS $0, R6, R10
- ADCS $0, R7, R11
- STP.P (R8, R9), 32(R3)
- STP (R10, R11), -16(R3)
- SUB $4, R0
+ vwOneIter(ADCS, R0, len1)
B loop
len1:
CSET HS, R2 // extract carry flag
len0:
MOVD R2, c+56(FP)
+done:
RET
+large:
+ AND $0x3, R0, R10
+ AND $~0x3, R0
+ // unrolling for the first 1~4 elements to avoid saving the carry
+ // flag in each step, adjust $R0 if we unrolled 4 elements
+ vwPreIter(ADDS, ADCS, R10, add4)
+ SUB $4, R0
+add4:
+ BCC copy
+ vwOneIter(ADCS, R0, len1)
+ B add4
+copy:
+ MOVD ZR, c+56(FP)
+ CMP R1, R3
+ BEQ done
+copy_4: // no carry flag, copy the rest
+ vwOneIterCopy(R0, done)
+ B copy_4
// func subVW(z, x []Word, y Word) (c Word)
+// The 'large' branch handles large 'z'. It checks the carry flag on every iteration
+// and switches to copy if we are done with carries. The copying is skipped as well
+// if 'x' and 'z' happen to share the same underlying storage.
+// The overhead of the checking and branching is visible when 'z' are small (~5%),
+// so set a threshold of 32, and remain the small-sized part entirely untouched.
TEXT ·subVW(SB),NOSPLIT,$0
MOVD z+0(FP), R3
MOVD z_len+8(FP), R0
MOVD x+24(FP), R1
MOVD y+48(FP), R2
+ CMP $32, R0
+ BGE large // large-sized 'z' and 'x'
CBZ R0, len0 // the length of z is 0
MOVD.P 8(R1), R4
SUBS R2, R4 // z[0] = x[0] - y, set carry
@@ -177,22 +240,32 @@ two: // do it twice
STP.P (R8, R9), 16(R3)
SUB $2, R0
loop: // do four times per round
- CBZ R0, len1 // careful not to touch the carry flag
- LDP.P 32(R1), (R4, R5)
- LDP -16(R1), (R6, R7)
- SBCS $0, R4, R8
- SBCS $0, R5, R9
- SBCS $0, R6, R10
- SBCS $0, R7, R11
- STP.P (R8, R9), 32(R3)
- STP (R10, R11), -16(R3)
- SUB $4, R0
+ vwOneIter(SBCS, R0, len1)
B loop
len1:
CSET LO, R2 // extract carry flag
len0:
MOVD R2, c+56(FP)
+done:
RET
+large:
+ AND $0x3, R0, R10
+ AND $~0x3, R0
+ // unrolling for the first 1~4 elements to avoid saving the carry
+ // flag in each step, adjust $R0 if we unrolled 4 elements
+ vwPreIter(SUBS, SBCS, R10, sub4)
+ SUB $4, R0
+sub4:
+ BCS copy
+ vwOneIter(SBCS, R0, len1)
+ B sub4
+copy:
+ MOVD ZR, c+56(FP)
+ CMP R1, R3
+ BEQ done
+copy_4: // no carry flag, copy the rest
+ vwOneIterCopy(R0, done)
+ B copy_4
// func shlVU(z, x []Word, s uint) (c Word)
// This implementation handles the shift operation from the high word to the low word,
diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go
index 05136f1895..fc205934c5 100644
--- a/src/math/big/arith_test.go
+++ b/src/math/big/arith_test.go
@@ -179,6 +179,23 @@ func testFunVW(t *testing.T, msg string, f funVW, a argVW) {
}
}
+func testFunVWext(t *testing.T, msg string, f funVW, f_g funVW, a argVW) {
+ // using the result of addVW_g/subVW_g as golden
+ z_g := make(nat, len(a.z))
+ c_g := f_g(z_g, a.x, a.y)
+ c := f(a.z, a.x, a.y)
+
+ for i, zi := range a.z {
+ if zi != z_g[i] {
+ t.Errorf("%s\n\tgot z[%d] = %#x; want %#x", msg, i, zi, z_g[i])
+ break
+ }
+ }
+ if c != c_g {
+ t.Errorf("%s\n\tgot c = %#x; want %#x", msg, c, c_g)
+ }
+}
+
func makeFunVW(f func(z, x []Word, s uint) (c Word)) funVW {
return func(z, x []Word, s Word) (c Word) {
return f(z, x, uint(s))
@@ -213,6 +230,49 @@ func TestFunVW(t *testing.T) {
}
}
+// Construct a vector comprising the same word, usually '0' or 'maximum uint'
+func makeWordVec(e Word, n int) []Word {
+ v := make([]Word, n)
+ for i := range v {
+ v[i] = e
+ }
+ return v
+}
+
+// Extended testing to addVW and subVW using various kinds of input data.
+// We utilize the results of addVW_g and subVW_g as golden reference to check
+// correctness.
+func TestFunVWExt(t *testing.T) {
+ // 32 is the current threshold that triggers an optimized version of
+ // calculation for large-sized vector, ensure we have sizes around it tested.
+ var vwSizes = []int{0, 1, 3, 4, 5, 8, 9, 23, 31, 32, 33, 34, 35, 36, 50, 120}
+ for _, n := range vwSizes {
+ // vector of random numbers, using the result of addVW_g/subVW_g as golden
+ x := rndV(n)
+ y := rndW()
+ z := make(nat, n)
+ arg := argVW{z, x, y, 0}
+ testFunVWext(t, "addVW, random inputs", addVW, addVW_g, arg)
+ testFunVWext(t, "subVW, random inputs", subVW, subVW_g, arg)
+
+ // vector of random numbers, but make 'x' and 'z' share storage
+ arg = argVW{x, x, y, 0}
+ testFunVWext(t, "addVW, random inputs, sharing storage", addVW, addVW_g, arg)
+ testFunVWext(t, "subVW, random inputs, sharing storage", subVW, subVW_g, arg)
+
+ // vector of maximum uint, to force carry flag set in each 'add'
+ y = ^Word(0)
+ x = makeWordVec(y, n)
+ arg = argVW{z, x, y, 0}
+ testFunVWext(t, "addVW, vector of max uint", addVW, addVW_g, arg)
+
+ // vector of '0', to force carry flag set in each 'sub'
+ x = makeWordVec(0, n)
+ arg = argVW{z, x, 1, 0}
+ testFunVWext(t, "subVW, vector of zero", subVW, subVW_g, arg)
+ }
+}
+
type argVU struct {
d []Word // d is a Word slice, the input parameters x and z come from this array.
l uint // l is the length of the input parameters x and z.
@@ -241,20 +301,20 @@ var argshrVU = []argVU{
}
func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) {
- // save a.d for error message, or it will be overwritten.
+ // work on copy of a.d to preserve the original data.
b := make([]Word, len(a.d))
copy(b, a.d)
- z := a.d[a.zp : a.zp+a.l]
- x := a.d[a.xp : a.xp+a.l]
+ z := b[a.zp : a.zp+a.l]
+ x := b[a.xp : a.xp+a.l]
c := f(z, x, a.s)
for i, zi := range z {
if zi != a.r[i] {
- t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
+ t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
break
}
}
if c != a.c {
- t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
+ t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
}
}
@@ -299,6 +359,24 @@ func BenchmarkAddVW(b *testing.B) {
}
}
+// Benchmarking addVW using vector of maximum uint to force carry flag set
+func BenchmarkAddVWext(b *testing.B) {
+ for _, n := range benchSizes {
+ if isRaceBuilder && n > 1e3 {
+ continue
+ }
+ y := ^Word(0)
+ x := makeWordVec(y, n)
+ z := make([]Word, n)
+ b.Run(fmt.Sprint(n), func(b *testing.B) {
+ b.SetBytes(int64(n * _S))
+ for i := 0; i < b.N; i++ {
+ addVW(z, x, y)
+ }
+ })
+ }
+}
+
func BenchmarkSubVW(b *testing.B) {
for _, n := range benchSizes {
if isRaceBuilder && n > 1e3 {
@@ -316,6 +394,24 @@ func BenchmarkSubVW(b *testing.B) {
}
}
+// Benchmarking subVW using vector of zero to force carry flag set
+func BenchmarkSubVWext(b *testing.B) {
+ for _, n := range benchSizes {
+ if isRaceBuilder && n > 1e3 {
+ continue
+ }
+ x := makeWordVec(0, n)
+ y := Word(1)
+ z := make([]Word, n)
+ b.Run(fmt.Sprint(n), func(b *testing.B) {
+ b.SetBytes(int64(n * _S))
+ for i := 0; i < b.N; i++ {
+ subVW(z, x, y)
+ }
+ })
+ }
+}
+
type funVWW func(z, x []Word, y, r Word) (c Word)
type argVWW struct {
z, x nat
diff --git a/src/math/big/example_test.go b/src/math/big/example_test.go
index cfc77351d4..31ca784154 100644
--- a/src/math/big/example_test.go
+++ b/src/math/big/example_test.go
@@ -25,6 +25,13 @@ func ExampleInt_SetString() {
// Output: 420
}
+func ExampleFloat_SetString() {
+ f := new(big.Float)
+ f.SetString("3.14159")
+ fmt.Println(f)
+ // Output: 3.14159
+}
+
func ExampleRat_Scan() {
// The Scan function is rarely used directly;
// the fmt package recognizes it as an implementation of fmt.Scanner.
diff --git a/src/math/big/float.go b/src/math/big/float.go
index da964eef3e..42050e2c39 100644
--- a/src/math/big/float.go
+++ b/src/math/big/float.go
@@ -322,10 +322,11 @@ func (z *Float) SetMantExp(mant *Float, exp int) *Float {
mant.validate()
}
z.Copy(mant)
- if z.form != finite {
- return z
+
+ if z.form == finite {
+ // 0 < |mant| < +Inf
+ z.setExpAndRound(int64(z.exp)+int64(exp), 0)
}
- z.setExpAndRound(int64(z.exp)+int64(exp), 0)
return z
}
diff --git a/src/mime/example_test.go b/src/mime/example_test.go
index c7d13cdcdb..85795976f0 100644
--- a/src/mime/example_test.go
+++ b/src/mime/example_test.go
@@ -96,3 +96,29 @@ func ExampleWordDecoder_DecodeHeader() {
// ¡Hola, señor!
// HELLO WORLD!
}
+
+func ExampleFormatMediaType() {
+ mediatype := "text/html"
+ params := map[string]string{
+ "charset": "utf-8",
+ }
+
+ result := mime.FormatMediaType(mediatype, params)
+
+ fmt.Println("result:", result)
+ // Output:
+ // result: text/html; charset=utf-8
+}
+
+func ExampleParseMediaType() {
+ mediatype, params, err := mime.ParseMediaType("text/html; charset=utf-8")
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println("type:", mediatype)
+ fmt.Println("charset:", params["charset"])
+ // Output:
+ // type: text/html
+ // charset: utf-8
+}
diff --git a/src/net/error_test.go b/src/net/error_test.go
index 8d4a7ffb3d..62dfb9c15d 100644
--- a/src/net/error_test.go
+++ b/src/net/error_test.go
@@ -8,6 +8,7 @@ package net
import (
"context"
+ "errors"
"fmt"
"internal/poll"
"io"
@@ -101,7 +102,7 @@ second:
goto third
}
switch nestedErr {
- case errCanceled, poll.ErrNetClosing, errMissingAddress, errNoSuitableAddress,
+ case errCanceled, ErrClosed, errMissingAddress, errNoSuitableAddress,
context.DeadlineExceeded, context.Canceled:
return nil
}
@@ -436,7 +437,7 @@ second:
goto third
}
switch nestedErr {
- case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
+ case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
@@ -478,7 +479,7 @@ second:
goto third
}
switch nestedErr {
- case errCanceled, poll.ErrNetClosing, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF:
+ case errCanceled, ErrClosed, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
@@ -508,6 +509,10 @@ func parseCloseError(nestedErr error, isShutdown bool) error {
return fmt.Errorf("error string %q does not contain expected string %q", nestedErr, want)
}
+ if !isShutdown && !errors.Is(nestedErr, ErrClosed) {
+ return fmt.Errorf("errors.Is(%v, errClosed) returns false, want true", nestedErr)
+ }
+
switch err := nestedErr.(type) {
case *OpError:
if err := err.isValid(); err != nil {
@@ -531,7 +536,7 @@ second:
goto third
}
switch nestedErr {
- case poll.ErrNetClosing:
+ case ErrClosed:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
@@ -627,7 +632,7 @@ second:
goto third
}
switch nestedErr {
- case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
+ case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
@@ -706,7 +711,7 @@ second:
goto third
}
switch nestedErr {
- case poll.ErrNetClosing:
+ case ErrClosed:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
diff --git a/src/net/http/cgi/child.go b/src/net/http/cgi/child.go
index 9474175f17..d7d813e68a 100644
--- a/src/net/http/cgi/child.go
+++ b/src/net/http/cgi/child.go
@@ -146,6 +146,9 @@ func Serve(handler http.Handler) error {
if err != nil {
return err
}
+ if req.Body == nil {
+ req.Body = http.NoBody
+ }
if handler == nil {
handler = http.DefaultServeMux
}
diff --git a/src/net/http/cgi/integration_test.go b/src/net/http/cgi/integration_test.go
index 32d59c09a3..eaa090f6fe 100644
--- a/src/net/http/cgi/integration_test.go
+++ b/src/net/http/cgi/integration_test.go
@@ -152,6 +152,23 @@ func TestChildOnlyHeaders(t *testing.T) {
}
}
+// Test that a child handler does not receive a nil Request Body.
+// golang.org/issue/39190
+func TestNilRequestBody(t *testing.T) {
+ testenv.MustHaveExec(t)
+
+ h := &Handler{
+ Path: os.Args[0],
+ Root: "/test.go",
+ Args: []string{"-test.run=TestBeChildCGIProcess"},
+ }
+ expectedMap := map[string]string{
+ "nil-request-body": "false",
+ }
+ _ = runCgiTest(t, h, "POST /test.go?nil-request-body=1 HTTP/1.0\nHost: example.com\n\n", expectedMap)
+ _ = runCgiTest(t, h, "POST /test.go?nil-request-body=1 HTTP/1.0\nHost: example.com\nContent-Length: 0\n\n", expectedMap)
+}
+
// golang.org/issue/7198
func Test500WithNoHeaders(t *testing.T) { want500Test(t, "/immediate-disconnect") }
func Test500WithNoContentType(t *testing.T) { want500Test(t, "/no-content-type") }
@@ -198,6 +215,10 @@ func TestBeChildCGIProcess(t *testing.T) {
os.Exit(0)
}
Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+ if req.FormValue("nil-request-body") == "1" {
+ fmt.Fprintf(rw, "nil-request-body=%v\n", req.Body == nil)
+ return
+ }
rw.Header().Set("X-Test-Header", "X-Test-Value")
req.ParseForm()
if req.FormValue("no-body") == "1" {
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go
index 657ff9dba4..67a74ae19f 100644
--- a/src/net/http/export_test.go
+++ b/src/net/http/export_test.go
@@ -274,6 +274,17 @@ func (s *Server) ExportAllConnsIdle() bool {
return true
}
+func (s *Server) ExportAllConnsByState() map[ConnState]int {
+ states := map[ConnState]int{}
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ for c := range s.activeConn {
+ st, _ := c.getState()
+ states[st] += 1
+ }
+ return states
+}
+
func (r *Request) WithT(t *testing.T) *Request {
return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf))
}
diff --git a/src/net/http/fcgi/child.go b/src/net/http/fcgi/child.go
index 30a6b2ce2d..0e91042543 100644
--- a/src/net/http/fcgi/child.go
+++ b/src/net/http/fcgi/child.go
@@ -155,9 +155,12 @@ func (c *child) serve() {
defer c.cleanUp()
var rec record
for {
+ c.conn.mutex.Lock()
if err := rec.read(c.conn.rwc); err != nil {
+ c.conn.mutex.Unlock()
return
}
+ c.conn.mutex.Unlock()
if err := c.handleRecord(&rec); err != nil {
return
}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 922706ada1..d718fffba0 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -771,9 +771,15 @@ func parseRange(s string, size int64) ([]httpRange, error) {
var r httpRange
if start == "" {
// If no start is specified, end specifies the
- // range start relative to the end of the file.
+ // range start relative to the end of the file,
+ // and we are dealing with <suffix-length>
+ // which has to be a non-negative integer as per
+ // RFC 7233 Section 2.1 "Byte-Ranges".
+ if end == "" || end[0] == '-' {
+ return nil, errors.New("invalid range")
+ }
i, err := strconv.ParseInt(end, 10, 64)
- if err != nil {
+ if i < 0 || err != nil {
return nil, errors.New("invalid range")
}
if i > size {
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index c082ceee71..4ac73b728f 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -1136,6 +1136,14 @@ func TestLinuxSendfile(t *testing.T) {
t.Skipf("skipping; failed to run strace: %v", err)
}
+ filename := fmt.Sprintf("1kb-%d", os.Getpid())
+ filepath := path.Join(os.TempDir(), filename)
+
+ if err := ioutil.WriteFile(filepath, bytes.Repeat([]byte{'a'}, 1<<10), 0755); err != nil {
+ t.Fatal(err)
+ }
+ defer os.Remove(filepath)
+
var buf bytes.Buffer
child := exec.Command("strace", "-f", "-q", os.Args[0], "-test.run=TestLinuxSendfileChild")
child.ExtraFiles = append(child.ExtraFiles, lnf)
@@ -1146,7 +1154,7 @@ func TestLinuxSendfile(t *testing.T) {
t.Skipf("skipping; failed to start straced child: %v", err)
}
- res, err := Get(fmt.Sprintf("http://%s/", ln.Addr()))
+ res, err := Get(fmt.Sprintf("http://%s/%s", ln.Addr(), filename))
if err != nil {
t.Fatalf("http client error: %v", err)
}
@@ -1192,7 +1200,7 @@ func TestLinuxSendfileChild(*testing.T) {
panic(err)
}
mux := NewServeMux()
- mux.Handle("/", FileServer(Dir("testdata")))
+ mux.Handle("/", FileServer(Dir(os.TempDir())))
mux.HandleFunc("/quit", func(ResponseWriter, *Request) {
os.Exit(0)
})
@@ -1308,3 +1316,61 @@ func Test_scanETag(t *testing.T) {
}
}
}
+
+// Issue 40940: Ensure that we only accept non-negative suffix-lengths
+// in "Range": "bytes=-N", and should reject "bytes=--2".
+func TestServeFileRejectsInvalidSuffixLengths_h1(t *testing.T) {
+ testServeFileRejectsInvalidSuffixLengths(t, h1Mode)
+}
+func TestServeFileRejectsInvalidSuffixLengths_h2(t *testing.T) {
+ testServeFileRejectsInvalidSuffixLengths(t, h2Mode)
+}
+
+func testServeFileRejectsInvalidSuffixLengths(t *testing.T, h2 bool) {
+ defer afterTest(t)
+ cst := httptest.NewUnstartedServer(FileServer(Dir("testdata")))
+ cst.EnableHTTP2 = h2
+ cst.StartTLS()
+ defer cst.Close()
+
+ tests := []struct {
+ r string
+ wantCode int
+ wantBody string
+ }{
+ {"bytes=--6", 416, "invalid range\n"},
+ {"bytes=--0", 416, "invalid range\n"},
+ {"bytes=---0", 416, "invalid range\n"},
+ {"bytes=-6", 206, "hello\n"},
+ {"bytes=6-", 206, "html says hello\n"},
+ {"bytes=-6-", 416, "invalid range\n"},
+ {"bytes=-0", 206, ""},
+ {"bytes=", 200, "index.html says hello\n"},
+ }
+
+ for _, tt := range tests {
+ tt := tt
+ t.Run(tt.r, func(t *testing.T) {
+ req, err := NewRequest("GET", cst.URL+"/index.html", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ req.Header.Set("Range", tt.r)
+ res, err := cst.Client().Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if g, w := res.StatusCode, tt.wantCode; g != w {
+ t.Errorf("StatusCode mismatch: got %d want %d", g, w)
+ }
+ slurp, err := ioutil.ReadAll(res.Body)
+ res.Body.Close()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if g, w := string(slurp), tt.wantBody; g != w {
+ t.Fatalf("Content mismatch:\nGot: %q\nWant: %q", g, w)
+ }
+ })
+ }
+}
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 81c3671f85..458e0b7646 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -5591,7 +5591,11 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead
}
if bodyOpen {
if vv, ok := rp.header["Content-Length"]; ok {
- req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
+ if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
+ req.ContentLength = int64(cl)
+ } else {
+ req.ContentLength = 0
+ }
} else {
req.ContentLength = -1
}
@@ -5629,7 +5633,7 @@ func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2re
var trailer Header
for _, v := range rp.header["Trailer"] {
for _, key := range strings.Split(v, ",") {
- key = CanonicalHeaderKey(strings.TrimSpace(key))
+ key = CanonicalHeaderKey(textproto.TrimString(key))
switch key {
case "Transfer-Encoding", "Trailer", "Content-Length":
// Bogus. (copy of http1 rules)
@@ -5974,9 +5978,8 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
var ctype, clen string
if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
rws.snapHeader.Del("Content-Length")
- clen64, err := strconv.ParseInt(clen, 10, 64)
- if err == nil && clen64 >= 0 {
- rws.sentContentLen = clen64
+ if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
+ rws.sentContentLen = int64(cl)
} else {
clen = ""
}
@@ -6606,6 +6609,19 @@ type http2Transport struct {
// waiting for their turn.
StrictMaxConcurrentStreams bool
+ // ReadIdleTimeout is the timeout after which a health check using ping
+ // frame will be carried out if no frame is received on the connection.
+ // Note that a ping response will is considered a received frame, so if
+ // there is no other traffic on the connection, the health check will
+ // be performed every ReadIdleTimeout interval.
+ // If zero, no health check is performed.
+ ReadIdleTimeout time.Duration
+
+ // PingTimeout is the timeout after which the connection will be closed
+ // if a response to Ping is not received.
+ // Defaults to 15s.
+ PingTimeout time.Duration
+
// t1, if non-nil, is the standard library Transport using
// this transport. Its settings are used (but not its
// RoundTrip method, etc).
@@ -6629,6 +6645,14 @@ func (t *http2Transport) disableCompression() bool {
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
}
+func (t *http2Transport) pingTimeout() time.Duration {
+ if t.PingTimeout == 0 {
+ return 15 * time.Second
+ }
+ return t.PingTimeout
+
+}
+
// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
// It returns an error if t1 has already been HTTP/2-enabled.
func http2ConfigureTransport(t1 *Transport) error {
@@ -7174,6 +7198,20 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2Client
return cc, nil
}
+func (cc *http2ClientConn) healthCheck() {
+ pingTimeout := cc.t.pingTimeout()
+ // We don't need to periodically ping in the health check, because the readLoop of ClientConn will
+ // trigger the healthCheck again if there is no frame received.
+ ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
+ defer cancel()
+ err := cc.Ping(ctx)
+ if err != nil {
+ cc.closeForLostPing()
+ cc.t.connPool().MarkDead(cc)
+ return
+ }
+}
+
func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
cc.mu.Lock()
defer cc.mu.Unlock()
@@ -7345,14 +7383,12 @@ func (cc *http2ClientConn) sendGoAway() error {
return nil
}
-// Close closes the client connection immediately.
-//
-// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
-func (cc *http2ClientConn) Close() error {
+// closes the client connection immediately. In-flight requests are interrupted.
+// err is sent to streams.
+func (cc *http2ClientConn) closeForError(err error) error {
cc.mu.Lock()
defer cc.cond.Broadcast()
defer cc.mu.Unlock()
- err := errors.New("http2: client connection force closed via ClientConn.Close")
for id, cs := range cc.streams {
select {
case cs.resc <- http2resAndError{err: err}:
@@ -7365,6 +7401,20 @@ func (cc *http2ClientConn) Close() error {
return cc.tconn.Close()
}
+// Close closes the client connection immediately.
+//
+// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
+func (cc *http2ClientConn) Close() error {
+ err := errors.New("http2: client connection force closed via ClientConn.Close")
+ return cc.closeForError(err)
+}
+
+// closes the client connection immediately. In-flight requests are interrupted.
+func (cc *http2ClientConn) closeForLostPing() error {
+ err := errors.New("http2: client connection lost")
+ return cc.closeForError(err)
+}
+
const http2maxAllocFrameSize = 512 << 10
// frameBuffer returns a scratch buffer suitable for writing DATA frames.
@@ -8236,8 +8286,17 @@ func (rl *http2clientConnReadLoop) run() error {
rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
gotReply := false // ever saw a HEADERS reply
gotSettings := false
+ readIdleTimeout := cc.t.ReadIdleTimeout
+ var t *time.Timer
+ if readIdleTimeout != 0 {
+ t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
+ defer t.Stop()
+ }
for {
f, err := cc.fr.ReadFrame()
+ if t != nil {
+ t.Reset(readIdleTimeout)
+ }
if err != nil {
cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
}
@@ -8449,8 +8508,8 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http
if !streamEnded || isHead {
res.ContentLength = -1
if clens := res.Header["Content-Length"]; len(clens) == 1 {
- if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
- res.ContentLength = clen64
+ if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
+ res.ContentLength = int64(cl)
} else {
// TODO: care? unlike http/1, it won't mess up our framing, so it's
// more safe smuggling-wise to ignore.
@@ -8968,6 +9027,8 @@ func http2strSliceContains(ss []string, s string) bool {
type http2erringRoundTripper struct{ err error }
+func (rt http2erringRoundTripper) RoundTripErr() error { return rt.err }
+
func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
// gzipReader wraps a response body so it can lazily
diff --git a/src/net/http/omithttp2.go b/src/net/http/omithttp2.go
index 7e2f492579..c8f5c28a59 100644
--- a/src/net/http/omithttp2.go
+++ b/src/net/http/omithttp2.go
@@ -32,10 +32,6 @@ type http2Transport struct {
func (*http2Transport) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
func (*http2Transport) CloseIdleConnections() {}
-type http2erringRoundTripper struct{ err error }
-
-func (http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
-
type http2noDialH2RoundTripper struct{}
func (http2noDialH2RoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 5f56932778..6d3317fb0c 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -2849,29 +2849,47 @@ func TestStripPrefix(t *testing.T) {
defer afterTest(t)
h := HandlerFunc(func(w ResponseWriter, r *Request) {
w.Header().Set("X-Path", r.URL.Path)
+ w.Header().Set("X-RawPath", r.URL.RawPath)
})
- ts := httptest.NewServer(StripPrefix("/foo", h))
+ ts := httptest.NewServer(StripPrefix("/foo/bar", h))
defer ts.Close()
c := ts.Client()
- res, err := c.Get(ts.URL + "/foo/bar")
- if err != nil {
- t.Fatal(err)
- }
- if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
- t.Errorf("test 1: got %s, want %s", g, e)
- }
- res.Body.Close()
-
- res, err = Get(ts.URL + "/bar")
- if err != nil {
- t.Fatal(err)
- }
- if g, e := res.StatusCode, 404; g != e {
- t.Errorf("test 2: got status %v, want %v", g, e)
+ cases := []struct {
+ reqPath string
+ path string // If empty we want a 404.
+ rawPath string
+ }{
+ {"/foo/bar/qux", "/qux", ""},
+ {"/foo/bar%2Fqux", "/qux", "%2Fqux"},
+ {"/foo%2Fbar/qux", "", ""}, // Escaped prefix does not match.
+ {"/bar", "", ""}, // No prefix match.
+ }
+ for _, tc := range cases {
+ t.Run(tc.reqPath, func(t *testing.T) {
+ res, err := c.Get(ts.URL + tc.reqPath)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res.Body.Close()
+ if tc.path == "" {
+ if res.StatusCode != StatusNotFound {
+ t.Errorf("got %q, want 404 Not Found", res.Status)
+ }
+ return
+ }
+ if res.StatusCode != StatusOK {
+ t.Fatalf("got %q, want 200 OK", res.Status)
+ }
+ if g, w := res.Header.Get("X-Path"), tc.path; g != w {
+ t.Errorf("got Path %q, want %q", g, w)
+ }
+ if g, w := res.Header.Get("X-RawPath"), tc.rawPath; g != w {
+ t.Errorf("got RawPath %q, want %q", g, w)
+ }
+ })
}
- res.Body.Close()
}
// https://golang.org/issue/18952.
@@ -5519,16 +5537,23 @@ func TestServerSetKeepAlivesEnabledClosesConns(t *testing.T) {
}
}
-func TestServerShutdown_h1(t *testing.T) { testServerShutdown(t, h1Mode) }
-func TestServerShutdown_h2(t *testing.T) { testServerShutdown(t, h2Mode) }
+func TestServerShutdown_h1(t *testing.T) {
+ testServerShutdown(t, h1Mode)
+}
+func TestServerShutdown_h2(t *testing.T) {
+ testServerShutdown(t, h2Mode)
+}
func testServerShutdown(t *testing.T, h2 bool) {
setParallel(t)
defer afterTest(t)
var doShutdown func() // set later
+ var doStateCount func()
var shutdownRes = make(chan error, 1)
+ var statesRes = make(chan map[ConnState]int, 1)
var gotOnShutdown = make(chan struct{}, 1)
handler := HandlerFunc(func(w ResponseWriter, r *Request) {
+ doStateCount()
go doShutdown()
// Shutdown is graceful, so it should not interrupt
// this in-flight response. Add a tiny sleep here to
@@ -5545,6 +5570,9 @@ func testServerShutdown(t *testing.T, h2 bool) {
doShutdown = func() {
shutdownRes <- cst.ts.Config.Shutdown(context.Background())
}
+ doStateCount = func() {
+ statesRes <- cst.ts.Config.ExportAllConnsByState()
+ }
get(t, cst.c, cst.ts.URL) // calls t.Fail on failure
if err := <-shutdownRes; err != nil {
@@ -5556,6 +5584,10 @@ func testServerShutdown(t *testing.T, h2 bool) {
t.Errorf("onShutdown callback not called, RegisterOnShutdown broken?")
}
+ if states := <-statesRes; states[StateActive] != 1 {
+ t.Errorf("connection in wrong state, %v", states)
+ }
+
res, err := cst.c.Get(cst.ts.URL)
if err == nil {
res.Body.Close()
diff --git a/src/net/http/server.go b/src/net/http/server.go
index d41b5f6f48..25fab288f2 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -324,7 +324,7 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
}
}
- c.setState(rwc, StateHijacked)
+ c.setState(rwc, StateHijacked, runHooks)
return
}
@@ -561,51 +561,53 @@ type writerOnly struct {
io.Writer
}
-func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
- switch v := src.(type) {
- case *os.File:
- fi, err := v.Stat()
- if err != nil {
- return false, err
- }
- return fi.Mode().IsRegular(), nil
- case *io.LimitedReader:
- return srcIsRegularFile(v.R)
- default:
- return
- }
-}
-
// ReadFrom is here to optimize copying from an *os.File regular file
-// to a *net.TCPConn with sendfile.
+// to a *net.TCPConn with sendfile, or from a supported src type such
+// as a *net.TCPConn on Linux with splice.
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
+ bufp := copyBufPool.Get().(*[]byte)
+ buf := *bufp
+ defer copyBufPool.Put(bufp)
+
// Our underlying w.conn.rwc is usually a *TCPConn (with its
- // own ReadFrom method). If not, or if our src isn't a regular
- // file, just fall back to the normal copy method.
+ // own ReadFrom method). If not, just fall back to the normal
+ // copy method.
rf, ok := w.conn.rwc.(io.ReaderFrom)
- regFile, err := srcIsRegularFile(src)
- if err != nil {
- return 0, err
- }
- if !ok || !regFile {
- bufp := copyBufPool.Get().(*[]byte)
- defer copyBufPool.Put(bufp)
- return io.CopyBuffer(writerOnly{w}, src, *bufp)
+ if !ok {
+ return io.CopyBuffer(writerOnly{w}, src, buf)
}
// sendfile path:
- if !w.wroteHeader {
- w.WriteHeader(StatusOK)
- }
+ // Do not start actually writing response until src is readable.
+ // If body length is <= sniffLen, sendfile/splice path will do
+ // little anyway. This small read also satisfies sniffing the
+ // body in case Content-Type is missing.
+ nr, er := src.Read(buf[:sniffLen])
+ atEOF := errors.Is(er, io.EOF)
+ n += int64(nr)
- if w.needsSniff() {
- n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
- n += n0
- if err != nil {
- return n, err
+ if nr > 0 {
+ // Write the small amount read normally.
+ nw, ew := w.Write(buf[:nr])
+ if ew != nil {
+ err = ew
+ } else if nr != nw {
+ err = io.ErrShortWrite
}
}
+ if err == nil && er != nil && !atEOF {
+ err = er
+ }
+
+ // Do not send StatusOK in the error case where nothing has been written.
+ if err == nil && !w.wroteHeader {
+ w.WriteHeader(StatusOK) // nr == 0, no error (or EOF)
+ }
+
+ if err != nil || atEOF {
+ return n, err
+ }
w.w.Flush() // get rid of any previous writes
w.cw.flush() // make sure Header is written; flush data to rwc
@@ -1737,7 +1739,12 @@ func validNextProto(proto string) bool {
return true
}
-func (c *conn) setState(nc net.Conn, state ConnState) {
+const (
+ runHooks = true
+ skipHooks = false
+)
+
+func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
srv := c.server
switch state {
case StateNew:
@@ -1750,6 +1757,9 @@ func (c *conn) setState(nc net.Conn, state ConnState) {
}
packedState := uint64(time.Now().Unix()<<8) | uint64(state)
atomic.StoreUint64(&c.curState.atomic, packedState)
+ if !runHook {
+ return
+ }
if hook := srv.ConnState; hook != nil {
hook(nc, state)
}
@@ -1803,7 +1813,7 @@ func (c *conn) serve(ctx context.Context) {
}
if !c.hijacked() {
c.close()
- c.setState(c.rwc, StateClosed)
+ c.setState(c.rwc, StateClosed, runHooks)
}
}()
@@ -1831,6 +1841,10 @@ func (c *conn) serve(ctx context.Context) {
if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) {
if fn := c.server.TLSNextProto[proto]; fn != nil {
h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
+ // Mark freshly created HTTP/2 as active and prevent any server state hooks
+ // from being run on these connections. This prevents closeIdleConns from
+ // closing such connections. See issue https://golang.org/issue/39776.
+ c.setState(c.rwc, StateActive, skipHooks)
fn(c.server, tlsConn, h)
}
return
@@ -1851,7 +1865,7 @@ func (c *conn) serve(ctx context.Context) {
w, err := c.readRequest(ctx)
if c.r.remain != c.server.initialReadLimitSize() {
// If we read any bytes off the wire, we're active.
- c.setState(c.rwc, StateActive)
+ c.setState(c.rwc, StateActive, runHooks)
}
if err != nil {
const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
@@ -1934,7 +1948,7 @@ func (c *conn) serve(ctx context.Context) {
}
return
}
- c.setState(c.rwc, StateIdle)
+ c.setState(c.rwc, StateIdle, runHooks)
c.curReq.Store((*response)(nil))
if !w.conn.server.doKeepAlives() {
@@ -2062,22 +2076,26 @@ func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", Sta
// that replies to each request with a ``404 page not found'' reply.
func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
-// StripPrefix returns a handler that serves HTTP requests
-// by removing the given prefix from the request URL's Path
-// and invoking the handler h. StripPrefix handles a
-// request for a path that doesn't begin with prefix by
-// replying with an HTTP 404 not found error.
+// StripPrefix returns a handler that serves HTTP requests by removing the
+// given prefix from the request URL's Path (and RawPath if set) and invoking
+// the handler h. StripPrefix handles a request for a path that doesn't begin
+// with prefix by replying with an HTTP 404 not found error. The prefix must
+// match exactly: if the prefix in the request contains escaped characters
+// the reply is also an HTTP 404 not found error.
func StripPrefix(prefix string, h Handler) Handler {
if prefix == "" {
return h
}
return HandlerFunc(func(w ResponseWriter, r *Request) {
- if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
+ p := strings.TrimPrefix(r.URL.Path, prefix)
+ rp := strings.TrimPrefix(r.URL.RawPath, prefix)
+ if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) {
r2 := new(Request)
*r2 = *r
r2.URL = new(url.URL)
*r2.URL = *r.URL
r2.URL.Path = p
+ r2.URL.RawPath = rp
h.ServeHTTP(w, r2)
} else {
NotFound(w, r)
@@ -2965,7 +2983,7 @@ func (srv *Server) Serve(l net.Listener) error {
}
tempDelay = 0
c := srv.newConn(rw)
- c.setState(c.rwc, StateNew) // before Serve can return
+ c.setState(c.rwc, StateNew, runHooks) // before Serve can return
go c.serve(connCtx)
}
}
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index d37b52b13d..b97c4268b5 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -1528,6 +1528,10 @@ func (pconn *persistConn) addTLS(name string, trace *httptrace.ClientTrace) erro
return nil
}
+type erringRoundTripper interface {
+ RoundTripErr() error
+}
+
func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
pconn = &persistConn{
t: t,
@@ -1694,9 +1698,9 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" {
if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok {
alt := next(cm.targetAddr, pconn.conn.(*tls.Conn))
- if e, ok := alt.(http2erringRoundTripper); ok {
+ if e, ok := alt.(erringRoundTripper); ok {
// pconn.conn was closed by next (http2configureTransport.upgradeFn).
- return nil, e.err
+ return nil, e.RoundTripErr()
}
return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil
}
@@ -1963,6 +1967,15 @@ func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritte
return nil
}
+ // Wait for the writeLoop goroutine to terminate to avoid data
+ // races on callers who mutate the request on failure.
+ //
+ // When resc in pc.roundTrip and hence rc.ch receives a responseAndError
+ // with a non-nil error it implies that the persistConn is either closed
+ // or closing. Waiting on pc.writeLoopDone is hence safe as all callers
+ // close closech which in turn ensures writeLoop returns.
+ <-pc.writeLoopDone
+
// If the request was canceled, that's better than network
// failures that were likely the result of tearing down the
// connection.
@@ -1988,7 +2001,6 @@ func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritte
return err
}
if pc.isBroken() {
- <-pc.writeLoopDone
if pc.nwrite == startBytesWritten {
return nothingWrittenError{err}
}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 2d9ca10bf0..f4b7623630 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -25,6 +25,7 @@ import (
"io"
"io/ioutil"
"log"
+ mrand "math/rand"
"net"
. "net/http"
"net/http/httptest"
@@ -6284,3 +6285,101 @@ func TestTransportRejectsSignInContentLength(t *testing.T) {
t.Fatalf("Error mismatch\nGot: %q\nWanted substring: %q", got, want)
}
}
+
+// dumpConn is a net.Conn which writes to Writer and reads from Reader
+type dumpConn struct {
+ io.Writer
+ io.Reader
+}
+
+func (c *dumpConn) Close() error { return nil }
+func (c *dumpConn) LocalAddr() net.Addr { return nil }
+func (c *dumpConn) RemoteAddr() net.Addr { return nil }
+func (c *dumpConn) SetDeadline(t time.Time) error { return nil }
+func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil }
+func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
+
+// delegateReader is a reader that delegates to another reader,
+// once it arrives on a channel.
+type delegateReader struct {
+ c chan io.Reader
+ r io.Reader // nil until received from c
+}
+
+func (r *delegateReader) Read(p []byte) (int, error) {
+ if r.r == nil {
+ var ok bool
+ if r.r, ok = <-r.c; !ok {
+ return 0, errors.New("delegate closed")
+ }
+ }
+ return r.r.Read(p)
+}
+
+func testTransportRace(req *Request) {
+ save := req.Body
+ pr, pw := io.Pipe()
+ defer pr.Close()
+ defer pw.Close()
+ dr := &delegateReader{c: make(chan io.Reader)}
+
+ t := &Transport{
+ Dial: func(net, addr string) (net.Conn, error) {
+ return &dumpConn{pw, dr}, nil
+ },
+ }
+ defer t.CloseIdleConnections()
+
+ quitReadCh := make(chan struct{})
+ // Wait for the request before replying with a dummy response:
+ go func() {
+ defer close(quitReadCh)
+
+ req, err := ReadRequest(bufio.NewReader(pr))
+ if err == nil {
+ // Ensure all the body is read; otherwise
+ // we'll get a partial dump.
+ io.Copy(ioutil.Discard, req.Body)
+ req.Body.Close()
+ }
+ select {
+ case dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n"):
+ case quitReadCh <- struct{}{}:
+ // Ensure delegate is closed so Read doesn't block forever.
+ close(dr.c)
+ }
+ }()
+
+ t.RoundTrip(req)
+
+ // Ensure the reader returns before we reset req.Body to prevent
+ // a data race on req.Body.
+ pw.Close()
+ <-quitReadCh
+
+ req.Body = save
+}
+
+// Issue 37669
+// Test that a cancellation doesn't result in a data race due to the writeLoop
+// goroutine being left running, if the caller mutates the processed Request
+// upon completion.
+func TestErrorWriteLoopRace(t *testing.T) {
+ if testing.Short() {
+ return
+ }
+ t.Parallel()
+ for i := 0; i < 1000; i++ {
+ delay := time.Duration(mrand.Intn(5)) * time.Millisecond
+ ctx, cancel := context.WithTimeout(context.Background(), delay)
+ defer cancel()
+
+ r := bytes.NewBuffer(make([]byte, 10000))
+ req, err := NewRequestWithContext(ctx, MethodPost, "http://example.com", r)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ testTransportRace(req)
+ }
+}
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 6833cfaec1..09fb794005 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -279,9 +279,6 @@ func (p *addrParser) parseAddressList() ([]*Address, error) {
if p.consume(',') {
continue
}
- if p.empty() {
- break
- }
addrs, err := p.parseAddress(true)
if err != nil {
@@ -295,9 +292,17 @@ func (p *addrParser) parseAddressList() ([]*Address, error) {
if p.empty() {
break
}
- if !p.consume(',') {
+ if p.peek() != ',' {
return nil, errors.New("mail: expected comma")
}
+
+ // Skip empty entries for obs-addr-list.
+ for p.consume(',') {
+ p.skipSpace()
+ }
+ if p.empty() {
+ break
+ }
}
return list, nil
}
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
index 75db767547..67e3643aeb 100644
--- a/src/net/mail/message_test.go
+++ b/src/net/mail/message_test.go
@@ -446,6 +446,19 @@ func TestAddressParsing(t *testing.T) {
},
},
{
+ ` , joe@where.test,,John <jdoe@one.test>,,`,
+ []*Address{
+ {
+ Name: "",
+ Address: "joe@where.test",
+ },
+ {
+ Name: "John",
+ Address: "jdoe@one.test",
+ },
+ },
+ },
+ {
`Group1: <addr1@example.com>;, Group 2: addr2@example.com;, John <addr3@example.com>`,
[]*Address{
{
@@ -1067,3 +1080,22 @@ func TestAddressFormattingAndParsing(t *testing.T) {
}
}
}
+
+func TestEmptyAddress(t *testing.T) {
+ parsed, err := ParseAddress("")
+ if parsed != nil || err == nil {
+ t.Errorf(`ParseAddress("") = %v, %v, want nil, error`, parsed, err)
+ }
+ list, err := ParseAddressList("")
+ if len(list) > 0 || err == nil {
+ t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
+ }
+ list, err = ParseAddressList(",")
+ if len(list) > 0 || err == nil {
+ t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
+ }
+ list, err = ParseAddressList("a@b c@d")
+ if len(list) > 0 || err == nil {
+ t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
+ }
+}
diff --git a/src/net/net.go b/src/net/net.go
index 2e61a7c02e..4b4ed129cc 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -81,6 +81,7 @@ package net
import (
"context"
"errors"
+ "internal/poll"
"io"
"os"
"sync"
@@ -632,6 +633,17 @@ func (e *DNSError) Timeout() bool { return e.IsTimeout }
// error and return a DNSError for which Temporary returns false.
func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
+// errClosed exists just so that the docs for ErrClosed don't mention
+// the internal package poll.
+var errClosed = poll.ErrNetClosing
+
+// ErrClosed is the error returned by an I/O call on a network
+// connection that has already been closed, or that is closed by
+// another goroutine before the I/O is completed. This may be wrapped
+// in another error, and should normally be tested using
+// errors.Is(err, net.ErrClosed).
+var ErrClosed = errClosed
+
type writerOnly struct {
io.Writer
}
diff --git a/src/net/smtp/smtp.go b/src/net/smtp/smtp.go
index e4e12ae5ee..1a6864a0f2 100644
--- a/src/net/smtp/smtp.go
+++ b/src/net/smtp/smtp.go
@@ -241,7 +241,8 @@ func (c *Client) Auth(a Auth) error {
// Mail issues a MAIL command to the server using the provided email address.
// If the server supports the 8BITMIME extension, Mail adds the BODY=8BITMIME
-// parameter.
+// parameter. If the server supports the SMTPUTF8 extension, Mail adds the
+// SMTPUTF8 parameter.
// This initiates a mail transaction and is followed by one or more Rcpt calls.
func (c *Client) Mail(from string) error {
if err := validateLine(from); err != nil {
@@ -255,6 +256,9 @@ func (c *Client) Mail(from string) error {
if _, ok := c.ext["8BITMIME"]; ok {
cmdStr += " BODY=8BITMIME"
}
+ if _, ok := c.ext["SMTPUTF8"]; ok {
+ cmdStr += " SMTPUTF8"
+ }
}
_, _, err := c.cmd(250, cmdStr, from)
return err
diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
index cfda0790e9..55219372d2 100644
--- a/src/net/smtp/smtp_test.go
+++ b/src/net/smtp/smtp_test.go
@@ -288,6 +288,219 @@ Goodbye.
QUIT
`
+func TestExtensions(t *testing.T) {
+ fake := func(server string) (c *Client, bcmdbuf *bufio.Writer, cmdbuf *strings.Builder) {
+ server = strings.Join(strings.Split(server, "\n"), "\r\n")
+
+ cmdbuf = &strings.Builder{}
+ bcmdbuf = bufio.NewWriter(cmdbuf)
+ var fake faker
+ fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+ c = &Client{Text: textproto.NewConn(fake), localName: "localhost"}
+
+ return c, bcmdbuf, cmdbuf
+ }
+
+ t.Run("helo", func(t *testing.T) {
+ const (
+ basicServer = `250 mx.google.com at your service
+250 Sender OK
+221 Goodbye
+`
+
+ basicClient = `HELO localhost
+MAIL FROM:<user@gmail.com>
+QUIT
+`
+ )
+
+ c, bcmdbuf, cmdbuf := fake(basicServer)
+
+ if err := c.helo(); err != nil {
+ t.Fatalf("HELO failed: %s", err)
+ }
+ c.didHello = true
+ if err := c.Mail("user@gmail.com"); err != nil {
+ t.Fatalf("MAIL FROM failed: %s", err)
+ }
+ if err := c.Quit(); err != nil {
+ t.Fatalf("QUIT failed: %s", err)
+ }
+
+ bcmdbuf.Flush()
+ actualcmds := cmdbuf.String()
+ client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+ if client != actualcmds {
+ t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+ }
+ })
+
+ t.Run("ehlo", func(t *testing.T) {
+ const (
+ basicServer = `250-mx.google.com at your service
+250 SIZE 35651584
+250 Sender OK
+221 Goodbye
+`
+
+ basicClient = `EHLO localhost
+MAIL FROM:<user@gmail.com>
+QUIT
+`
+ )
+
+ c, bcmdbuf, cmdbuf := fake(basicServer)
+
+ if err := c.Hello("localhost"); err != nil {
+ t.Fatalf("EHLO failed: %s", err)
+ }
+ if ok, _ := c.Extension("8BITMIME"); ok {
+ t.Fatalf("Shouldn't support 8BITMIME")
+ }
+ if ok, _ := c.Extension("SMTPUTF8"); ok {
+ t.Fatalf("Shouldn't support SMTPUTF8")
+ }
+ if err := c.Mail("user@gmail.com"); err != nil {
+ t.Fatalf("MAIL FROM failed: %s", err)
+ }
+ if err := c.Quit(); err != nil {
+ t.Fatalf("QUIT failed: %s", err)
+ }
+
+ bcmdbuf.Flush()
+ actualcmds := cmdbuf.String()
+ client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+ if client != actualcmds {
+ t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+ }
+ })
+
+ t.Run("ehlo 8bitmime", func(t *testing.T) {
+ const (
+ basicServer = `250-mx.google.com at your service
+250-SIZE 35651584
+250 8BITMIME
+250 Sender OK
+221 Goodbye
+`
+
+ basicClient = `EHLO localhost
+MAIL FROM:<user@gmail.com> BODY=8BITMIME
+QUIT
+`
+ )
+
+ c, bcmdbuf, cmdbuf := fake(basicServer)
+
+ if err := c.Hello("localhost"); err != nil {
+ t.Fatalf("EHLO failed: %s", err)
+ }
+ if ok, _ := c.Extension("8BITMIME"); !ok {
+ t.Fatalf("Should support 8BITMIME")
+ }
+ if ok, _ := c.Extension("SMTPUTF8"); ok {
+ t.Fatalf("Shouldn't support SMTPUTF8")
+ }
+ if err := c.Mail("user@gmail.com"); err != nil {
+ t.Fatalf("MAIL FROM failed: %s", err)
+ }
+ if err := c.Quit(); err != nil {
+ t.Fatalf("QUIT failed: %s", err)
+ }
+
+ bcmdbuf.Flush()
+ actualcmds := cmdbuf.String()
+ client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+ if client != actualcmds {
+ t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+ }
+ })
+
+ t.Run("ehlo smtputf8", func(t *testing.T) {
+ const (
+ basicServer = `250-mx.google.com at your service
+250-SIZE 35651584
+250 SMTPUTF8
+250 Sender OK
+221 Goodbye
+`
+
+ basicClient = `EHLO localhost
+MAIL FROM:<user+📧@gmail.com> SMTPUTF8
+QUIT
+`
+ )
+
+ c, bcmdbuf, cmdbuf := fake(basicServer)
+
+ if err := c.Hello("localhost"); err != nil {
+ t.Fatalf("EHLO failed: %s", err)
+ }
+ if ok, _ := c.Extension("8BITMIME"); ok {
+ t.Fatalf("Shouldn't support 8BITMIME")
+ }
+ if ok, _ := c.Extension("SMTPUTF8"); !ok {
+ t.Fatalf("Should support SMTPUTF8")
+ }
+ if err := c.Mail("user+📧@gmail.com"); err != nil {
+ t.Fatalf("MAIL FROM failed: %s", err)
+ }
+ if err := c.Quit(); err != nil {
+ t.Fatalf("QUIT failed: %s", err)
+ }
+
+ bcmdbuf.Flush()
+ actualcmds := cmdbuf.String()
+ client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+ if client != actualcmds {
+ t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+ }
+ })
+
+ t.Run("ehlo 8bitmime smtputf8", func(t *testing.T) {
+ const (
+ basicServer = `250-mx.google.com at your service
+250-SIZE 35651584
+250-8BITMIME
+250 SMTPUTF8
+250 Sender OK
+221 Goodbye
+ `
+
+ basicClient = `EHLO localhost
+MAIL FROM:<user+📧@gmail.com> BODY=8BITMIME SMTPUTF8
+QUIT
+`
+ )
+
+ c, bcmdbuf, cmdbuf := fake(basicServer)
+
+ if err := c.Hello("localhost"); err != nil {
+ t.Fatalf("EHLO failed: %s", err)
+ }
+ c.didHello = true
+ if ok, _ := c.Extension("8BITMIME"); !ok {
+ t.Fatalf("Should support 8BITMIME")
+ }
+ if ok, _ := c.Extension("SMTPUTF8"); !ok {
+ t.Fatalf("Should support SMTPUTF8")
+ }
+ if err := c.Mail("user+📧@gmail.com"); err != nil {
+ t.Fatalf("MAIL FROM failed: %s", err)
+ }
+ if err := c.Quit(); err != nil {
+ t.Fatalf("QUIT failed: %s", err)
+ }
+
+ bcmdbuf.Flush()
+ actualcmds := cmdbuf.String()
+ client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+ if client != actualcmds {
+ t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+ }
+ })
+}
+
func TestNewClient(t *testing.T) {
server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n")
client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n")
diff --git a/src/os/dir_darwin.go b/src/os/dir_darwin.go
index 87797e2dda..476af6862e 100644
--- a/src/os/dir_darwin.go
+++ b/src/os/dir_darwin.go
@@ -28,7 +28,7 @@ func (f *File) readdirnames(n int) (names []string, err error) {
if f.dirinfo == nil {
dir, call, errno := f.pfd.OpenDir()
if errno != nil {
- return nil, wrapSyscallError(call, errno)
+ return nil, &PathError{call, f.name, errno}
}
f.dirinfo = &dirInfo{
dir: dir,
@@ -46,11 +46,11 @@ func (f *File) readdirnames(n int) (names []string, err error) {
var dirent syscall.Dirent
var entptr *syscall.Dirent
for len(names) < size || n == -1 {
- if res := readdir_r(d.dir, &dirent, &entptr); res != 0 {
- if syscall.Errno(res) == syscall.EINTR {
+ if errno := readdir_r(d.dir, &dirent, &entptr); errno != 0 {
+ if errno == syscall.EINTR {
continue
}
- return names, wrapSyscallError("readdir", syscall.Errno(res))
+ return names, &PathError{"readdir", f.name, errno}
}
if entptr == nil { // EOF
break
@@ -84,4 +84,4 @@ func (f *File) readdirnames(n int) (names []string, err error) {
func closedir(dir uintptr) (err error)
//go:linkname readdir_r syscall.readdir_r
-func readdir_r(dir uintptr, entry *syscall.Dirent, result **syscall.Dirent) (res int)
+func readdir_r(dir uintptr, entry *syscall.Dirent, result **syscall.Dirent) (res syscall.Errno)
diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go
index e0c4989756..58ec406ab8 100644
--- a/src/os/dir_unix.go
+++ b/src/os/dir_unix.go
@@ -50,7 +50,7 @@ func (f *File) readdirnames(n int) (names []string, err error) {
d.nbuf, errno = f.pfd.ReadDirent(d.buf)
runtime.KeepAlive(f)
if errno != nil {
- return names, wrapSyscallError("readdirent", errno)
+ return names, &PathError{"readdirent", f.name, errno}
}
if d.nbuf <= 0 {
break // EOF
diff --git a/src/os/os_test.go b/src/os/os_test.go
index e8c64510f5..520916d880 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -688,6 +688,10 @@ func TestReaddirOfFile(t *testing.T) {
if err == nil {
t.Error("Readdirnames succeeded; want non-nil error")
}
+ var pe *PathError
+ if !errors.As(err, &pe) || pe.Path != f.Name() {
+ t.Errorf("Readdirnames returned %q; want a PathError with path %q", err, f.Name())
+ }
if len(names) > 0 {
t.Errorf("unexpected dir names in regular file: %q", names)
}
diff --git a/src/os/proc.go b/src/os/proc.go
index 7364d631f2..cbd5a6aad9 100644
--- a/src/os/proc.go
+++ b/src/os/proc.go
@@ -7,6 +7,7 @@
package os
import (
+ "internal/testlog"
"runtime"
"syscall"
)
@@ -60,6 +61,13 @@ func Getgroups() ([]int, error) {
// For portability, the status code should be in the range [0, 125].
func Exit(code int) {
if code == 0 {
+ if testlog.PanicOnExit0() {
+ // We were told to panic on calls to os.Exit(0).
+ // This is used to fail tests that make an early
+ // unexpected call to os.Exit(0).
+ panic("unexpected call to os.Exit(0) during test")
+ }
+
// Give race detector a chance to fail the program.
// Racy programs do not have the right to finish successfully.
runtime_beforeExit()
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 099aa540e0..427ed0ffb9 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -286,13 +286,8 @@ func cgocallbackg1(ctxt uintptr) {
// Additional two words (16-byte alignment) are for saving FP.
cb = (*args)(unsafe.Pointer(sp + 7*sys.PtrSize))
case "amd64":
- // On amd64, stack frame is two words, plus caller PC.
- if framepointer_enabled {
- // In this case, there's also saved BP.
- cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
- break
- }
- cb = (*args)(unsafe.Pointer(sp + 3*sys.PtrSize))
+ // On amd64, stack frame is two words, plus caller PC and BP.
+ cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
case "386":
// On 386, stack frame is three words, plus caller PC.
cb = (*args)(unsafe.Pointer(sp + 4*sys.PtrSize))
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
index 76eeb2e41a..f411b22676 100644
--- a/src/runtime/debug.go
+++ b/src/runtime/debug.go
@@ -10,9 +10,8 @@ import (
)
// GOMAXPROCS sets the maximum number of CPUs that can be executing
-// simultaneously and returns the previous setting. If n < 1, it does not
-// change the current setting.
-// The number of logical CPUs on the local machine can be queried with NumCPU.
+// simultaneously and returns the previous setting. It defaults to
+// the value of runtime.NumCPU. If n < 1, it does not change the current setting.
// This call will go away when the scheduler improves.
func GOMAXPROCS(n int) int {
if GOARCH == "wasm" && n > 1 {
diff --git a/src/runtime/debugcall.go b/src/runtime/debugcall.go
index 6c285ec829..b5480c73ae 100644
--- a/src/runtime/debugcall.go
+++ b/src/runtime/debugcall.go
@@ -87,7 +87,7 @@ func debugCallCheck(pc uintptr) string {
pcdata = 0 // in prologue
}
stkmap := (*stackmap)(funcdata(f, _FUNCDATA_RegPointerMaps))
- if pcdata == -2 || stkmap == nil {
+ if pcdata == _PCDATA_RegMapUnsafe || stkmap == nil {
// Not at a safe point.
ret = debugCallUnsafePoint
return
diff --git a/src/runtime/defs_linux_arm.go b/src/runtime/defs_linux_arm.go
index ea29fd9d98..5bc0916f8b 100644
--- a/src/runtime/defs_linux_arm.go
+++ b/src/runtime/defs_linux_arm.go
@@ -1,3 +1,7 @@
+// 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.
+
package runtime
// Constants
diff --git a/src/runtime/defs_linux_mips64x.go b/src/runtime/defs_linux_mips64x.go
index 0fb53d5737..1fb423b198 100644
--- a/src/runtime/defs_linux_mips64x.go
+++ b/src/runtime/defs_linux_mips64x.go
@@ -1,3 +1,7 @@
+// 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 mips64 mips64le
// +build linux
diff --git a/src/runtime/defs_openbsd_arm64.go b/src/runtime/defs_openbsd_arm64.go
index 8b8d5cddf2..628f4bc5a5 100644
--- a/src/runtime/defs_openbsd_arm64.go
+++ b/src/runtime/defs_openbsd_arm64.go
@@ -1,3 +1,7 @@
+// 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 runtime
import "unsafe"
diff --git a/src/runtime/defs_plan9_386.go b/src/runtime/defs_plan9_386.go
index 220169d280..49129b3c3f 100644
--- a/src/runtime/defs_plan9_386.go
+++ b/src/runtime/defs_plan9_386.go
@@ -1,3 +1,7 @@
+// 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.
+
package runtime
const _PAGESIZE = 0x1000
diff --git a/src/runtime/defs_plan9_amd64.go b/src/runtime/defs_plan9_amd64.go
index 29a2643c3a..0099563034 100644
--- a/src/runtime/defs_plan9_amd64.go
+++ b/src/runtime/defs_plan9_amd64.go
@@ -1,3 +1,7 @@
+// 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.
+
package runtime
const _PAGESIZE = 0x1000
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index d591fdc4e9..929bb35db6 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -358,7 +358,11 @@ func ReadMemStatsSlow() (base, slow MemStats) {
}
for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
- pg := mheap_.pages.chunkOf(i).scavenged.popcntRange(0, pallocChunkPages)
+ chunk := mheap_.pages.tryChunkOf(i)
+ if chunk == nil {
+ continue
+ }
+ pg := chunk.scavenged.popcntRange(0, pallocChunkPages)
slow.HeapReleased += uint64(pg) * pageSize
}
for _, p := range allp {
@@ -756,11 +760,7 @@ func (p *PageAlloc) InUse() []AddrRange {
// Returns nil if the PallocData's L2 is missing.
func (p *PageAlloc) PallocData(i ChunkIdx) *PallocData {
ci := chunkIdx(i)
- l2 := (*pageAlloc)(p).chunks[ci.l1()]
- if l2 == nil {
- return nil
- }
- return (*PallocData)(&l2[ci.l2()])
+ return (*PallocData)((*pageAlloc)(p).tryChunkOf(ci))
}
// AddrRange represents a range over addresses.
@@ -900,7 +900,10 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
lock(&mheap_.lock)
chunkLoop:
for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
- chunk := mheap_.pages.chunkOf(i)
+ chunk := mheap_.pages.tryChunkOf(i)
+ if chunk == nil {
+ continue
+ }
for j := 0; j < pallocChunkPages/64; j++ {
// Run over each 64-bit bitmap section and ensure
// scavenged is being cleared properly on allocation.
@@ -981,9 +984,8 @@ func MapHashCheck(m interface{}, k interface{}) (uintptr, uintptr) {
}
func MSpanCountAlloc(bits []byte) int {
- s := mspan{
- nelems: uintptr(len(bits) * 8),
- gcmarkBits: (*gcBits)(unsafe.Pointer(&bits[0])),
- }
+ s := (*mspan)(mheap_.spanalloc.alloc())
+ s.nelems = uintptr(len(bits) * 8)
+ s.gcmarkBits = (*gcBits)(unsafe.Pointer(&bits[0]))
return s.countAlloc()
}
diff --git a/src/runtime/lockrank.go b/src/runtime/lockrank.go
index b23cf767be..042f10b1d3 100644
--- a/src/runtime/lockrank.go
+++ b/src/runtime/lockrank.go
@@ -230,7 +230,7 @@ var lockPartialOrder [][]lockRank = [][]lockRank{
lockRankStackLarge: {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan},
lockRankDefer: {},
lockRankSudog: {lockRankNotifyList, lockRankHchan},
- lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog},
+ lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog},
lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans, lockRankSpanSetSpine},
lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan},
lockRankGlobalAlloc: {lockRankProf, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial},
diff --git a/src/runtime/lockrank_off.go b/src/runtime/lockrank_off.go
index 425ca8dd93..32378a9627 100644
--- a/src/runtime/lockrank_off.go
+++ b/src/runtime/lockrank_off.go
@@ -18,19 +18,29 @@ func getLockRank(l *mutex) lockRank {
return 0
}
+// The following functions may be called in nosplit context.
+// Nosplit is not strictly required for lockWithRank, unlockWithRank
+// and lockWithRankMayAcquire, but these nosplit annotations must
+// be kept consistent with the equivalent functions in lockrank_on.go.
+
+//go:nosplit
func lockWithRank(l *mutex, rank lockRank) {
lock2(l)
}
+//go:nosplit
func acquireLockRank(rank lockRank) {
}
+//go:nosplit
func unlockWithRank(l *mutex) {
unlock2(l)
}
+//go:nosplit
func releaseLockRank(rank lockRank) {
}
+//go:nosplit
func lockWithRankMayAcquire(l *mutex, rank lockRank) {
}
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 399c1b071f..8be1d3991d 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -780,6 +780,11 @@ search:
}
notLast:
h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
break search
}
}
@@ -993,6 +998,10 @@ func mapclear(t *maptype, h *hmap) {
h.noverflow = 0
h.count = 0
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ h.hash0 = fastrand()
+
// Keep the mapextra allocation but clear any extra information.
if h.extra != nil {
*h.extra = mapextra{}
diff --git a/src/runtime/map_fast32.go b/src/runtime/map_fast32.go
index d035ed0386..d80f5eac78 100644
--- a/src/runtime/map_fast32.go
+++ b/src/runtime/map_fast32.go
@@ -344,6 +344,11 @@ search:
}
notLast:
h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
break search
}
}
diff --git a/src/runtime/map_fast64.go b/src/runtime/map_fast64.go
index f1f3927598..3bc84bbdd3 100644
--- a/src/runtime/map_fast64.go
+++ b/src/runtime/map_fast64.go
@@ -346,6 +346,11 @@ search:
}
notLast:
h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
break search
}
}
diff --git a/src/runtime/map_faststr.go b/src/runtime/map_faststr.go
index 069cda6554..108c502394 100644
--- a/src/runtime/map_faststr.go
+++ b/src/runtime/map_faststr.go
@@ -369,6 +369,11 @@ search:
}
notLast:
h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
break search
}
}
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 2b84945471..79df59d6d6 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -837,7 +837,8 @@ func scanstack(gp *g, gcw *gcWork) {
x := state.head
state.head = x.next
if stackTraceDebug {
- for _, obj := range x.obj[:x.nobj] {
+ for i := 0; i < x.nobj; i++ {
+ obj := &x.obj[i]
if obj.typ == nil { // reachable
continue
}
diff --git a/src/runtime/mgcstack.go b/src/runtime/mgcstack.go
index 211d882fa6..8eb941a328 100644
--- a/src/runtime/mgcstack.go
+++ b/src/runtime/mgcstack.go
@@ -167,8 +167,6 @@ func (obj *stackObject) setType(typ *_type) {
// A stackScanState keeps track of the state used during the GC walk
// of a goroutine.
-//
-//go:notinheap
type stackScanState struct {
cache pcvalueCache
diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go
index 6c7a4cf8dc..8859ed68cc 100644
--- a/src/runtime/mkduff.go
+++ b/src/runtime/mkduff.go
@@ -83,7 +83,6 @@ func copyAMD64(w io.Writer) {
//
// This is equivalent to a sequence of MOVSQ but
// for some reason that is 3.5x slower than this code.
- // The STOSQ in duffzero seem fine, though.
fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT, $0-0")
for i := 0; i < 64; i++ {
fmt.Fprintln(w, "\tMOVUPS\t(SI), X0")
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go
index 8b3c62c375..c90a6378bd 100644
--- a/src/runtime/mpagealloc.go
+++ b/src/runtime/mpagealloc.go
@@ -326,7 +326,20 @@ func (s *pageAlloc) init(mheapLock *mutex, sysStat *uint64) {
s.scav.scavLWM = maxSearchAddr
}
+// tryChunkOf returns the bitmap data for the given chunk.
+//
+// Returns nil if the chunk data has not been mapped.
+func (s *pageAlloc) tryChunkOf(ci chunkIdx) *pallocData {
+ l2 := s.chunks[ci.l1()]
+ if l2 == nil {
+ return nil
+ }
+ return &l2[ci.l2()]
+}
+
// chunkOf returns the chunk at the given chunk index.
+//
+// The chunk index must be valid or this method may throw.
func (s *pageAlloc) chunkOf(ci chunkIdx) *pallocData {
return &s.chunks[ci.l1()][ci.l2()]
}
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 9702920bcf..371db73502 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -5,7 +5,6 @@
package runtime
import (
- "runtime/internal/atomic"
"runtime/internal/sys"
"unsafe"
)
@@ -476,21 +475,7 @@ func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
func getpid() int
func tgkill(tgid, tid, sig int)
-// touchStackBeforeSignal stores an errno value. If non-zero, it means
-// that we should touch the signal stack before sending a signal.
-// This is used on systems that have a bug when the signal stack must
-// be faulted in. See #35777 and #37436.
-//
-// This is accessed atomically as it is set and read in different threads.
-//
-// TODO(austin): Remove this after Go 1.15 when we remove the
-// mlockGsignal workaround.
-var touchStackBeforeSignal uint32
-
// signalM sends a signal to mp.
func signalM(mp *m, sig int) {
- if atomic.Load(&touchStackBeforeSignal) != 0 {
- atomic.Cas((*uint32)(unsafe.Pointer(mp.gsignal.stack.hi-4)), 0, 0)
- }
tgkill(getpid(), int(mp.procid), sig)
}
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index 761856576a..17ef2c90d3 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -406,7 +406,7 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
var startpc uintptr
if !go115ReduceLiveness {
smi := pcdatavalue(f, _PCDATA_RegMapIndex, pc, nil)
- if smi == -2 {
+ if smi == _PCDATA_RegMapUnsafe {
// Unsafe-point marked by compiler. This includes
// atomic sequences (e.g., write barrier) and nosplit
// functions (except at calls).
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 5e38b3194c..739745aa26 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -3928,6 +3928,13 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
return
}
+ // If mp.profilehz is 0, then profiling is not enabled for this thread.
+ // We must check this to avoid a deadlock between setcpuprofilerate
+ // and the call to cpuprof.add, below.
+ if mp != nil && mp.profilehz == 0 {
+ return
+ }
+
// On mips{,le}, 64bit atomics are emulated with spinlocks, in
// runtime/internal/atomic. If SIGPROF arrives while the program is inside
// the critical section, it creates a deadlock (when writing the sample).
@@ -5459,9 +5466,6 @@ func setMaxThreads(in int) (out int) {
}
func haveexperiment(name string) bool {
- if name == "framepointer" {
- return framepointer_enabled // set by linker
- }
x := sys.Goexperiment
for x != "" {
xname := ""
diff --git a/src/runtime/rt0_linux_ppc64.s b/src/runtime/rt0_linux_ppc64.s
index 1265b15853..897d61052a 100644
--- a/src/runtime/rt0_linux_ppc64.s
+++ b/src/runtime/rt0_linux_ppc64.s
@@ -1,3 +1,7 @@
+// 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.
+
#include "textflag.h"
// actually a function descriptor for _main<>(SB)
diff --git a/src/runtime/rt0_linux_ppc64le.s b/src/runtime/rt0_linux_ppc64le.s
index 54ea9d58f7..4f7c6e6c99 100644
--- a/src/runtime/rt0_linux_ppc64le.s
+++ b/src/runtime/rt0_linux_ppc64le.s
@@ -1,3 +1,7 @@
+// 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.
+
#include "go_asm.h"
#include "textflag.h"
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index b7d0739e54..a3157037e7 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -329,7 +329,7 @@ type gobuf struct {
ctxt unsafe.Pointer
ret sys.Uintreg
lr uintptr
- bp uintptr // for GOEXPERIMENT=framepointer
+ bp uintptr // for framepointer-enabled architectures
}
// sudog represents a g in a wait list, such as for sending/receiving
@@ -909,15 +909,12 @@ type _defer struct {
// A _panic holds information about an active panic.
//
-// This is marked go:notinheap because _panic values must only ever
-// live on the stack.
+// A _panic value must only ever live on the stack.
//
// The argp and link fields are stack pointers, but don't need special
// handling during stack growth: because they are pointer-typed and
// _panic values only live on the stack, regular stack pointer
// adjustment takes care of them.
-//
-//go:notinheap
type _panic struct {
argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
arg interface{} // argument to panic
@@ -1049,8 +1046,7 @@ var (
isIntel bool
lfenceBeforeRdtsc bool
- goarm uint8 // set by cmd/link on arm systems
- framepointer_enabled bool // set by cmd/link
+ goarm uint8 // set by cmd/link on arm systems
)
// Set by the linker so the runtime can determine the buildmode.
@@ -1058,3 +1054,6 @@ var (
islibrary bool // -buildmode=c-shared
isarchive bool // -buildmode=c-archive
)
+
+// Must agree with cmd/internal/objabi.Framepointer_enabled.
+const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin")
diff --git a/src/runtime/select.go b/src/runtime/select.go
index 80768b285b..a506747910 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -118,6 +118,7 @@ func selectgo(cas0 *scase, order0 *uint16, pc0 *uintptr, nsends, nrecvs int, blo
scases := cas1[:ncases:ncases]
pollorder := order1[:ncases:ncases]
lockorder := order1[ncases:][:ncases:ncases]
+ // NOTE: pollorder/lockorder's underlying array was not zero-initialized by compiler.
// Even when raceenabled is true, there might be select
// statements in packages compiled without -race (e.g.,
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 0e930f60db..821c2e8436 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -66,7 +66,7 @@ const (
// to each stack below the usual guard area for OS-specific
// purposes like signal handling. Used on Windows, Plan 9,
// and iOS because they do not use a separate stack.
- _StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm*1024 + sys.GoosDarwin*sys.GoarchArm64*1024
+ _StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm64*1024
// The minimum size of stack used by Go code
_StackMin = 2048
@@ -648,12 +648,8 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
}
// Adjust saved base pointer if there is one.
+ // TODO what about arm64 frame pointer adjustment?
if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.RegSize {
- if !framepointer_enabled {
- print("runtime: found space for saved base pointer, but no framepointer experiment\n")
- print("argp=", hex(frame.argp), " varp=", hex(frame.varp), "\n")
- throw("bad frame layout")
- }
if stackDebug >= 3 {
print(" saved bp\n")
}
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index ddb5ea82b4..fa8d17035e 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -284,6 +284,9 @@ const (
)
const (
+ // 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/runtime/trace/annotation.go b/src/runtime/trace/annotation.go
index 82cb232dba..6e18bfb755 100644
--- a/src/runtime/trace/annotation.go
+++ b/src/runtime/trace/annotation.go
@@ -1,3 +1,7 @@
+// 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 trace
import (
diff --git a/src/runtime/trace/annotation_test.go b/src/runtime/trace/annotation_test.go
index 71abbfcfa6..31fccef206 100644
--- a/src/runtime/trace/annotation_test.go
+++ b/src/runtime/trace/annotation_test.go
@@ -1,3 +1,7 @@
+// 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 trace_test
import (
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 7850eceafa..94f4a44976 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -269,9 +269,9 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
frame.varp -= sys.RegSize
}
- // If framepointer_enabled and there's a frame, then
- // there's a saved bp here.
- if frame.varp > frame.sp && (framepointer_enabled && GOARCH == "amd64" || GOARCH == "arm64") {
+ // For architectures with frame pointers, if there's
+ // a frame, then there's a saved frame pointer here.
+ if frame.varp > frame.sp && (GOARCH == "amd64" || GOARCH == "arm64") {
frame.varp -= sys.RegSize
}
diff --git a/src/sync/map.go b/src/sync/map.go
index a61e2ebdd6..9ad25353ff 100644
--- a/src/sync/map.go
+++ b/src/sync/map.go
@@ -274,6 +274,7 @@ func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
e, ok = read.m[key]
if !ok && read.amended {
e, ok = m.dirty[key]
+ delete(m.dirty, key)
// Regardless of whether the entry was present, record a miss: this key
// will take the slow path until the dirty map is promoted to the read
// map.
diff --git a/src/sync/map_test.go b/src/sync/map_test.go
index 4ae989a6d5..7f163caa5c 100644
--- a/src/sync/map_test.go
+++ b/src/sync/map_test.go
@@ -9,6 +9,7 @@ import (
"reflect"
"runtime"
"sync"
+ "sync/atomic"
"testing"
"testing/quick"
)
@@ -171,3 +172,26 @@ func TestConcurrentRange(t *testing.T) {
}
}
}
+
+func TestIssue40999(t *testing.T) {
+ var m sync.Map
+
+ // Since the miss-counting in missLocked (via Delete)
+ // compares the miss count with len(m.dirty),
+ // add an initial entry to bias len(m.dirty) above the miss count.
+ m.Store(nil, struct{}{})
+
+ var finalized uint32
+
+ // Set finalizers that count for collected keys. A non-zero count
+ // indicates that keys have not been leaked.
+ for atomic.LoadUint32(&finalized) == 0 {
+ p := new(int)
+ runtime.SetFinalizer(p, func(*int) {
+ atomic.AddUint32(&finalized, 1)
+ })
+ m.Store(p, struct{}{})
+ m.Delete(p)
+ runtime.GC()
+ }
+}
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index 52766005bf..e9687bf26d 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -242,7 +242,7 @@ func (b *B) run1() bool {
if b.skipped {
tag = "SKIP"
}
- if b.chatty && (len(b.output) > 0 || b.finished) {
+ if b.chatty != nil && (len(b.output) > 0 || b.finished) {
b.trimOutput()
fmt.Fprintf(b.w, "--- %s: %s\n%s", tag, b.name, b.output)
}
@@ -523,10 +523,9 @@ func runBenchmarks(importPath string, matchString func(pat, str string) (bool, e
}
main := &B{
common: common{
- name: "Main",
- w: os.Stdout,
- chatty: *chatty,
- bench: true,
+ name: "Main",
+ w: os.Stdout,
+ bench: true,
},
importPath: importPath,
benchFunc: func(b *B) {
@@ -537,6 +536,9 @@ func runBenchmarks(importPath string, matchString func(pat, str string) (bool, e
benchTime: benchTime,
context: ctx,
}
+ if Verbose() {
+ main.chatty = newChattyPrinter(main.w)
+ }
main.runN(1)
return !main.failed
}
@@ -549,7 +551,7 @@ func (ctx *benchContext) processBench(b *B) {
benchName := benchmarkName(b.name, procs)
// If it's chatty, we've already printed this information.
- if !b.chatty {
+ if b.chatty == nil {
fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
}
// Recompute the running time for all but the first iteration.
@@ -576,7 +578,7 @@ func (ctx *benchContext) processBench(b *B) {
continue
}
results := r.String()
- if b.chatty {
+ if b.chatty != nil {
fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
}
if *benchmarkMemory || b.showAllocResult {
@@ -639,7 +641,7 @@ func (b *B) Run(name string, f func(b *B)) bool {
atomic.StoreInt32(&sub.hasSub, 1)
}
- if b.chatty {
+ if b.chatty != nil {
labelsOnce.Do(func() {
fmt.Printf("goos: %s\n", runtime.GOOS)
fmt.Printf("goarch: %s\n", runtime.GOARCH)
diff --git a/src/testing/example.go b/src/testing/example.go
index adc91d5faf..0217c5d242 100644
--- a/src/testing/example.go
+++ b/src/testing/example.go
@@ -62,9 +62,10 @@ func sortLines(output string) string {
// If stdout doesn't match the expected output or if recovered is non-nil, it'll print the cause of failure to stdout.
// If the test is chatty/verbose, it'll print a success message to stdout.
// If recovered is non-nil, it'll panic with that value.
-func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, recovered interface{}) (passed bool) {
+// If the test panicked with nil, or invoked runtime.Goexit, it'll be
+// made to fail and panic with errNilPanicOrGoexit
+func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, finished bool, recovered interface{}) (passed bool) {
passed = true
-
dstr := fmtDuration(timeSpent)
var fail string
got := strings.TrimSpace(stdout)
@@ -78,16 +79,20 @@ func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Durati
fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
}
}
- if fail != "" || recovered != nil {
+ if fail != "" || !finished || recovered != nil {
fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
passed = false
} else if *chatty {
fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
}
+
if recovered != nil {
// Propagate the previously recovered result, by panicking.
panic(recovered)
}
+ if !finished && recovered == nil {
+ panic(errNilPanicOrGoexit)
+ }
return
}
diff --git a/src/testing/internal/testdeps/deps.go b/src/testing/internal/testdeps/deps.go
index af08dd768a..3608d33294 100644
--- a/src/testing/internal/testdeps/deps.go
+++ b/src/testing/internal/testdeps/deps.go
@@ -121,3 +121,8 @@ func (TestDeps) StopTestLog() error {
log.w = nil
return err
}
+
+// SetPanicOnExit0 tells the os package whether to panic on os.Exit(0).
+func (TestDeps) SetPanicOnExit0(v bool) {
+ testlog.SetPanicOnExit0(v)
+}
diff --git a/src/testing/run_example.go b/src/testing/run_example.go
index 10bde49e5b..4dc83f7d32 100644
--- a/src/testing/run_example.go
+++ b/src/testing/run_example.go
@@ -43,6 +43,7 @@ func runExample(eg InternalExample) (ok bool) {
outC <- buf.String()
}()
+ finished := false
start := time.Now()
// Clean up in a deferred call so we can recover if the example panics.
@@ -55,10 +56,11 @@ func runExample(eg InternalExample) (ok bool) {
out := <-outC
err := recover()
- ok = eg.processRunResult(out, timeSpent, err)
+ ok = eg.processRunResult(out, timeSpent, finished, err)
}()
// Run example.
eg.F()
+ finished = true
return
}
diff --git a/src/testing/run_example_js.go b/src/testing/run_example_js.go
index 472e0c57fa..1d4164b61f 100644
--- a/src/testing/run_example_js.go
+++ b/src/testing/run_example_js.go
@@ -26,6 +26,7 @@ func runExample(eg InternalExample) (ok bool) {
stdout := os.Stdout
f := createTempFile(eg.Name)
os.Stdout = f
+ finished := false
start := time.Now()
// Clean up in a deferred call so we can recover if the example panics.
@@ -50,11 +51,12 @@ func runExample(eg InternalExample) (ok bool) {
}
err := recover()
- ok = eg.processRunResult(out, timeSpent, err)
+ ok = eg.processRunResult(out, timeSpent, finished, err)
}()
// Run example.
eg.F()
+ finished = true
return
}
diff --git a/src/testing/sub_test.go b/src/testing/sub_test.go
index 8eb0084b1c..5b226f85ad 100644
--- a/src/testing/sub_test.go
+++ b/src/testing/sub_test.go
@@ -483,10 +483,12 @@ func TestTRun(t *T) {
signal: make(chan bool),
name: "Test",
w: buf,
- chatty: tc.chatty,
},
context: ctx,
}
+ if tc.chatty {
+ root.chatty = newChattyPrinter(root.w)
+ }
ok := root.Run(tc.desc, tc.f)
ctx.release()
@@ -665,11 +667,13 @@ func TestBRun(t *T) {
signal: make(chan bool),
name: "root",
w: buf,
- chatty: tc.chatty,
},
benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
benchTime: benchTimeFlag{d: 1 * time.Microsecond},
}
+ if tc.chatty {
+ root.chatty = newChattyPrinter(root.w)
+ }
root.runN(1)
if ok != !tc.failed {
t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, !tc.failed)
@@ -741,9 +745,13 @@ func TestParallelSub(t *T) {
}
}
-type funcWriter func([]byte) (int, error)
+type funcWriter struct {
+ write func([]byte) (int, error)
+}
-func (fw funcWriter) Write(b []byte) (int, error) { return fw(b) }
+func (fw *funcWriter) Write(b []byte) (int, error) {
+ return fw.write(b)
+}
func TestRacyOutput(t *T) {
var runs int32 // The number of running Writes
@@ -761,9 +769,10 @@ func TestRacyOutput(t *T) {
var wg sync.WaitGroup
root := &T{
- common: common{w: funcWriter(raceDetector), chatty: true},
+ common: common{w: &funcWriter{raceDetector}},
context: newTestContext(1, newMatcher(regexp.MatchString, "", "")),
}
+ root.chatty = newChattyPrinter(root.w)
root.Run("", func(t *T) {
for i := 0; i < 100; i++ {
wg.Add(1)
@@ -928,3 +937,30 @@ func TestCleanupParallelSubtests(t *T) {
t.Errorf("unexpected cleanup count; got %d want 1", ranCleanup)
}
}
+
+func TestNestedCleanup(t *T) {
+ ranCleanup := 0
+ t.Run("test", func(t *T) {
+ t.Cleanup(func() {
+ if ranCleanup != 2 {
+ t.Errorf("unexpected cleanup count in first cleanup: got %d want 2", ranCleanup)
+ }
+ ranCleanup++
+ })
+ t.Cleanup(func() {
+ if ranCleanup != 0 {
+ t.Errorf("unexpected cleanup count in second cleanup: got %d want 0", ranCleanup)
+ }
+ ranCleanup++
+ t.Cleanup(func() {
+ if ranCleanup != 1 {
+ t.Errorf("unexpected cleanup count in nested cleanup: got %d want 1", ranCleanup)
+ }
+ ranCleanup++
+ })
+ })
+ })
+ if ranCleanup != 3 {
+ t.Errorf("unexpected cleanup count: got %d want 3", ranCleanup)
+ }
+}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 6fc8c4fa9f..66f296234a 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -294,6 +294,7 @@ func Init() {
blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
+ panicOnExit0 = flag.Bool("test.paniconexit0", false, "panic on call to os.Exit(0)")
traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
@@ -320,12 +321,12 @@ var (
blockProfileRate *int
mutexProfile *string
mutexProfileFraction *int
+ panicOnExit0 *bool
traceFile *string
timeout *time.Duration
cpuListStr *string
parallel *int
testlog *string
- printer *testPrinter
haveExamples bool // are there examples?
@@ -335,55 +336,45 @@ var (
numFailed uint32 // number of test failures
)
-type testPrinter struct {
- chatty bool
-
+type chattyPrinter struct {
+ w io.Writer
lastNameMu sync.Mutex // guards lastName
lastName string // last printed test name in chatty mode
}
-func newTestPrinter(chatty bool) *testPrinter {
- return &testPrinter{
- chatty: chatty,
- }
+func newChattyPrinter(w io.Writer) *chattyPrinter {
+ return &chattyPrinter{w: w}
}
-func (p *testPrinter) Print(testName, out string) {
- p.Fprint(os.Stdout, testName, out)
+// Updatef prints a message about the status of the named test to w.
+//
+// The formatted message must include the test name itself.
+func (p *chattyPrinter) Updatef(testName, format string, args ...interface{}) {
+ p.lastNameMu.Lock()
+ defer p.lastNameMu.Unlock()
+
+ // Since the message already implies an association with a specific new test,
+ // we don't need to check what the old test name was or log an extra CONT line
+ // for it. (We're updating it anyway, and the current message already includes
+ // the test name.)
+ p.lastName = testName
+ fmt.Fprintf(p.w, format, args...)
}
-func (p *testPrinter) Fprint(w io.Writer, testName, out string) {
+// Printf prints a message, generated by the named test, that does not
+// necessarily mention that tests's name itself.
+func (p *chattyPrinter) Printf(testName, format string, args ...interface{}) {
p.lastNameMu.Lock()
defer p.lastNameMu.Unlock()
- if !p.chatty ||
- strings.HasPrefix(out, "--- PASS: ") ||
- strings.HasPrefix(out, "--- FAIL: ") ||
- strings.HasPrefix(out, "--- SKIP: ") ||
- strings.HasPrefix(out, "=== RUN ") ||
- strings.HasPrefix(out, "=== CONT ") ||
- strings.HasPrefix(out, "=== PAUSE ") {
- // If we're buffering test output (!p.chatty), we don't really care which
- // test is emitting which line so long as they are serialized.
- //
- // If the message already implies an association with a specific new test,
- // we don't need to check what the old test name was or log an extra CONT
- // line for it. (We're updating it anyway, and the current message already
- // includes the test name.)
- p.lastName = testName
- fmt.Fprint(w, out)
- return
- }
-
if p.lastName == "" {
p.lastName = testName
} else if p.lastName != testName {
- // Always printed as-is, with 0 decoration or indentation. So, we skip
- // printing to w.
- fmt.Printf("=== CONT %s\n", testName)
+ fmt.Fprintf(p.w, "=== CONT %s\n", testName)
p.lastName = testName
}
- fmt.Fprint(w, out)
+
+ fmt.Fprintf(p.w, format, args...)
}
// The maximum number of stack frames to go through when skipping helper functions for
@@ -401,16 +392,16 @@ type common struct {
skipped bool // Test of benchmark has been skipped.
done bool // Test is finished and all subtests have completed.
helpers map[string]struct{} // functions to be skipped when writing file/line info
- cleanup func() // optional function to be called at the end of the test
+ cleanups []func() // optional functions to be called at the end of the test
cleanupName string // Name of the cleanup function.
cleanupPc []uintptr // The stack trace at the point where Cleanup was called.
- chatty bool // A copy of the chatty flag.
- bench bool // Whether the current test is a benchmark.
- finished bool // Test function has completed.
- hasSub int32 // Written atomically.
- raceErrors int // Number of races detected during test.
- runner string // Function name of tRunner running the test.
+ chatty *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
+ bench bool // Whether the current test is a benchmark.
+ finished bool // Test function has completed.
+ hasSub int32 // Written atomically.
+ raceErrors int // Number of races detected during test.
+ runner string // Function name of tRunner running the test.
parent *common
level int // Nesting depth of test or benchmark.
@@ -422,10 +413,10 @@ type common struct {
signal chan bool // To signal a test is done.
sub []*T // Queue of subtests to be run in parallel.
- tempDirOnce sync.Once
- tempDir string
- tempDirErr error
- tempDirSeq int32
+ tempDirMu sync.Mutex
+ tempDir string
+ tempDirErr error
+ tempDirSeq int32
}
// Short reports whether the -test.short flag is set.
@@ -572,12 +563,31 @@ func (c *common) flushToParent(testName, format string, args ...interface{}) {
p.mu.Lock()
defer p.mu.Unlock()
- printer.Fprint(p.w, testName, fmt.Sprintf(format, args...))
-
c.mu.Lock()
defer c.mu.Unlock()
- io.Copy(p.w, bytes.NewReader(c.output))
- c.output = c.output[:0]
+
+ if len(c.output) > 0 {
+ format += "%s"
+ args = append(args[:len(args):len(args)], c.output)
+ c.output = c.output[:0] // but why?
+ }
+
+ if c.chatty != nil && p.w == c.chatty.w {
+ // We're flushing to the actual output, so track that this output is
+ // associated with a specific test (and, specifically, that the next output
+ // is *not* associated with that test).
+ //
+ // Moreover, if c.output is non-empty it is important that this write be
+ // atomic with respect to the output of other tests, so that we don't end up
+ // with confusing '=== CONT' lines in the middle of our '--- PASS' block.
+ // Neither humans nor cmd/test2json can parse those easily.
+ // (See https://golang.org/issue/40771.)
+ c.chatty.Updatef(testName, format, args...)
+ } else {
+ // We're flushing to the output buffer of the parent test, which will
+ // itself follow a test-name header when it is finally flushed to stdout.
+ fmt.Fprintf(p.w, format, args...)
+ }
}
type indenter struct {
@@ -746,13 +756,13 @@ func (c *common) logDepth(s string, depth int) {
}
panic("Log in goroutine after " + c.name + " has completed")
} else {
- if c.chatty {
+ if c.chatty != nil {
if c.bench {
// Benchmarks don't print === CONT, so we should skip the test
// printer and just print straight to stdout.
fmt.Print(c.decorate(s, depth+1))
} else {
- printer.Print(c.name, c.decorate(s, depth+1))
+ c.chatty.Printf(c.name, "%s", c.decorate(s, depth+1))
}
return
@@ -853,24 +863,31 @@ func (c *common) Helper() {
// subtests complete. Cleanup functions will be called in last added,
// first called order.
func (c *common) Cleanup(f func()) {
- c.mu.Lock()
- defer c.mu.Unlock()
- oldCleanup := c.cleanup
- oldCleanupPc := c.cleanupPc
- c.cleanup = func() {
- if oldCleanup != nil {
- defer func() {
- c.cleanupPc = oldCleanupPc
- oldCleanup()
- }()
- }
- c.cleanupName = callerName(0)
- f()
- }
var pc [maxStackLen]uintptr
// Skip two extra frames to account for this function and runtime.Callers itself.
n := runtime.Callers(2, pc[:])
- c.cleanupPc = pc[:n]
+ cleanupPc := pc[:n]
+
+ fn := func() {
+ defer func() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.cleanupName = ""
+ c.cleanupPc = nil
+ }()
+
+ name := callerName(0)
+ c.mu.Lock()
+ c.cleanupName = name
+ c.cleanupPc = cleanupPc
+ c.mu.Unlock()
+
+ f()
+ }
+
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.cleanups = append(c.cleanups, fn)
}
var tempDirReplacer struct {
@@ -886,7 +903,19 @@ var tempDirReplacer struct {
func (c *common) TempDir() string {
// Use a single parent directory for all the temporary directories
// created by a test, each numbered sequentially.
- c.tempDirOnce.Do(func() {
+ c.tempDirMu.Lock()
+ var nonExistent bool
+ if c.tempDir == "" { // Usually the case with js/wasm
+ nonExistent = true
+ } else {
+ _, err := os.Stat(c.tempDir)
+ nonExistent = os.IsNotExist(err)
+ if err != nil && !nonExistent {
+ c.Fatalf("TempDir: %v", err)
+ }
+ }
+
+ if nonExistent {
c.Helper()
// ioutil.TempDir doesn't like path separators in its pattern,
@@ -904,7 +933,9 @@ func (c *common) TempDir() string {
}
})
}
- })
+ }
+ c.tempDirMu.Unlock()
+
if c.tempDirErr != nil {
c.Fatalf("TempDir: %v", c.tempDirErr)
}
@@ -928,22 +959,37 @@ const (
// If catchPanic is true, this will catch panics, and return the recovered
// value if any.
func (c *common) runCleanup(ph panicHandling) (panicVal interface{}) {
- c.mu.Lock()
- cleanup := c.cleanup
- c.cleanup = nil
- c.mu.Unlock()
- if cleanup == nil {
- return nil
- }
-
if ph == recoverAndReturnPanic {
defer func() {
panicVal = recover()
}()
}
- cleanup()
- return nil
+ // Make sure that if a cleanup function panics,
+ // we still run the remaining cleanup functions.
+ defer func() {
+ c.mu.Lock()
+ recur := len(c.cleanups) > 0
+ c.mu.Unlock()
+ if recur {
+ c.runCleanup(normalPanic)
+ }
+ }()
+
+ for {
+ var cleanup func()
+ c.mu.Lock()
+ if len(c.cleanups) > 0 {
+ last := len(c.cleanups) - 1
+ cleanup = c.cleanups[last]
+ c.cleanups = c.cleanups[:last]
+ }
+ c.mu.Unlock()
+ if cleanup == nil {
+ return nil
+ }
+ cleanup()
+ }
}
// callerName gives the function name (qualified with a package path)
@@ -979,34 +1025,22 @@ func (t *T) Parallel() {
t.parent.sub = append(t.parent.sub, t)
t.raceErrors += race.Errors()
- if t.chatty {
- // Print directly to root's io.Writer so there is no delay.
- root := t.parent
- for ; root.parent != nil; root = root.parent {
- }
- root.mu.Lock()
+ if t.chatty != nil {
// Unfortunately, even though PAUSE indicates that the named test is *no
// longer* running, cmd/test2json interprets it as changing the active test
// for the purpose of log parsing. We could fix cmd/test2json, but that
// won't fix existing deployments of third-party tools that already shell
// out to older builds of cmd/test2json — so merely fixing cmd/test2json
// isn't enough for now.
- printer.Fprint(root.w, t.name, fmt.Sprintf("=== PAUSE %s\n", t.name))
- root.mu.Unlock()
+ t.chatty.Updatef(t.name, "=== PAUSE %s\n", t.name)
}
t.signal <- true // Release calling test.
<-t.parent.barrier // Wait for the parent test to complete.
t.context.waitParallel()
- if t.chatty {
- // Print directly to root's io.Writer so there is no delay.
- root := t.parent
- for ; root.parent != nil; root = root.parent {
- }
- root.mu.Lock()
- printer.Fprint(root.w, t.name, fmt.Sprintf("=== CONT %s\n", t.name))
- root.mu.Unlock()
+ if t.chatty != nil {
+ t.chatty.Updatef(t.name, "=== CONT %s\n", t.name)
}
t.start = time.Now()
@@ -1157,14 +1191,8 @@ func (t *T) Run(name string, f func(t *T)) bool {
}
t.w = indenter{&t.common}
- if t.chatty {
- // Print directly to root's io.Writer so there is no delay.
- root := t.parent
- for ; root.parent != nil; root = root.parent {
- }
- root.mu.Lock()
- printer.Fprint(root.w, t.name, fmt.Sprintf("=== RUN %s\n", t.name))
- root.mu.Unlock()
+ if t.chatty != nil {
+ t.chatty.Updatef(t.name, "=== RUN %s\n", t.name)
}
// Instead of reducing the running count of this test before calling the
// tRunner and increasing it afterwards, we rely on tRunner keeping the
@@ -1257,6 +1285,7 @@ func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return e
func (f matchStringOnly) ImportPath() string { return "" }
func (f matchStringOnly) StartTestLog(io.Writer) {}
func (f matchStringOnly) StopTestLog() error { return errMain }
+func (f matchStringOnly) SetPanicOnExit0(bool) {}
// Main is an internal function, part of the implementation of the "go test" command.
// It was exported because it is cross-package and predates "internal" packages.
@@ -1292,6 +1321,7 @@ type M struct {
type testDeps interface {
ImportPath() string
MatchString(pat, str string) (bool, error)
+ SetPanicOnExit0(bool)
StartCPUProfile(io.Writer) error
StopCPUProfile()
StartTestLog(io.Writer)
@@ -1329,8 +1359,6 @@ func (m *M) Run() (code int) {
flag.Parse()
}
- printer = newTestPrinter(Verbose())
-
if *parallel < 1 {
fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
flag.Usage()
@@ -1375,7 +1403,7 @@ func (t *T) report() {
format := "--- %s: %s (%s)\n"
if t.Failed() {
t.flushToParent(t.name, format, "FAIL", t.name, dstr)
- } else if t.chatty {
+ } else if t.chatty != nil {
if t.Skipped() {
t.flushToParent(t.name, format, "SKIP", t.name, dstr)
} else {
@@ -1436,10 +1464,12 @@ func runTests(matchString func(pat, str string) (bool, error), tests []InternalT
signal: make(chan bool),
barrier: make(chan bool),
w: os.Stdout,
- chatty: *chatty,
},
context: ctx,
}
+ if Verbose() {
+ t.chatty = newChattyPrinter(t.w)
+ }
tRunner(t, func(t *T) {
for _, test := range tests {
t.Run(test.Name, test.F)
@@ -1517,6 +1547,9 @@ func (m *M) before() {
m.deps.StartTestLog(f)
testlogFile = f
}
+ if *panicOnExit0 {
+ m.deps.SetPanicOnExit0(true)
+ }
}
// after runs after all testing.
@@ -1524,6 +1557,13 @@ func (m *M) after() {
m.afterOnce.Do(func() {
m.writeProfiles()
})
+
+ // Restore PanicOnExit0 after every run, because we set it to true before
+ // every run. Otherwise, if m.Run is called multiple times the behavior of
+ // os.Exit(0) will not be restored after the second run.
+ if *panicOnExit0 {
+ m.deps.SetPanicOnExit0(false)
+ }
}
func (m *M) writeProfiles() {
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
index dbef7066e0..d665a334e4 100644
--- a/src/testing/testing_test.go
+++ b/src/testing/testing_test.go
@@ -19,6 +19,38 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
+func TestTempDirInCleanup(t *testing.T) {
+ var dir string
+
+ t.Run("test", func(t *testing.T) {
+ t.Cleanup(func() {
+ dir = t.TempDir()
+ })
+ _ = t.TempDir()
+ })
+
+ fi, err := os.Stat(dir)
+ if fi != nil {
+ t.Fatalf("Directory %q from user Cleanup still exists", dir)
+ }
+ if !os.IsNotExist(err) {
+ t.Fatalf("Unexpected error: %v", err)
+ }
+}
+
+func TestTempDirInBenchmark(t *testing.T) {
+ testing.Benchmark(func(b *testing.B) {
+ if !b.Run("test", func(b *testing.B) {
+ // Add a loop so that the test won't fail. See issue 38677.
+ for i := 0; i < b.N; i++ {
+ _ = b.TempDir()
+ }
+ }) {
+ t.Fatal("Sub test failure in a benchmark")
+ }
+ })
+}
+
func TestTempDir(t *testing.T) {
testTempDir(t)
t.Run("InSubtest", testTempDir)
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index ac3e741390..7ac5175006 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -256,6 +256,7 @@ func (s *state) walk(dot reflect.Value, node parse.Node) {
if len(node.Pipe.Decl) == 0 {
s.printValue(node, val)
}
+ case *parse.CommentNode:
case *parse.IfNode:
s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
case *parse.ListNode:
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
index 30371f2862..e41373a002 100644
--- a/src/text/template/parse/lex.go
+++ b/src/text/template/parse/lex.go
@@ -41,6 +41,7 @@ const (
itemBool // boolean constant
itemChar // printable ASCII character; grab bag for comma etc.
itemCharConstant // character constant
+ itemComment // comment text
itemComplex // complex constant (1+2i); imaginary is just a number
itemAssign // equals ('=') introducing an assignment
itemDeclare // colon-equals (':=') introducing a declaration
@@ -112,6 +113,7 @@ type lexer struct {
leftDelim string // start of action
rightDelim string // end of action
trimRightDelim string // end of action with trim marker
+ emitComment bool // emit itemComment tokens.
pos Pos // current position in the input
start Pos // start position of this item
width Pos // width of last rune read from input
@@ -203,7 +205,7 @@ func (l *lexer) drain() {
}
// lex creates a new scanner for the input string.
-func lex(name, input, left, right string) *lexer {
+func lex(name, input, left, right string, emitComment bool) *lexer {
if left == "" {
left = leftDelim
}
@@ -216,6 +218,7 @@ func lex(name, input, left, right string) *lexer {
leftDelim: left,
rightDelim: right,
trimRightDelim: rightTrimMarker + right,
+ emitComment: emitComment,
items: make(chan item),
line: 1,
startLine: 1,
@@ -323,6 +326,9 @@ func lexComment(l *lexer) stateFn {
if !delim {
return l.errorf("comment ends before closing delimiter")
}
+ if l.emitComment {
+ l.emit(itemComment)
+ }
if trimSpace {
l.pos += trimMarkerLen
}
diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
index 563c4fc1cb..f6d5f285ed 100644
--- a/src/text/template/parse/lex_test.go
+++ b/src/text/template/parse/lex_test.go
@@ -15,6 +15,7 @@ var itemName = map[itemType]string{
itemBool: "bool",
itemChar: "char",
itemCharConstant: "charconst",
+ itemComment: "comment",
itemComplex: "complex",
itemDeclare: ":=",
itemEOF: "EOF",
@@ -90,6 +91,7 @@ var lexTests = []lexTest{
{"text", `now is the time`, []item{mkItem(itemText, "now is the time"), tEOF}},
{"text with comment", "hello-{{/* this is a comment */}}-world", []item{
mkItem(itemText, "hello-"),
+ mkItem(itemComment, "/* this is a comment */"),
mkItem(itemText, "-world"),
tEOF,
}},
@@ -311,6 +313,7 @@ var lexTests = []lexTest{
}},
{"trimming spaces before and after comment", "hello- {{- /* hello */ -}} -world", []item{
mkItem(itemText, "hello-"),
+ mkItem(itemComment, "/* hello */"),
mkItem(itemText, "-world"),
tEOF,
}},
@@ -389,7 +392,7 @@ var lexTests = []lexTest{
// collect gathers the emitted items into a slice.
func collect(t *lexTest, left, right string) (items []item) {
- l := lex(t.name, t.input, left, right)
+ l := lex(t.name, t.input, left, right, true)
for {
item := l.nextItem()
items = append(items, item)
@@ -529,7 +532,7 @@ func TestPos(t *testing.T) {
func TestShutdown(t *testing.T) {
// We need to duplicate template.Parse here to hold on to the lexer.
const text = "erroneous{{define}}{{else}}1234"
- lexer := lex("foo", text, "{{", "}}")
+ lexer := lex("foo", text, "{{", "}}", false)
_, err := New("root").parseLexer(lexer)
if err == nil {
t.Fatalf("expected error")
diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go
index dddc7752a2..177482f9b2 100644
--- a/src/text/template/parse/node.go
+++ b/src/text/template/parse/node.go
@@ -70,6 +70,7 @@ const (
NodeTemplate // A template invocation action.
NodeVariable // A $ variable.
NodeWith // A with action.
+ NodeComment // A comment.
)
// Nodes.
@@ -149,6 +150,38 @@ func (t *TextNode) Copy() Node {
return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)}
}
+// CommentNode holds a comment.
+type CommentNode struct {
+ NodeType
+ Pos
+ tr *Tree
+ Text string // Comment text.
+}
+
+func (t *Tree) newComment(pos Pos, text string) *CommentNode {
+ return &CommentNode{tr: t, NodeType: NodeComment, Pos: pos, Text: text}
+}
+
+func (c *CommentNode) String() string {
+ var sb strings.Builder
+ c.writeTo(&sb)
+ return sb.String()
+}
+
+func (c *CommentNode) writeTo(sb *strings.Builder) {
+ sb.WriteString("{{")
+ sb.WriteString(c.Text)
+ sb.WriteString("}}")
+}
+
+func (c *CommentNode) tree() *Tree {
+ return c.tr
+}
+
+func (c *CommentNode) Copy() Node {
+ return &CommentNode{tr: c.tr, NodeType: NodeComment, Pos: c.Pos, Text: c.Text}
+}
+
// PipeNode holds a pipeline with optional declaration
type PipeNode struct {
NodeType
diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
index c9b80f4a24..496d8bfa1d 100644
--- a/src/text/template/parse/parse.go
+++ b/src/text/template/parse/parse.go
@@ -21,6 +21,7 @@ type Tree struct {
Name string // name of the template represented by the tree.
ParseName string // name of the top-level template during parsing, for error messages.
Root *ListNode // top-level root of the tree.
+ Mode Mode // parsing mode.
text string // text parsed to create the template (or its parent)
// Parsing only; cleared after parse.
funcs []map[string]interface{}
@@ -29,8 +30,16 @@ type Tree struct {
peekCount int
vars []string // variables defined at the moment.
treeSet map[string]*Tree
+ mode Mode
}
+// A mode value is a set of flags (or 0). Modes control parser behavior.
+type Mode uint
+
+const (
+ ParseComments Mode = 1 << iota // parse comments and add them to AST
+)
+
// Copy returns a copy of the Tree. Any parsing state is discarded.
func (t *Tree) Copy() *Tree {
if t == nil {
@@ -220,7 +229,8 @@ func (t *Tree) stopParse() {
func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) {
defer t.recover(&err)
t.ParseName = t.Name
- t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim), treeSet)
+ emitComment := t.Mode&ParseComments != 0
+ t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, emitComment), treeSet)
t.text = text
t.parse()
t.add()
@@ -240,12 +250,14 @@ func (t *Tree) add() {
}
}
-// IsEmptyTree reports whether this tree (node) is empty of everything but space.
+// IsEmptyTree reports whether this tree (node) is empty of everything but space or comments.
func IsEmptyTree(n Node) bool {
switch n := n.(type) {
case nil:
return true
case *ActionNode:
+ case *CommentNode:
+ return true
case *IfNode:
case *ListNode:
for _, node := range n.Nodes {
@@ -276,6 +288,7 @@ func (t *Tree) parse() {
if t.nextNonSpace().typ == itemDefine {
newT := New("definition") // name will be updated once we know it.
newT.text = t.text
+ newT.Mode = t.Mode
newT.ParseName = t.ParseName
newT.startParse(t.funcs, t.lex, t.treeSet)
newT.parseDefinition()
@@ -331,13 +344,15 @@ func (t *Tree) itemList() (list *ListNode, next Node) {
}
// textOrAction:
-// text | action
+// text | comment | action
func (t *Tree) textOrAction() Node {
switch token := t.nextNonSpace(); token.typ {
case itemText:
return t.newText(token.pos, token.val)
case itemLeftDelim:
return t.action()
+ case itemComment:
+ return t.newComment(token.pos, token.val)
default:
t.unexpected(token, "input")
}
@@ -539,6 +554,7 @@ func (t *Tree) blockControl() Node {
block := New(name) // name will be updated once we know it.
block.text = t.text
+ block.Mode = t.Mode
block.ParseName = t.ParseName
block.startParse(t.funcs, t.lex, t.treeSet)
var end Node
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
index 4e09a7852c..d9c13c5d95 100644
--- a/src/text/template/parse/parse_test.go
+++ b/src/text/template/parse/parse_test.go
@@ -348,6 +348,30 @@ func TestParseCopy(t *testing.T) {
testParse(true, t)
}
+func TestParseWithComments(t *testing.T) {
+ textFormat = "%q"
+ defer func() { textFormat = "%s" }()
+ tests := [...]parseTest{
+ {"comment", "{{/*\n\n\n*/}}", noError, "{{/*\n\n\n*/}}"},
+ {"comment trim left", "x \r\n\t{{- /* hi */}}", noError, `"x"{{/* hi */}}`},
+ {"comment trim right", "{{/* hi */ -}}\n\n\ty", noError, `{{/* hi */}}"y"`},
+ {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x"{{/* */}}"y"`},
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ tr := New(test.name)
+ tr.Mode = ParseComments
+ tmpl, err := tr.Parse(test.input, "", "", make(map[string]*Tree))
+ if err != nil {
+ t.Errorf("%q: expected error; got none", test.name)
+ }
+ if result := tmpl.Root.String(); result != test.result {
+ t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result)
+ }
+ })
+ }
+}
+
type isEmptyTest struct {
name string
input string
@@ -358,6 +382,7 @@ var isEmptyTests = []isEmptyTest{
{"empty", ``, true},
{"nonempty", `hello`, false},
{"spaces only", " \t\n \t\n", true},
+ {"comment only", "{{/* comment */}}", true},
{"definition", `{{define "x"}}something{{end}}`, true},
{"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
{"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false},
diff --git a/src/unicode/utf8/utf8_test.go b/src/unicode/utf8/utf8_test.go
index 359461bd05..eaf1b5ffee 100644
--- a/src/unicode/utf8/utf8_test.go
+++ b/src/unicode/utf8/utf8_test.go
@@ -597,16 +597,24 @@ func BenchmarkDecodeJapaneseRune(b *testing.B) {
}
}
-func BenchmarkFullASCIIRune(b *testing.B) {
- a := []byte{'a'}
- for i := 0; i < b.N; i++ {
- FullRune(a)
- }
-}
-
-func BenchmarkFullJapaneseRune(b *testing.B) {
- nihon := []byte("本")
- for i := 0; i < b.N; i++ {
- FullRune(nihon)
+// boolSink is used to reference the return value of benchmarked
+// functions to avoid dead code elimination.
+var boolSink bool
+
+func BenchmarkFullRune(b *testing.B) {
+ benchmarks := []struct {
+ name string
+ data []byte
+ }{
+ {"ASCII", []byte("a")},
+ {"Incomplete", []byte("\xf0\x90\x80")},
+ {"Japanese", []byte("本")},
+ }
+ for _, bm := range benchmarks {
+ b.Run(bm.name, func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ boolSink = FullRune(bm.data)
+ }
+ })
}
}
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index e687d77b4d..faf95b871e 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
golang.org/x/crypto/hkdf
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/poly1305
-# golang.org/x/net v0.0.0-20200707034311-ab3426394381
+# golang.org/x/net v0.0.0-20200904194848-62affa334b73
## explicit
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts
diff --git a/test/README.md b/test/README.md
index 068dc1b22b..432d36b653 100644
--- a/test/README.md
+++ b/test/README.md
@@ -6,6 +6,10 @@ To run just these tests, execute:
../bin/go run run.go
+To run just tests from specified files in this directory, execute:
+
+ ../bin/go run run.go -- file1.go file2.go ...
+
Standard library tests should be written as regular Go tests in the appropriate package.
The tool chain and runtime also have regular Go tests in their packages.
diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go
index afd4d66bd9..0bdb66a376 100644
--- a/test/codegen/arithmetic.go
+++ b/test/codegen/arithmetic.go
@@ -42,6 +42,48 @@ func SubMem(arr []int, b, c, d int) int {
return arr[0] - arr[1]
}
+func SubFromConst(a int) int {
+ // ppc64le: `SUBC\tR[0-9]+,\s[$]40,\sR`
+ // ppc64: `SUBC\tR[0-9]+,\s[$]40,\sR`
+ b := 40 - a
+ return b
+}
+
+func SubFromConstNeg(a int) int {
+ // ppc64le: `ADD\t[$]40,\sR[0-9]+,\sR`
+ // ppc64: `ADD\t[$]40,\sR[0-9]+,\sR`
+ c := 40 - (-a)
+ return c
+}
+
+func SubSubFromConst(a int) int {
+ // ppc64le: `ADD\t[$]20,\sR[0-9]+,\sR`
+ // ppc64: `ADD\t[$]20,\sR[0-9]+,\sR`
+ c := 40 - (20 - a)
+ return c
+}
+
+func AddSubFromConst(a int) int {
+ // ppc64le: `SUBC\tR[0-9]+,\s[$]60,\sR`
+ // ppc64: `SUBC\tR[0-9]+,\s[$]60,\sR`
+ c := 40 + (20 - a)
+ return c
+}
+
+func NegSubFromConst(a int) int {
+ // ppc64le: `ADD\t[$]-20,\sR[0-9]+,\sR`
+ // ppc64: `ADD\t[$]-20,\sR[0-9]+,\sR`
+ c := -(20 - a)
+ return c
+}
+
+func NegAddFromConstNeg(a int) int {
+ // ppc64le: `SUBC\tR[0-9]+,\s[$]40,\sR`
+ // ppc64: `SUBC\tR[0-9]+,\s[$]40,\sR`
+ c := -(-40 + a)
+ return c
+}
+
// -------------------- //
// Multiplication //
// -------------------- //
diff --git a/test/codegen/mathbits.go b/test/codegen/mathbits.go
index 942605de55..4c35f26997 100644
--- a/test/codegen/mathbits.go
+++ b/test/codegen/mathbits.go
@@ -76,9 +76,17 @@ func Len64(n uint64) int {
// arm:"CLZ" arm64:"CLZ"
// mips:"CLZ"
// wasm:"I64Clz"
+ // ppc64le:"SUBC","CNTLZD"
+ // ppc64:"SUBC","CNTLZD"
return bits.Len64(n)
}
+func SubFromLen64(n uint64) int {
+ // ppc64le:"CNTLZD",-"SUBC"
+ // ppc64:"CNTLZD",-"SUBC"
+ return 64 - bits.Len64(n)
+}
+
func Len32(n uint32) int {
// amd64:"BSRQ","LEAQ",-"CMOVQEQ"
// s390x:"FLOGR"
@@ -291,6 +299,12 @@ func TrailingZeros64(n uint64) int {
return bits.TrailingZeros64(n)
}
+func TrailingZeros64Subtract(n uint64) int {
+ // ppc64le/power8:"NEG","SUBC","ANDN","POPCNTD"
+ // ppc64le/power9:"SUBC","CNTTZD"
+ return bits.TrailingZeros64(1 - n)
+}
+
func TrailingZeros32(n uint32) int {
// amd64:"BTSQ\\t\\$32","BSFQ"
// arm:"CLZ"
diff --git a/test/codegen/select.go b/test/codegen/select.go
new file mode 100644
index 0000000000..4426924b36
--- /dev/null
+++ b/test/codegen/select.go
@@ -0,0 +1,20 @@
+// asmcheck
+
+// 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 codegen
+
+func f() {
+ ch1 := make(chan int)
+ ch2 := make(chan int)
+ for {
+ // amd64:-`MOVQ\t[$]0, ""..autotmp_3`
+ select {
+ case <-ch1:
+ case <-ch2:
+ default:
+ }
+ }
+}
diff --git a/test/codegen/slices.go b/test/codegen/slices.go
index 40e857f9f6..38e8a62f4b 100644
--- a/test/codegen/slices.go
+++ b/test/codegen/slices.go
@@ -347,3 +347,24 @@ func InitNotSmallSliceLiteral() []int {
42,
}
}
+
+// --------------------------------------- //
+// Test PPC64 SUBFCconst folding rules //
+// triggered by slice operations. //
+// --------------------------------------- //
+
+func SliceWithConstCompare(a []int, b int) []int {
+ var c []int = []int{1, 2, 3, 4, 5}
+ if b+len(a) < len(c) {
+ // ppc64le:-"NEG"
+ // ppc64:-"NEG"
+ return c[b:]
+ }
+ return a
+}
+
+func SliceWithSubtractBound(a []int, b int) []int {
+ // ppc64le:"SUBC",-"NEG"
+ // ppc64:"SUBC",-"NEG"
+ return a[(3 - b):]
+}
diff --git a/test/fixedbugs/bug229.go b/test/fixedbugs/bug229.go
index 4baf65e48b..a30202fa2c 100644
--- a/test/fixedbugs/bug229.go
+++ b/test/fixedbugs/bug229.go
@@ -10,11 +10,11 @@ import "testing"
func main() {
var t testing.T
-
+
// make sure error mentions that
// name is unexported, not just "name not found".
- t.common.name = nil // ERROR "unexported"
-
- println(testing.anyLowercaseName("asdf")) // ERROR "unexported" "undefined: testing.anyLowercaseName"
+ t.common.name = nil // ERROR "unexported"
+
+ println(testing.anyLowercaseName("asdf")) // ERROR "unexported"
}
diff --git a/test/fixedbugs/issue22921.go b/test/fixedbugs/issue22921.go
new file mode 100644
index 0000000000..04f78b2c08
--- /dev/null
+++ b/test/fixedbugs/issue22921.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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 main
+
+import "bytes"
+
+type _ struct{ bytes.nonexist } // ERROR "unexported"
+
+type _ interface{ bytes.nonexist } // ERROR "unexported"
+
+func main() {
+ var _ bytes.Buffer
+ var _ bytes.buffer // ERROR "unexported"
+}
diff --git a/test/fixedbugs/issue24491.go b/test/fixedbugs/issue24491.go
new file mode 100644
index 0000000000..4703368793
--- /dev/null
+++ b/test/fixedbugs/issue24491.go
@@ -0,0 +1,45 @@
+// run
+
+// 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.
+
+// This test makes sure unsafe-uintptr arguments are handled correctly.
+
+package main
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+var done = make(chan bool, 1)
+
+func setup() unsafe.Pointer {
+ s := "ok"
+ runtime.SetFinalizer(&s, func(p *string) { *p = "FAIL" })
+ return unsafe.Pointer(&s)
+}
+
+//go:noinline
+//go:uintptrescapes
+func test(s string, p uintptr) {
+ runtime.GC()
+ if *(*string)(unsafe.Pointer(p)) != "ok" {
+ panic(s + " return unexpected result")
+ }
+ done <- true
+}
+
+func main() {
+ test("normal", uintptr(setup()))
+ <-done
+
+ go test("go", uintptr(setup()))
+ <-done
+
+ func() {
+ defer test("defer", uintptr(setup()))
+ }()
+ <-done
+}
diff --git a/test/fixedbugs/issue38125.go b/test/fixedbugs/issue38125.go
new file mode 100644
index 0000000000..1207aecd39
--- /dev/null
+++ b/test/fixedbugs/issue38125.go
@@ -0,0 +1,22 @@
+// compile
+
+// 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.
+
+// gccgo mishandled embedded methods of type aliases.
+
+package p
+
+type I int
+
+func (I) M() {}
+
+type T = struct {
+ I
+}
+
+func F() {
+ _ = T.M
+ _ = struct { I }.M
+}
diff --git a/test/fixedbugs/issue39505.go b/test/fixedbugs/issue39505.go
new file mode 100644
index 0000000000..711b562867
--- /dev/null
+++ b/test/fixedbugs/issue39505.go
@@ -0,0 +1,31 @@
+// compile
+
+// 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 f() {
+ if len([]int{})-1 < len([]int{}) {
+ }
+
+ var st struct {
+ i int
+ }
+ g := func() string {
+ return ""
+ }
+ h := func(string) string {
+ return g() + g()
+ }
+ s, i := "", 0
+
+ st.i = len(s)
+ i = len(h(s[i+0:i+1])) + len(s[len(s)+1:i+1])
+ s = s[(len(s[i+1:len(s)+1])+1):len(h(""))+1] + (s[i+1 : len([]int{})+i])
+ i = 1 + len([]int{len([]string{s[i+len([]int{}) : len(s)+i]})})
+
+ var ch chan int
+ ch <- len(h("")) - len(s)
+}
diff --git a/test/fixedbugs/issue39505b.go b/test/fixedbugs/issue39505b.go
new file mode 100644
index 0000000000..ecf1ab64f4
--- /dev/null
+++ b/test/fixedbugs/issue39505b.go
@@ -0,0 +1,183 @@
+// run
+
+// 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 main
+
+func main() {
+ ff := []func(){lt_f1, lt_f2, lt_f3, lt_f4, lt_f5, lt_f6, lt_f7, lt_f8, lt_f9,
+ gt_f1, gt_f2, gt_f3, le_f1, le_f2, le_f3, ge_f1, ge_f2, ge_f3}
+
+ for _, f := range ff {
+ f()
+ }
+}
+
+func lt_f1() {
+ const c = 1
+ var a = 0
+ var v *int = &a
+ if *v-c < len([]int{}) {
+ } else {
+ panic("bad")
+ }
+}
+
+func lt_f2() {
+ const c = 10
+ var a = 0
+ var v *int = &a
+ if *v+c < len([]int{}) {
+ panic("bad")
+ }
+}
+
+func lt_f3() {
+ const c = -10
+ var a = 0
+ var v *int = &a
+ if *v|0xff+c < len([]int{}) {
+ panic("bad")
+ }
+}
+
+func lt_f4() {
+ const c = 10
+ var a = 0
+ var v *int = &a
+ if *v|0x0f+c < len([]int{}) {
+ panic("bad")
+ }
+}
+
+func lt_f5() {
+ const c int32 = 1
+ var a int32 = 0
+ var v *int32 = &a
+ if *v-c < int32(len([]int32{})) {
+ } else {
+ panic("bad")
+ }
+}
+
+func lt_f6() {
+ const c int32 = 10
+ var a int32 = 0
+ var v *int32 = &a
+ if *v+c < int32(len([]int32{})) {
+ panic("bad")
+ }
+}
+
+func lt_f7() {
+ const c int32 = -10
+ var a int32 = 0
+ var v *int32 = &a
+ if *v|0xff+c < int32(len([]int{})) {
+ panic("bad")
+ }
+}
+
+func lt_f8() {
+ const c int32 = 10
+ var a int32 = 0
+ var v *int32 = &a
+ if *v|0x0f+c < int32(len([]int{})) {
+ panic("bad")
+ }
+}
+
+func lt_f9() {
+ const c int32 = -10
+ var a int32 = 0
+ var v *int32 = &a
+ if *v|0x0a+c < int32(len([]int{})) {
+ panic("bad")
+ }
+}
+
+func gt_f1() {
+ const c = 1
+ var a = 0
+ var v *int = &a
+ if len([]int{}) > *v-c {
+ } else {
+ panic("bad")
+ }
+}
+
+func gt_f2() {
+ const c = 10
+ var a = 0
+ var v *int = &a
+ if len([]int{}) > *v|0x0f+c {
+ panic("bad")
+ }
+}
+
+func gt_f3() {
+ const c int32 = 10
+ var a int32 = 0
+ var v *int32 = &a
+ if int32(len([]int{})) > *v|0x0f+c {
+ panic("bad")
+ }
+}
+
+func le_f1() {
+ const c = -10
+ var a = 0
+ var v *int = &a
+ if *v|0xff+c <= len([]int{}) {
+ panic("bad")
+ }
+}
+
+func le_f2() {
+ const c = 0xf
+ var a = 0
+ var v *int = &a
+ if *v|0xf-c <= len([]int{}) {
+ } else {
+ panic("bad")
+ }
+}
+
+func le_f3() {
+ const c int32 = -10
+ var a int32 = 0
+ var v *int32 = &a
+ if *v|0xff+c <= int32(len([]int{})) {
+ panic("bad")
+ }
+}
+
+func ge_f1() {
+ const c = -10
+ var a = 0
+ var v *int = &a
+ if len([]int{}) >= *v|0xff+c {
+ panic("bad")
+ }
+}
+
+func ge_f2() {
+ const c int32 = 10
+ var a int32 = 0
+ var v *int32 = &a
+ if int32(len([]int{})) >= *v|0x0f+c {
+ panic("bad")
+ }
+}
+
+func ge_f3() {
+ const c = -10
+ var a = 0
+ var v *int = &a
+ if len([]int{}) >= *v|0x0a+c {
+ } else {
+ panic("bad")
+ }
+}
diff --git a/test/fixedbugs/issue41247.go b/test/fixedbugs/issue41247.go
new file mode 100644
index 0000000000..2df919c9e6
--- /dev/null
+++ b/test/fixedbugs/issue41247.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// 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 f() [2]int {
+ return [...]int{2: 0} // ERROR "cannot use \[\.\.\.\]int literal \(type \[3\]int\)"
+}
diff --git a/test/fixedbugs/issue8606b.go b/test/fixedbugs/issue8606b.go
new file mode 100644
index 0000000000..448ea566f0
--- /dev/null
+++ b/test/fixedbugs/issue8606b.go
@@ -0,0 +1,63 @@
+// run
+
+// 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.
+
+// This is an optimization check. We want to make sure that we compare
+// string lengths, and other scalar fields, before checking string
+// contents. There's no way to verify this in the language, and
+// codegen tests in test/codegen can't really detect ordering
+// optimizations like this. Instead, we generate invalid strings with
+// bad backing store pointers but nonzero length, so we can check that
+// the backing store never gets compared.
+//
+// We use two different bad strings so that pointer comparisons of
+// backing store pointers fail.
+
+package main
+
+import (
+ "fmt"
+ "reflect"
+ "unsafe"
+)
+
+func bad1() string {
+ s := "foo"
+ (*reflect.StringHeader)(unsafe.Pointer(&s)).Data = 1 // write bad value to data ptr
+ return s
+}
+func bad2() string {
+ s := "foo"
+ (*reflect.StringHeader)(unsafe.Pointer(&s)).Data = 2 // write bad value to data ptr
+ return s
+}
+
+type SI struct {
+ s string
+ i int
+}
+
+type SS struct {
+ s string
+ t string
+}
+
+func main() {
+ for _, test := range []struct {
+ a, b interface{}
+ }{
+ {SI{s: bad1(), i: 1}, SI{s: bad2(), i: 2}},
+ {SS{s: bad1(), t: "a"}, SS{s: bad2(), t: "aa"}},
+ {SS{s: "a", t: bad1()}, SS{s: "b", t: bad2()}},
+ // This one would panic because the length of both strings match, and we check
+ // the body of the bad strings before the body of the good strings.
+ //{SS{s: bad1(), t: "a"}, SS{s: bad2(), t: "b"}},
+ } {
+ if test.a == test.b {
+ panic(fmt.Sprintf("values %#v and %#v should not be equal", test.a, test.b))
+ }
+ }
+
+}
diff --git a/test/notinheap2.go b/test/notinheap2.go
index 944f2993ab..de1e6db1d3 100644
--- a/test/notinheap2.go
+++ b/test/notinheap2.go
@@ -13,12 +13,14 @@ type nih struct {
next *nih
}
-// Globals and stack variables are okay.
+// Global variables are okay.
var x nih
+// Stack variables are not okay.
+
func f() {
- var y nih
+ var y nih // ERROR "nih is go:notinheap; stack allocation disallowed"
x = y
}
@@ -26,11 +28,17 @@ func f() {
var y *nih
var z []nih
+var w []nih
+var n int
func g() {
y = new(nih) // ERROR "heap allocation disallowed"
z = make([]nih, 1) // ERROR "heap allocation disallowed"
z = append(z, x) // ERROR "heap allocation disallowed"
+ // Test for special case of OMAKESLICECOPY
+ x := make([]nih, n) // ERROR "heap allocation disallowed"
+ copy(x, z)
+ z = x
}
// Writes don't produce write barriers.
diff --git a/test/runtime.go b/test/runtime.go
index 0cf781b814..bccc9b53af 100644
--- a/test/runtime.go
+++ b/test/runtime.go
@@ -17,5 +17,5 @@ package main
import "runtime"
func main() {
- runtime.printbool(true) // ERROR "unexported" "undefined"
+ runtime.printbool(true) // ERROR "unexported"
}