mirror of
https://github.com/golang/go.git
synced 2026-01-31 08:02:06 +03:00
Compare commits
13 Commits
go1.8.2
...
dev.garbag
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d4942afe0 | ||
|
|
8b25a00e6d | ||
|
|
42afbd9e63 | ||
|
|
f9f6c90ed1 | ||
|
|
69161e279e | ||
|
|
fb4c718209 | ||
|
|
81b74bf9c5 | ||
|
|
edb54c300f | ||
|
|
312aa09996 | ||
|
|
d491e550c3 | ||
|
|
641c32dafa | ||
|
|
2e495a1df6 | ||
|
|
344476d23c |
54
README.md
54
README.md
@@ -5,37 +5,39 @@ reliable, and efficient software.
|
||||
|
||||

|
||||
|
||||
For documentation about how to install and use Go,
|
||||
visit https://golang.org/ or load doc/install-source.html
|
||||
in your web browser.
|
||||
|
||||
Our canonical Git repository is located at https://go.googlesource.com/go.
|
||||
There is a mirror of the repository at https://github.com/golang/go.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed under the
|
||||
BSD-style license found in the LICENSE file.
|
||||
|
||||
### Download and Install
|
||||
|
||||
#### Binary Distributions
|
||||
|
||||
Official binary distributions are available at https://golang.org/dl/.
|
||||
|
||||
After downloading a binary release, visit https://golang.org/doc/install
|
||||
or load doc/install.html in your web browser for installation
|
||||
instructions.
|
||||
|
||||
#### Install From Source
|
||||
|
||||
If a binary distribution is not available for your combination of
|
||||
operating system and architecture, visit
|
||||
https://golang.org/doc/install/source or load doc/install-source.html
|
||||
in your web browser for source installation instructions.
|
||||
|
||||
### Contributing
|
||||
|
||||
Go is the work of hundreds of contributors. We appreciate your help!
|
||||
|
||||
To contribute, please read the contribution guidelines:
|
||||
https://golang.org/doc/contribute.html
|
||||
|
||||
Note that the Go project does not use GitHub pull requests, and that
|
||||
we use the issue tracker for bug reports and proposals only. See
|
||||
https://golang.org/wiki/Questions for a list of places to ask
|
||||
questions about the Go language.
|
||||
##### Note that we do not accept pull requests and that we use the issue tracker for bug reports and proposals only. Please ask questions on https://forum.golangbridge.org or https://groups.google.com/forum/#!forum/golang-nuts.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
--
|
||||
|
||||
## Binary Distribution Notes
|
||||
|
||||
If you have just untarred a binary Go distribution, you need to set
|
||||
the environment variable $GOROOT to the full path of the go
|
||||
directory (the one containing this file). You can omit the
|
||||
variable if you unpack it into /usr/local/go, or if you rebuild
|
||||
from sources by running all.bash (see doc/install-source.html).
|
||||
You should also add the Go binary directory $GOROOT/bin
|
||||
to your shell's path.
|
||||
|
||||
For example, if you extracted the tar file into $HOME/go, you might
|
||||
put the following in your .profile:
|
||||
|
||||
export GOROOT=$HOME/go
|
||||
export PATH=$PATH:$GOROOT/bin
|
||||
|
||||
See https://golang.org/doc/install or doc/install.html for more details.
|
||||
|
||||
@@ -148,26 +148,29 @@ These actions are explicitly forbidden in Go spaces:
|
||||
|
||||
<p>
|
||||
The Go spaces are not free speech venues; they are for discussion about Go.
|
||||
Each of these spaces have their own moderators.
|
||||
These spaces have moderators.
|
||||
The goal of the moderators is to facilitate civil discussion about Go.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When using the official Go spaces you should act in the spirit of the “Gopher
|
||||
values”.
|
||||
If a reported conflict cannot be resolved amicably, the CoC Working Group
|
||||
may make a recommendation to the relevant forum moderators.
|
||||
If you conduct yourself in a way that is explicitly forbidden by the CoC,
|
||||
you will be warned and asked to stop.
|
||||
If you do not stop, you will be removed from our community spaces temporarily.
|
||||
Repeated, willful breaches of the CoC will result in a permanent ban.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
CoC Working Group members and forum moderators are held to a higher standard than other community members.
|
||||
If a working group member or moderator creates an inappropriate situation, they
|
||||
should expect less leeway than others, and should expect to be removed from
|
||||
their position if they cannot adhere to the CoC.
|
||||
Moderators are held to a higher standard than other community members.
|
||||
If a moderator creates an inappropriate situation, they should expect less
|
||||
leeway than others, and should expect to be removed from their position if they
|
||||
cannot adhere to the CoC.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Complaints about working group member or moderator actions must be handled
|
||||
using the reporting process below.
|
||||
Complaints about moderator actions must be handled using the reporting process
|
||||
below.
|
||||
</p>
|
||||
|
||||
<h2 id="reporting">Reporting issues</h2>
|
||||
@@ -182,6 +185,8 @@ satisfaction of all parties. They are:
|
||||
<ul>
|
||||
<li>Aditya Mukerjee <dev@chimeracoder.net>
|
||||
<li>Andrew Gerrand <adg@golang.org>
|
||||
<li>Dave Cheney <dave@cheney.net>
|
||||
<li>Jason Buberel <jbuberel@google.com>
|
||||
<li>Peggy Li <peggyli.224@gmail.com>
|
||||
<li>Sarah Adams <sadams.codes@gmail.com>
|
||||
<li>Steve Francia <steve.francia@gmail.com>
|
||||
@@ -196,10 +201,13 @@ particular individual or group.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Mail <a href="mailto:conduct@golang.org">conduct@golang.org</a>.
|
||||
<li>Mail <a href="mailto:conduct@golang.org">conduct@golang.org</a> or
|
||||
<a href="https://golang.org/s/conduct-report">submit an anonymous report</a>.
|
||||
<ul>
|
||||
<li>Your message will reach the Working Group.
|
||||
<li>Reports are confidential within the Working Group.
|
||||
<li>Should you choose to remain anonymous then the Working Group cannot
|
||||
notify you of the outcome of your report.
|
||||
<li>You may contact a member of the group directly if you do not feel
|
||||
comfortable contacting the group as a whole. That member will then raise
|
||||
the issue with the Working Group as a whole, preserving the privacy of the
|
||||
@@ -221,8 +229,11 @@ particular individual or group.
|
||||
<li>The Working Group will reach a decision as to how to act. These may include:
|
||||
<ul>
|
||||
<li>Nothing.
|
||||
<li>Passing the report along to the offender.
|
||||
<li>A recommendation of action to the relevant forum moderators.
|
||||
<li>A request for a private or public apology.
|
||||
<li>A private or public warning.
|
||||
<li>An imposed vacation (for instance, asking someone to abstain for a week
|
||||
from a mailing list or IRC).
|
||||
<li>A permanent or temporary ban from some or all Go spaces.
|
||||
</ul>
|
||||
<li>The Working Group will reach out to the original reporter to let them know
|
||||
the decision.
|
||||
@@ -235,6 +246,7 @@ particular individual or group.
|
||||
conflicts in the most harmonious way possible.</b>
|
||||
We hope that in most cases issues may be resolved through polite discussion and
|
||||
mutual agreement.
|
||||
Bannings and other forceful measures are to be employed only as a last resort.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -34,7 +34,6 @@ We encourage all Go users to subscribe to
|
||||
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="/doc/go1.8">Go 1.8</a> <small>(February 2017)</small></li>
|
||||
<li><a href="/doc/go1.7">Go 1.7</a> <small>(August 2016)</small></li>
|
||||
<li><a href="/doc/go1.6">Go 1.6</a> <small>(February 2016)</small></li>
|
||||
<li><a href="/doc/go1.5">Go 1.5</a> <small>(August 2015)</small></li>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<!--{
|
||||
"Title": "Contribution Guide"
|
||||
"Title": "Contribution Guidelines"
|
||||
}-->
|
||||
|
||||
<h2 id="Introduction">Introduction</h2>
|
||||
|
||||
<p>
|
||||
The Go project welcomes all contributors. The process of contributing
|
||||
to the Go project may be different than many projects you are used to.
|
||||
This document is intended as a guide to help you through the contribution
|
||||
process. This guide assumes you have a basic understanding of Git and Go.
|
||||
This document explains how to contribute changes to the Go project.
|
||||
It assumes you have followed the
|
||||
<a href="/doc/install/source">installation instructions</a> and
|
||||
have <a href="code.html">written and tested your code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -18,54 +20,103 @@ see <a href="gccgo_contribute.html">Contributing to gccgo</a>.)
|
||||
Sensitive security-related issues should be reported to <a href="mailto:security@golang.org">security@golang.org</a>.
|
||||
</p>
|
||||
|
||||
<h1 id="contributor">Becoming a contributor</h1>
|
||||
<h2 id="Design">Discuss your design</h2>
|
||||
|
||||
<p>
|
||||
Before you can contribute to the Go project you need to setup a few prerequisites.
|
||||
The Go project uses <a href="https://www.gerritcodereview.com/">Gerrit</a>, an open
|
||||
source online tool, to perform all code reviews.
|
||||
Gerrit uses your email address as a unique identifier.
|
||||
The Go project contributing flow is currently configured to work only with Google Accounts.
|
||||
You must go through the following process <em>prior to contributing</em>.
|
||||
You only need to do this once per Google Account.
|
||||
</p>
|
||||
|
||||
<h2 id="auth">Configure Git to use Gerrit</h2>
|
||||
<p>
|
||||
You'll need a web browser and a command line terminal.
|
||||
You should already have Git installed.
|
||||
The project welcomes submissions but please let everyone know what
|
||||
you're working on if you want to change or add to the Go repositories.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Gerrit uses Google Accounts for authentication.
|
||||
If you don't have a Google Account, you can create an account which
|
||||
Before undertaking to write something new for the Go project,
|
||||
please <a href="https://golang.org/issue/new">file an issue</a>
|
||||
(or claim an <a href="https://golang.org/issues">existing issue</a>).
|
||||
Significant changes must go through the
|
||||
<a href="https://golang.org/s/proposal-process">change proposal process</a>
|
||||
before they can be accepted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This process gives everyone a chance to validate the design,
|
||||
helps prevent duplication of effort,
|
||||
and ensures that the idea fits inside the goals for the language and tools.
|
||||
It also checks that the design is sound before code is written;
|
||||
the code review tool is not the place for high-level discussions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When planning work, please note that the Go project follows a
|
||||
<a href="https://golang.org/wiki/Go-Release-Cycle">six-month
|
||||
development cycle</a>. The latter half of each cycle is a three-month
|
||||
feature freeze during which only bug fixes and doc updates are accepted.
|
||||
New work cannot be submitted during a feature freeze.
|
||||
</p>
|
||||
|
||||
<h2 id="Testing">Testing redux</h2>
|
||||
|
||||
<p>
|
||||
You've <a href="code.html">written and tested your code</a>, but
|
||||
before sending code out for review, run all the tests for the whole
|
||||
tree to make sure the changes don't break other packages or programs:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ cd go/src
|
||||
$ ./all.bash
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
(To build under Windows use <code>all.bat</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
After running for a while, the command should print
|
||||
"<code>ALL</code> <code>TESTS</code> <code>PASSED</code>".
|
||||
</p>
|
||||
|
||||
<h2 id="Code_review">Code review</h2>
|
||||
|
||||
<p>
|
||||
Changes to Go must be reviewed before they are accepted,
|
||||
no matter who makes the change.
|
||||
A custom git command called <code>git-codereview</code>,
|
||||
discussed below, helps manage the code review process through a Google-hosted
|
||||
<a href="https://go-review.googlesource.com/">instance</a> of the code review
|
||||
system called <a href="https://www.gerritcodereview.com/">Gerrit</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="auth">Set up authentication for code review</h3>
|
||||
|
||||
<p>
|
||||
Gerrit uses Google Accounts for authentication. If you don't have
|
||||
a Google Account, you can create an account which
|
||||
<a href="https://www.google.com/accounts/NewAccount">includes
|
||||
a new Gmail email account</a> or create an account associated
|
||||
<a href="https://accounts.google.com/SignUpWithoutGmail">with your existing
|
||||
email address</a>.
|
||||
</p>
|
||||
|
||||
<h3>Step 1: Sign in to googlesource and generate a password</h3>
|
||||
<p>
|
||||
The email address associated with the Google Account you use will be recorded in
|
||||
the <a href="https://go.googlesource.com/go/+log/">change log</a>
|
||||
and in the <a href="/CONTRIBUTORS">contributors file</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Visit <a href="https://go.googlesource.com">go.googlesource.com</a>
|
||||
To set up your account in Gerrit, visit
|
||||
<a href="https://go.googlesource.com">go.googlesource.com</a>
|
||||
and click on "Generate Password" in the page's top right menu bar.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You will be redirected to accounts.google.com to sign in.
|
||||
</p>
|
||||
|
||||
<h3>Step 2: Run the provided script</h3>
|
||||
<p>
|
||||
After signing in, you are taken to a page on go.googlesource.com with the title "Configure Git".
|
||||
This page contains a personalized script which when run locally will configure git
|
||||
to have your unique authentication key.
|
||||
This key is paired with one generated server side similar to how ssh keys work.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Copy and run this script locally in your command line terminal.
|
||||
(On a Windows computer using cmd you should instead follow the instructions
|
||||
in the yellow box to run the command. If you are using git-bash use the same
|
||||
script as *nix.)
|
||||
Once signed in, you are returned back to go.googlesource.com to "Configure Git".
|
||||
Follow the instructions on the page.
|
||||
(If you are on a Windows computer, you should instead follow the instructions
|
||||
in the yellow box to run the command.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -73,25 +124,23 @@ Your secret authentication token is now in a <code>.gitcookie</code> file
|
||||
and Git is configured to use this file.
|
||||
</p>
|
||||
|
||||
<h3 id="gerrit">Step 3: Register with Gerrit</h3>
|
||||
<h3 id="gerrit">Register with Gerrit</h3>
|
||||
|
||||
<p>
|
||||
Now that you have your authentication token, you need to register your
|
||||
account with Gerrit.
|
||||
To do this, visit <a href="https://go-review.googlesource.com/login/">
|
||||
go-review.googlesource.com/login/</a>.
|
||||
Sign in using the same Google Account you used above.
|
||||
Now that you have your authentication token,
|
||||
you need to register your account with Gerrit.
|
||||
To do this, visit
|
||||
<a href="https://go-review.googlesource.com/login/">
|
||||
go-review.googlesource.com/login/</a>. You will immediately be redirected
|
||||
to Google Accounts. Sign in using the same Google Account you used above.
|
||||
That is all that is required.
|
||||
</p>
|
||||
|
||||
<h2 id="cla">Contributor License Agreement</h2>
|
||||
|
||||
<h3 id="which_cla">Which CLA</h3>
|
||||
<p>
|
||||
Before sending your first change to the Go project
|
||||
you must have completed one of the following two CLAs.
|
||||
Which CLA you should sign depends on who owns the copyright to your work.
|
||||
</p>
|
||||
<h3 id="cla">Contributor License Agreement</h3>
|
||||
|
||||
<p>Gerrit serves as the gatekeeper and uses your e-mail address as the key.
|
||||
To send your first change to the Go project from a given address,
|
||||
you must have completed one of the contributor license agreements:
|
||||
<ul>
|
||||
<li>
|
||||
If you are the copyright holder, you will need to agree to the
|
||||
@@ -102,49 +151,37 @@ contributor license agreement</a>, which can be completed online.
|
||||
If your organization is the copyright holder, the organization
|
||||
will need to agree to the
|
||||
<a href="https://developers.google.com/open-source/cla/corporate">corporate
|
||||
contributor license agreement</a>.<br>
|
||||
contributor license agreement</a>.
|
||||
(If the copyright holder for your code has already completed the
|
||||
agreement in connection with another Google open source project,
|
||||
it does not need to be completed again.)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<i>If the copyright holder for your contribution has already completed the
|
||||
agreement in connection with another Google open source project,
|
||||
it does not need to be completed again.</i>
|
||||
</p>
|
||||
|
||||
<h3 id="signing_cla">Completing the CLA</h3>
|
||||
|
||||
<p>
|
||||
You can see your currently signed agreements and sign new ones through the Gerrit
|
||||
interface.
|
||||
To do this, <a href="https://go-review.googlesource.com/login/">Log into Gerrit</a>,
|
||||
You can use the links above to create and sign the contributor license agreement
|
||||
or you can show your current agreements and create new ones through the Gerrit
|
||||
interface. <a href="https://go-review.googlesource.com/login/">Log into Gerrit</a>,
|
||||
click your name in the upper-right, choose "Settings", then select "Agreements"
|
||||
from the topics on the left.
|
||||
If you do not have a signed agreement listed here,
|
||||
from the topics on the left. If you do not have a signed agreement listed here,
|
||||
you can create one by clicking "New Contributor Agreement" and following the steps.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the copyright holder for the code you are submitting changes — for example,
|
||||
if you start contributing code on behalf of a new company — please send email
|
||||
to golang-dev and let us know, so that we can make sure an appropriate agreement is
|
||||
completed and update the <code>AUTHORS</code> file.
|
||||
This rigmarole only needs to be done for your first submission for each email address.
|
||||
</p>
|
||||
|
||||
<span id="Code_review"></span>
|
||||
<h1 id="prepare_dev_env">Preparing a Development Environment for Contributing</h1>
|
||||
|
||||
<h2 id="git-codereview">Setting up Git for submission to Gerrit</h2>
|
||||
<p>
|
||||
Changes to Go must be reviewed before they are accepted, no matter who makes the change.
|
||||
A custom git command called <code>git-codereview</code>, discussed below,
|
||||
helps manage the code review process through a Google-hosted
|
||||
<a href="https://go-review.googlesource.com/">instance</a> Gerrit.
|
||||
If the copyright holder for the code you are submitting changes—for example,
|
||||
if you start contributing code on behalf of a new company—please send email
|
||||
to let us know, so that we can make sure an appropriate agreement is completed
|
||||
and update the <code>AUTHORS</code> file.
|
||||
</p>
|
||||
|
||||
<h3 id="git-codereview_install">Install the git-codereview command</h3>
|
||||
<h3 id="git-codereview">Install the git-codereview command</h3>
|
||||
|
||||
<p>
|
||||
Install the <code>git-codereview</code> command by running,
|
||||
Now install the <code>git-codereview</code> command by running,
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -164,29 +201,19 @@ $ git codereview help
|
||||
prints help text, not an error.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
On Windows, when using git-bash you must make sure that
|
||||
<code>git-codereview.exe</code> is in your git exec-path.
|
||||
Run <code>git --exec-path</code> to discover the right location then create a
|
||||
symbolic link or simply copy the executible from $GOPATH/bin to this directory.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note to Git aficionados:</b>
|
||||
The <code>git-codereview</code> command is not required to
|
||||
upload and manage Gerrit code reviews.
|
||||
For those who prefer plain Git, the text below gives the Git equivalent of
|
||||
each git-codereview command.
|
||||
upload and manage Gerrit code reviews. For those who prefer plain Git, the text
|
||||
below gives the Git equivalent of each git-codereview command.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you do use plain Git, note that you still need the commit hooks that the
|
||||
git-codereview command configures; those hooks add a Gerrit
|
||||
<code>Change-Id</code> line to the commit message and check that all Go source
|
||||
files have been formatted with gofmt.
|
||||
Even if you intend to use plain Git for
|
||||
daily work, install the hooks in a new Git checkout by running
|
||||
<code>git-codereview</code> <code>hooks</code>.
|
||||
<p>If you do use plain
|
||||
Git, note that you still need the commit hooks that the git-codereview command
|
||||
configures; those hooks add a Gerrit <code>Change-Id</code> line to the commit
|
||||
message and check that all Go source files have been formatted with gofmt. Even
|
||||
if you intend to use plain Git for daily work, install the hooks in a new Git
|
||||
checkout by running <code>git-codereview</code> <code>hooks</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -237,8 +264,7 @@ To install them, copy this text into your Git configuration file
|
||||
sync = codereview sync
|
||||
</pre>
|
||||
|
||||
<span id="help"></span>
|
||||
<h3 id="understanding_git-codereview">Understanding the git-codereview command</h3>
|
||||
<h3 id="help">Understanding the git-codereview command</h3>
|
||||
|
||||
<p>After installing the <code>git-codereview</code> command, you can run</p>
|
||||
|
||||
@@ -251,70 +277,11 @@ to learn more about its commands.
|
||||
You can also read the <a href="https://godoc.org/golang.org/x/review/git-codereview">command documentation</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h1 id="making_a_contribution">Making a Contribution</h1>
|
||||
|
||||
<h2 id="Design">Discuss your design</h2>
|
||||
|
||||
<p>
|
||||
The project welcomes submissions but please let everyone know what
|
||||
you're working on if you want to change or add to the Go repositories.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Before undertaking to write something new for the Go project,
|
||||
please <a href="https://golang.org/issue/new">file an issue</a>
|
||||
(or claim an <a href="https://golang.org/issues">existing issue</a>).
|
||||
Significant changes must go through the
|
||||
<a href="https://golang.org/s/proposal-process">change proposal process</a>
|
||||
before they can be accepted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This process gives everyone a chance to validate the design,
|
||||
helps prevent duplication of effort,
|
||||
and ensures that the idea fits inside the goals for the language and tools.
|
||||
It also checks that the design is sound before code is written;
|
||||
the code review tool is not the place for high-level discussions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When planning work, please note that the Go project follows a <a
|
||||
href="https://golang.org/wiki/Go-Release-Cycle">six-month development cycle</a>.
|
||||
The latter half of each cycle is a three-month feature freeze during
|
||||
which only bug fixes and doc updates are accepted. New contributions can be
|
||||
sent during a feature freeze but will not be accepted until the freeze thaws.
|
||||
</p>
|
||||
|
||||
<h2 id="making_a_change">Making a change</h2>
|
||||
|
||||
<h3 id="checkout_go">Getting Go Source</h3>
|
||||
<p>
|
||||
First you need to have a local copy of the source checked out from the correct
|
||||
repository.
|
||||
As Go builds Go you will also likely need to have a working version
|
||||
of Go installed (some documentation changes may not need this).
|
||||
This should be a recent version of Go and can be obtained via any package or
|
||||
binary distribution or you can build it from source.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You should checkout the Go source repo anywhere you want as long as it's
|
||||
outside of your $GOPATH.
|
||||
Go to a directory where you want the source to appear and run the following
|
||||
command in a terminal.
|
||||
</p>
|
||||
|
||||
<pre><code>
|
||||
$ git clone https://go.googlesource.com/go
|
||||
$ cd go
|
||||
</code></pre>
|
||||
|
||||
<h3 id="master">Contributing to the main Go tree</h3>
|
||||
<h3 id="master">Switch to the master branch</h3>
|
||||
|
||||
<p>
|
||||
Most Go installations use a release branch, but new changes should
|
||||
only be made based on the master branch. <br>
|
||||
only be made based on the master branch.
|
||||
(They may be applied later to a release branch as part of the release process,
|
||||
but most contributors won't do this themselves.)
|
||||
Before making a change, make sure you start on the master branch:
|
||||
@@ -330,61 +297,10 @@ $ git sync
|
||||
<code>git</code> <code>pull</code> <code>-r</code>.)
|
||||
</p>
|
||||
|
||||
<h3 id="subrepos">Contributing to subrepositories (golang.org/x/...)</h3>
|
||||
|
||||
<p>
|
||||
If you are contributing a change to a subrepository, obtain the
|
||||
Go package using <code>go get</code>. For example, to contribute
|
||||
to <code>golang.org/x/oauth2</code>, check out the code by running:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ go get -d golang.org/x/oauth2/...
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Then, change your directory to the package's source directory
|
||||
(<code>$GOPATH/src/golang.org/x/oauth2</code>).
|
||||
</p>
|
||||
|
||||
<h3 id="change">Make your changes</h3>
|
||||
|
||||
<p>
|
||||
The entire checked-out tree is editable.
|
||||
Make your changes as you see fit ensuring that you create appropriate
|
||||
tests along with your changes. Test your changes as you go.
|
||||
</p>
|
||||
|
||||
<h3 id="copyright">Copyright</h3>
|
||||
|
||||
<p>
|
||||
Files in the Go repository don't list author names, both to avoid clutter
|
||||
and to avoid having to keep the lists up to date.
|
||||
Instead, your name will appear in the
|
||||
<a href="https://golang.org/change">change log</a> and in the <a
|
||||
href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file and perhaps the <a
|
||||
href="/AUTHORS"><code>AUTHORS</code></a> file.
|
||||
These files are automatically generated from the commit logs perodically.
|
||||
The <a href="/AUTHORS"><code>AUTHORS</code></a> file defines who “The Go
|
||||
Authors”—the copyright holders—are.
|
||||
</p>
|
||||
|
||||
<p>New files that you contribute should use the standard copyright header:</p>
|
||||
|
||||
<pre>
|
||||
// Copyright 2017 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.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Files in the repository are copyright the year they are added.
|
||||
Do not update the copyright year on files that you change.
|
||||
</p>
|
||||
|
||||
<h3 id="commit_changes">Commit your changes</h3>
|
||||
<h3 id="change">Make a change</h3>
|
||||
|
||||
<p>
|
||||
The entire checked-out tree is writable.
|
||||
Once you have edited files, you must tell Git that they have been modified.
|
||||
You must also tell Git about any files that are added, removed, or renamed files.
|
||||
These operations are done with the usual Git commands,
|
||||
@@ -395,19 +311,16 @@ and
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you have the changes queued up, you will want to commit them.
|
||||
In the Go contribution workflow this is done with a `git change` command,
|
||||
which creates a local branch and commits the changes directly to that local branch.
|
||||
</p>
|
||||
If you wish to checkpoint your work, or are ready to send the code out for review, run</p>
|
||||
|
||||
<pre>
|
||||
$ git change <i><branch></i>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
from any directory in your Go repository to commit the changes so far.
|
||||
The name <i><branch></i> is an arbitrary one you choose to identify the
|
||||
local branch containing your changes and will not be used elsewhere.
|
||||
This is an offline operation and nothing will be sent to the server yet.
|
||||
local branch containing your changes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -418,11 +331,9 @@ then <code>git</code> <code>commit</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As the `git commit` is the final step, Git will open an editor to ask for a
|
||||
commit message.
|
||||
Git will open a change description file in your editor.
|
||||
(It uses the editor named by the <code>$EDITOR</code> environment variable,
|
||||
<code>vi</code> by default.)
|
||||
|
||||
The file will look like:
|
||||
</p>
|
||||
|
||||
@@ -441,7 +352,7 @@ At the beginning of this file is a blank line; replace it
|
||||
with a thorough description of your change.
|
||||
The first line of the change description is conventionally a one-line
|
||||
summary of the change, prefixed by the primary affected package,
|
||||
and is used as the subject for code review email.
|
||||
and is used as the subject for code review mail.
|
||||
It should complete the sentence "This change modifies Go to _____."
|
||||
The rest of the description elaborates and should provide context for the
|
||||
change and explain what it does.
|
||||
@@ -484,7 +395,7 @@ the command and move that file to a different branch.
|
||||
<p>
|
||||
The special notation "Fixes #159" associates the change with issue 159 in the
|
||||
<a href="https://golang.org/issue/159">Go issue tracker</a>.
|
||||
When this change is eventually applied, the issue
|
||||
When this change is eventually submitted, the issue
|
||||
tracker will automatically mark the issue as fixed.
|
||||
(There are several such conventions, described in detail in the
|
||||
<a href="https://help.github.com/articles/closing-issues-via-commit-messages/">GitHub Issue Tracker documentation</a>.)
|
||||
@@ -495,13 +406,6 @@ Once you have finished writing the commit message,
|
||||
save the file and exit the editor.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You must have the $EDITOR environment variable set properly and working properly (exiting cleanly)
|
||||
for this operation to succeed.
|
||||
If you run into any issues at this step, it's likely your editor isn't exiting cleanly.
|
||||
Try setting a different editor in your $EDITOR environment variable.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you wish to do more editing, re-stage your changes using
|
||||
<code>git</code> <code>add</code>, and then run
|
||||
@@ -512,8 +416,8 @@ $ git change
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to update the change description and incorporate the staged changes.
|
||||
The change description contains a <code>Change-Id</code> line near the bottom,
|
||||
to update the change description and incorporate the staged changes. The
|
||||
change description contains a <code>Change-Id</code> line near the bottom,
|
||||
added by a Git commit hook during the initial
|
||||
<code>git</code> <code>change</code>.
|
||||
That line is used by Gerrit to match successive uploads of the same change.
|
||||
@@ -525,44 +429,35 @@ Do not edit or delete it.
|
||||
runs <code>git</code> <code>commit</code> <code>--amend</code>.)
|
||||
</p>
|
||||
|
||||
<h3 id="Testing">Testing</h3>
|
||||
<h3 id="mail">Mail the change for review</h3>
|
||||
|
||||
<p>
|
||||
You've <a href="code.html">written and tested your code</a>, but
|
||||
before sending code out for review, run all the tests for the whole
|
||||
tree to make sure the changes don't break other packages or programs:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ cd go/src
|
||||
$ ./all.bash
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
(To build under Windows use <code>all.bat</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
After running for a while, the command should print
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
"ALL TESTS PASSED".
|
||||
</pre>
|
||||
|
||||
<h3 id="mail">Send the change for review</h3>
|
||||
|
||||
<p>
|
||||
Once the change is ready, send it for review.
|
||||
This is similar to a <code>git push</code> in a GitHub style workflow.
|
||||
This is done via the mail alias setup earlier which despite its name, doesn't
|
||||
directly mail anything, it simply sends the change to Gerrit via git push.
|
||||
Once the change is ready, mail it out for review:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git mail
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You can specify a reviewer or CC interested parties
|
||||
using the <code>-r</code> or <code>-cc</code> options.
|
||||
Both accept a comma-separated list of email addresses:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git mail -r joe@golang.org -cc mabel@example.com,math-nuts@swtch.com
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Unless explicitly told otherwise, such as in the discussion leading
|
||||
up to sending in the change list, it's better not to specify a reviewer.
|
||||
All changes are automatically CC'ed to the
|
||||
<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews@googlegroups.com</a>
|
||||
mailing list. If this is your first ever change, there may be a moderation
|
||||
delay before it appears on the mailing list, to prevent spam.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(In Git terms, <code>git</code> <code>mail</code> pushes the local committed
|
||||
changes to Gerrit using <code>git</code> <code>push</code> <code>origin</code>
|
||||
@@ -584,76 +479,7 @@ remote: New Changes:
|
||||
remote: https://go-review.googlesource.com/99999 math: improved Sin, Cos and Tan precision for very large arguments
|
||||
</pre>
|
||||
|
||||
<h3>Troubleshooting</h3>
|
||||
|
||||
<p>
|
||||
The most common way that the <code>git mail</code> command fails is because the
|
||||
email address used has not gone through the setup above.
|
||||
<br>
|
||||
If you see something like...
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
remote: Processing changes: refs: 1, done
|
||||
remote:
|
||||
remote: ERROR: In commit ab13517fa29487dcf8b0d48916c51639426c5ee9
|
||||
remote: ERROR: author email address XXXXXXXXXXXXXXXXXXX
|
||||
remote: ERROR: does not match your user account.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You need to either add the email address listed to the CLA or set this repo to use
|
||||
another email address already approved.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
First let's change the email address for this repo so this doesn't happen again.
|
||||
You can change your email address for this repo with the following command:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git config user.email email@address.com
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Then change the previous commit to use this alternative email address.
|
||||
You can do that with:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git commit --amend --author="Author Name <email@address.com>"
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Finally try to resend with:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git mail
|
||||
</pre>
|
||||
|
||||
<h3 id="cc">Specifying a reviewer / CCing others</h3>
|
||||
|
||||
<p>
|
||||
Unless explicitly told otherwise, such as in the discussion leading
|
||||
up to sending in the change list, it's better not to specify a reviewer.
|
||||
All changes are automatically CC'ed to the
|
||||
<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews@googlegroups.com</a>
|
||||
mailing list. If this is your first ever change, there may be a moderation
|
||||
delay before it appears on the mailing list, to prevent spam.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can specify a reviewer or CC interested parties
|
||||
using the <code>-r</code> or <code>-cc</code> options.
|
||||
Both accept a comma-separated list of email addresses:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git mail -r joe@golang.org -cc mabel@example.com,math-nuts@swtch.com
|
||||
</pre>
|
||||
|
||||
<h2 id="review">Going through the review process</h2>
|
||||
<h3 id="review">Reviewing code</h3>
|
||||
|
||||
<p>
|
||||
Running <code>git</code> <code>mail</code> will send an email to you and the
|
||||
@@ -665,15 +491,7 @@ You must reply through the web interface.
|
||||
(Unlike with the old Rietveld review system, replying by mail has no effect.)
|
||||
</p>
|
||||
|
||||
<h3 id="revise">Revise and resend</h3>
|
||||
|
||||
<p>
|
||||
The Go contribution workflow is optimized for iterative revisions based on
|
||||
feedback.
|
||||
It is rare that an initial contribution will be ready to be applied as is.
|
||||
As you revise your contribution and resend Gerrit will retain a history of
|
||||
all the changes and comments made in the single URL.
|
||||
</p>
|
||||
<h3 id="revise">Revise and upload</h3>
|
||||
|
||||
<p>
|
||||
You must respond to review comments through the web interface.
|
||||
@@ -716,8 +534,6 @@ $ git sync
|
||||
<code>git</code> <code>pull</code> <code>-r</code>.)
|
||||
</p>
|
||||
|
||||
<h3 id="resolving_conflicts">Resolving Conflicts</h3>
|
||||
|
||||
<p>
|
||||
If files you were editing have changed, Git does its best to merge the
|
||||
remote changes into your local changes.
|
||||
@@ -793,8 +609,8 @@ might turn up:
|
||||
<p>
|
||||
Git doesn't show it, but suppose the original text that both edits
|
||||
started with was 1e8; you changed it to 1e10 and the other change to 1e9,
|
||||
so the correct answer might now be 1e10.
|
||||
First, edit the section to remove the markers and leave the correct code:
|
||||
so the correct answer might now be 1e10. First, edit the section
|
||||
to remove the markers and leave the correct code:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -823,13 +639,10 @@ restore the change commit.
|
||||
<h3 id="download">Reviewing code by others</h3>
|
||||
|
||||
<p>
|
||||
As part of the review process reviewers can propose changes directly (in the
|
||||
GitHub workflow this would be someone else attaching commits to a pull request).
|
||||
|
||||
You can import these changes proposed by someone else into your local Git repository.
|
||||
You can import a change proposed by someone else into your local Git repository.
|
||||
On the Gerrit review page, click the "Download ▼" link in the upper right
|
||||
corner, copy the "Checkout" command and run it from your local Git repo. It
|
||||
should look something like this:
|
||||
corner, copy the "Checkout" command and run it from your local Git repo.
|
||||
It should look something like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -840,11 +653,11 @@ $ git fetch https://go.googlesource.com/review refs/changes/21/1221/1 &&
|
||||
To revert, change back to the branch you were working in.
|
||||
</p>
|
||||
|
||||
<h2 id="submit">Apply the change to the master branch</h2>
|
||||
<h3 id="submit">Submit the change after the review</h3>
|
||||
|
||||
<p>
|
||||
After the code has been <code>LGTM</code>'ed, an approver may
|
||||
apply it to the master branch using the Gerrit UI.
|
||||
submit it to the master branch using the Gerrit UI.
|
||||
There is a "Submit" button on the web page for the change
|
||||
that appears once the change is approved (marked +2).
|
||||
</p>
|
||||
@@ -856,13 +669,41 @@ and the code review will be updated with a link to the change
|
||||
in the repository.
|
||||
Since the method used to integrate the changes is "Cherry Pick",
|
||||
the commit hashes in the repository will be changed by
|
||||
the "Submit" operation.
|
||||
the submit operation.
|
||||
</p>
|
||||
|
||||
<h2 id="more">More information</h2>
|
||||
<h3 id="more">More information</h3>
|
||||
|
||||
<p>
|
||||
In addition to the information here, the Go community maintains a <a
|
||||
href="https://golang.org/wiki/CodeReview">CodeReview</a> wiki page.
|
||||
In addition to the information here, the Go community maintains a <a href="https://golang.org/wiki/CodeReview">CodeReview</a> wiki page.
|
||||
Feel free to contribute to this page as you learn the review process.
|
||||
</p>
|
||||
|
||||
<h2 id="copyright">Copyright</h2>
|
||||
|
||||
<p>Files in the Go repository don't list author names,
|
||||
both to avoid clutter and to avoid having to keep the lists up to date.
|
||||
Instead, your name will appear in the
|
||||
<a href="https://golang.org/change">change log</a>
|
||||
and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file
|
||||
and perhaps the <a href="/AUTHORS"><code>AUTHORS</code></a> file.
|
||||
</p>
|
||||
|
||||
<p>The <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file
|
||||
defines who the Go contributors—the people—are;
|
||||
the <a href="/AUTHORS"><code>AUTHORS</code></a> file defines
|
||||
who “The Go Authors”—the copyright holders—are.
|
||||
These files will be periodically updated based on the commit logs.
|
||||
|
||||
<p>Code that you contribute should use the standard copyright header:</p>
|
||||
|
||||
<pre>
|
||||
// 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.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Files in the repository are copyright the year they are added. It is not
|
||||
necessary to update the copyright year on files that you change.
|
||||
</p>
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
}-->
|
||||
|
||||
<p><i>
|
||||
This applies to the standard toolchain (the <code>gc</code> Go
|
||||
compiler and tools). Gccgo has native gdb support.
|
||||
This applies to the <code>gc</code> toolchain. Gccgo has native gdb support.
|
||||
Besides this overview you might want to consult the
|
||||
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
|
||||
</i></p>
|
||||
@@ -50,14 +49,6 @@ when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
|
||||
debugged.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you want to use gdb to inspect a core dump, you can trigger a dump
|
||||
on a program crash, on systems that permit it, by setting
|
||||
<code>GOTRACEBACK=crash</code> in the environment (see the
|
||||
<a href="/pkg/runtime/#hdr-Environment_Variables"> runtime package
|
||||
documentation</a> for more info).
|
||||
</p>
|
||||
|
||||
<h3 id="Common_Operations">Common Operations</h3>
|
||||
|
||||
<ul>
|
||||
@@ -139,7 +130,7 @@ the DWARF code.
|
||||
|
||||
<p>
|
||||
If you're interested in what the debugging information looks like, run
|
||||
'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
|
||||
'<code>objdump -W 6.out</code>' and browse through the <code>.debug_*</code>
|
||||
sections.
|
||||
</p>
|
||||
|
||||
@@ -386,9 +377,7 @@ $3 = struct hchan<*testing.T>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
That <code>struct hchan<*testing.T></code> is the
|
||||
runtime-internal representation of a channel. It is currently empty,
|
||||
or gdb would have pretty-printed its contents.
|
||||
That <code>struct hchan<*testing.T></code> is the runtime-internal representation of a channel. It is currently empty, or gdb would have pretty-printed it's contents.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -30,32 +30,6 @@ to fix critical security problems in both Go 1.4 and Go 1.5 as they arise.
|
||||
See the <a href="/security">security policy</a> for more details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
|
||||
|
||||
<p>
|
||||
Go 1.8 is a major release of Go.
|
||||
Read the <a href="/doc/go1.8">Go 1.8 Release Notes</a> for more information.
|
||||
</p>
|
||||
|
||||
<h3 id="go1.8.minor">Minor revisions</h3>
|
||||
|
||||
<p>
|
||||
go1.8.1 (released 2017/04/07) includes fixes to the compiler, linker, runtime,
|
||||
documentation, <code>go</code> command and the <code>crypto/tls</code>,
|
||||
<code>encoding/xml</code>, <code>image/png</code>, <code>net</code>,
|
||||
<code>net/http</code>, <code>reflect</code>, <code>text/template</code>,
|
||||
and <code>time</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.1">Go
|
||||
1.8.1 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.8.2 (released 2017/05/23) includes a security fix to the
|
||||
<code>crypto/elliptic</code> package.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.2">Go
|
||||
1.8.2 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
|
||||
|
||||
<p>
|
||||
@@ -95,20 +69,6 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.4">Go
|
||||
1.7.4 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.7.5 (released 2017/01/26) includes fixes to the compiler, runtime,
|
||||
and the <code>crypto/x509</code> and <code>time</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.5">Go
|
||||
1.7.5 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
go1.7.6 (released 2017/05/23) includes the same security fix as Go 1.8.2 and
|
||||
was released at the same time.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.2">Go
|
||||
1.8.2 milestone</a> on our issue tracker for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.6">go1.6 (released 2016/02/17)</h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -52,19 +52,6 @@ user libraries. The Go 1.4 runtime is not fully merged, but that
|
||||
should not be visible to Go programs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The GCC 6 releases include a complete implementation of the Go 1.6.1
|
||||
user libraries. The Go 1.6 runtime is not fully merged, but that
|
||||
should not be visible to Go programs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The GCC 7 releases are expected to include a complete implementation
|
||||
of the Go 1.8 user libraries. As with earlier releases, the Go 1.8
|
||||
runtime is not fully merged, but that should not be visible to Go
|
||||
programs.
|
||||
</p>
|
||||
|
||||
<h2 id="Source_code">Source code</h2>
|
||||
|
||||
<p>
|
||||
@@ -173,6 +160,23 @@ make
|
||||
make install
|
||||
</pre>
|
||||
|
||||
<h3 id="Ubuntu">A note on Ubuntu</h3>
|
||||
|
||||
<p>
|
||||
Current versions of Ubuntu and versions of GCC before 4.8 disagree on
|
||||
where system libraries and header files are found. This is not a
|
||||
gccgo issue. When building older versions of GCC, setting these
|
||||
environment variables while configuring and building gccgo may fix the
|
||||
problem.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
|
||||
C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu
|
||||
CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu
|
||||
export LIBRARY_PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH
|
||||
</pre>
|
||||
|
||||
<h2 id="Using_gccgo">Using gccgo</h2>
|
||||
|
||||
<p>
|
||||
@@ -360,15 +364,12 @@ or with C++ code compiled using <code>extern "C"</code>.
|
||||
<h3 id="Types">Types</h3>
|
||||
|
||||
<p>
|
||||
Basic types map directly: an <code>int32</code> in Go is
|
||||
an <code>int32_t</code> in C, an <code>int64</code> is
|
||||
an <code>int64_t</code>, etc.
|
||||
The Go type <code>int</code> is an integer that is the same size as a
|
||||
pointer, and as such corresponds to the C type <code>intptr_t</code>.
|
||||
Go <code>byte</code> is equivalent to C <code>unsigned char</code>.
|
||||
Pointers in Go are pointers in C.
|
||||
A Go <code>struct</code> is the same as C <code>struct</code> with the
|
||||
same fields and types.
|
||||
Basic types map directly: an <code>int</code> in Go is an <code>int</code>
|
||||
in C, an <code>int32</code> is an <code>int32_t</code>,
|
||||
etc. Go <code>byte</code> is equivalent to C <code>unsigned
|
||||
char</code>.
|
||||
Pointers in Go are pointers in C. A Go <code>struct</code> is the same as C
|
||||
<code>struct</code> with the same fields and types.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -379,7 +380,7 @@ structure (this is <b style="color: red;">subject to change</b>):
|
||||
<pre>
|
||||
struct __go_string {
|
||||
const unsigned char *__data;
|
||||
intptr_t __length;
|
||||
int __length;
|
||||
};
|
||||
</pre>
|
||||
|
||||
@@ -399,8 +400,8 @@ A slice in Go is a structure. The current definition is
|
||||
<pre>
|
||||
struct __go_slice {
|
||||
void *__values;
|
||||
intptr_t __count;
|
||||
intptr_t __capacity;
|
||||
int __count;
|
||||
int __capacity;
|
||||
};
|
||||
</pre>
|
||||
|
||||
@@ -525,3 +526,15 @@ This procedure is full of unstated caveats and restrictions and we make no
|
||||
guarantee that it will not change in the future. It is more useful as a
|
||||
starting point for real Go code than as a regular procedure.
|
||||
</p>
|
||||
|
||||
<h2 id="RTEMS_Port">RTEMS Port</h2>
|
||||
<p>
|
||||
The gccgo compiler has been ported to <a href="http://www.rtems.com/">
|
||||
<code>RTEMS</code></a>. <code>RTEMS</code> is a real-time executive
|
||||
that provides a high performance environment for embedded applications
|
||||
on a range of processors and embedded hardware. The current gccgo
|
||||
port is for x86. The goal is to extend the port to most of the
|
||||
<a href="http://www.rtems.org/wiki/index.php/SupportedCPUs">
|
||||
architectures supported by <code>RTEMS</code></a>. For more information on the port,
|
||||
as well as instructions on how to install it, please see this
|
||||
<a href="http://www.rtems.org/wiki/index.php/GCCGoRTEMS"><code>RTEMS</code> Wiki page</a>.
|
||||
|
||||
@@ -15,7 +15,12 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
ul li { margin: 0.5em 0; }
|
||||
</style>
|
||||
|
||||
<h2 id="introduction">Introduction to Go 1.8</h2>
|
||||
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.8</h2>
|
||||
|
||||
<p><strong>
|
||||
Go 1.8 is not yet released. These are work-in-progress
|
||||
release notes. Go 1.8 is expected to be released in February 2017.
|
||||
</strong></p>
|
||||
|
||||
<p>
|
||||
The latest Go release, version 1.8, arrives six months after <a href="go1.7">Go 1.7</a>.
|
||||
@@ -88,8 +93,7 @@ On OpenBSD, Go now requires OpenBSD 5.9 or later. <!-- CL 34093 -->
|
||||
<p>
|
||||
The Plan 9 port's networking support is now much more complete
|
||||
and matches the behavior of Unix and Windows with respect to deadlines
|
||||
and cancelation. For Plan 9 kernel requirements, see the
|
||||
<a href="https://golang.org/wiki/Plan9">Plan 9 wiki page</a>.
|
||||
and cancelation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -430,11 +434,11 @@ version of gccgo.
|
||||
<h3 id="plugin">Plugins</h3>
|
||||
|
||||
<p>
|
||||
Go now provides early support for plugins with a “<code>plugin</code>”
|
||||
build mode for generating plugins written in Go, and a
|
||||
Go now supports a “<code>plugin</code>” build mode for generating
|
||||
plugins written in Go, and a
|
||||
new <a href="/pkg/plugin/"><code>plugin</code></a> package for
|
||||
loading such plugins at run time. Plugin support is currently only
|
||||
available on Linux. Please report any issues.
|
||||
loading such plugins at run time. Plugin support is only currently
|
||||
available on Linux.
|
||||
</p>
|
||||
|
||||
<h2 id="runtime">Runtime</h2>
|
||||
@@ -794,9 +798,9 @@ Optimizations and minor bug fixes are not listed.
|
||||
hardware support for AES-GCM is present.
|
||||
</p>
|
||||
|
||||
<p> <!-- CL 27315, CL 35290 -->
|
||||
<p> <!-- CL 27315 -->
|
||||
AES-128-CBC cipher suites with SHA-256 are also
|
||||
now supported, but disabled by default.
|
||||
now supported.
|
||||
</p>
|
||||
|
||||
</dd>
|
||||
@@ -804,6 +808,11 @@ Optimizations and minor bug fixes are not listed.
|
||||
|
||||
<dl id="crypto_x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
|
||||
<dd>
|
||||
<p> <!-- CL 30578 -->
|
||||
<a href="/pkg/crypto/x509/#SystemCertPool"><code>SystemCertPool</code></a>
|
||||
is now implemented on Windows.
|
||||
</p>
|
||||
|
||||
<p> <!-- CL 24743 -->
|
||||
PSS signatures are now supported.
|
||||
</p>
|
||||
@@ -854,12 +863,11 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
|
||||
<p>
|
||||
The <a href="/pkg/database/sql#IsolationLevel"><code>IsolationLevel</code></a>
|
||||
can now be set when starting a transaction by setting the isolation level
|
||||
on <a href="/pkg/database/sql#TxOptions.Isolation"><code>TxOptions.Isolation</code></a> and passing
|
||||
it to <a href="/pkg/database/sql#DB.BeginTx"><code>DB.BeginTx</code></a>.
|
||||
on the <code>Context</code> then passing that <code>Context</code> to
|
||||
<a href="/pkg/database/sql#DB.BeginContext"><code>DB.BeginContext</code></a>.
|
||||
An error will be returned if an isolation level is selected that the driver
|
||||
does not support. A read-only attribute may also be set on the transaction
|
||||
by setting <a href="/pkg/database/sql/#TxOptions.ReadOnly"><code>TxOptions.ReadOnly</code></a>
|
||||
to true.
|
||||
with <a href="/pkg/database/sql/#ReadOnlyContext"><code>ReadOnlyContext</code></a>.
|
||||
</p>
|
||||
<p>
|
||||
Queries now expose the SQL column type information for drivers that support it.
|
||||
@@ -1304,7 +1312,7 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
|
||||
request must have the new
|
||||
<a href="/pkg/net/http/#Request"><code>Request.GetBody</code></a>
|
||||
field defined.
|
||||
<a href="/pkg/net/http/#NewRequest"><code>NewRequest</code></a>
|
||||
<a href="pkg/net/http/#NewRequest"><code>NewRequest</code></a>
|
||||
sets <code>Request.GetBody</code> automatically for common
|
||||
body types.
|
||||
</li>
|
||||
@@ -1609,9 +1617,9 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
|
||||
June 31 and July 32.
|
||||
</p>
|
||||
|
||||
<p> <!-- CL 33029 --> <!-- CL 34816 -->
|
||||
<p> <!-- CL 33029 -->
|
||||
The <code>tzdata</code> database has been updated to version
|
||||
2016j for systems that don't already have a local time zone
|
||||
2016i for systems that don't already have a local time zone
|
||||
database.
|
||||
</p>
|
||||
|
||||
@@ -1641,17 +1649,6 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
|
||||
and only the overall execution of the test binary would fail.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 32455 -->
|
||||
The signature of the
|
||||
<a href="/pkg/testing/#MainStart"><code>MainStart</code></a>
|
||||
function has changed, as allowed by the documentation. It is an
|
||||
internal detail and not part of the Go 1 compatibility promise.
|
||||
If you're not calling <code>MainStart</code> directly but see
|
||||
errors, that likely means you set the
|
||||
normally-empty <code>GOROOT</code> environment variable and it
|
||||
doesn't match the version of your <code>go</code> command's binary.
|
||||
</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
@@ -147,9 +147,6 @@ either the git branch <code>release-branch.go1.4</code> or
|
||||
which contains the Go 1.4 source code plus accumulated fixes
|
||||
to keep the tools running on newer operating systems.
|
||||
(Go 1.4 was the last distribution in which the tool chain was written in C.)
|
||||
After unpacking the Go 1.4 source, <code>cd</code> to
|
||||
the <code>src</code> subdirectory and run <code>make.bash</code> (or,
|
||||
on Windows, <code>make.bat</code>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -221,7 +218,7 @@ To build without <code>cgo</code>, set the environment variable
|
||||
Change to the directory that will be its parent
|
||||
and make sure the <code>go</code> directory does not exist.
|
||||
Then clone the repository and check out the latest release tag
|
||||
(<code class="versionTag">go1.8.1</code>, for example):</p>
|
||||
(<code class="versionTag">go1.7.4</code>, for example):</p>
|
||||
|
||||
<pre>
|
||||
$ git clone https://go.googlesource.com/go
|
||||
@@ -409,7 +406,7 @@ New releases are announced on the
|
||||
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
|
||||
mailing list.
|
||||
Each announcement mentions the latest release tag, for instance,
|
||||
<code class="versionTag">go1.8.1</code>.
|
||||
<code class="versionTag">go1.7.4</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -250,7 +250,7 @@ $ <b>cd $HOME/go/src/hello</b>
|
||||
$ <b>go build</b>
|
||||
</pre>
|
||||
|
||||
<pre class="testWindows">
|
||||
<pre class="testWindows" style="display: none">
|
||||
C:\> <b>cd %USERPROFILE%\go\src\hello</b>
|
||||
C:\Users\Gopher\go\src\hello> <b>go build</b>
|
||||
</pre>
|
||||
@@ -267,7 +267,7 @@ $ <b>./hello</b>
|
||||
hello, world
|
||||
</pre>
|
||||
|
||||
<pre class="testWindows">
|
||||
<pre class="testWindows" style="display: none">
|
||||
C:\Users\Gopher\go\src\hello> <b>hello</b>
|
||||
hello, world
|
||||
</pre>
|
||||
|
||||
@@ -73,7 +73,7 @@ func test18146(t *testing.T) {
|
||||
}
|
||||
runtime.GOMAXPROCS(threads)
|
||||
argv := append(os.Args, "-test.run=NoSuchTestExists")
|
||||
if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
|
||||
if err := syscall.Exec(os.Args[0], argv, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package cgotest
|
||||
static stack_t oss;
|
||||
static char signalStack[SIGSTKSZ];
|
||||
|
||||
static void changeSignalStack(void) {
|
||||
static void changeSignalStack() {
|
||||
stack_t ss;
|
||||
memset(&ss, 0, sizeof ss);
|
||||
ss.ss_sp = signalStack;
|
||||
@@ -29,7 +29,7 @@ static void changeSignalStack(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void restoreSignalStack(void) {
|
||||
static void restoreSignalStack() {
|
||||
#if (defined(__x86_64__) || defined(__i386__)) && defined(__APPLE__)
|
||||
// The Darwin C library enforces a minimum that the kernel does not.
|
||||
// This is OK since we allocated this much space in mpreinit,
|
||||
@@ -42,7 +42,7 @@ static void restoreSignalStack(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static int zero(void) {
|
||||
static int zero() {
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -179,13 +179,6 @@ if test "$output" != "PASS"; then
|
||||
status=1
|
||||
fi
|
||||
|
||||
if test "$libext" = "dylib"; then
|
||||
# make sure dylibs are well-formed
|
||||
if ! otool -l libgo*.dylib >/dev/null; then
|
||||
status=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $status = 0; then
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright 2017 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 (
|
||||
"iface_i"
|
||||
"log"
|
||||
"plugin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
a, err := plugin.Open("iface_a.so")
|
||||
if err != nil {
|
||||
log.Fatalf(`plugin.Open("iface_a.so"): %v`, err)
|
||||
}
|
||||
b, err := plugin.Open("iface_b.so")
|
||||
if err != nil {
|
||||
log.Fatalf(`plugin.Open("iface_b.so"): %v`, err)
|
||||
}
|
||||
|
||||
af, err := a.Lookup("F")
|
||||
if err != nil {
|
||||
log.Fatalf(`a.Lookup("F") failed: %v`, err)
|
||||
}
|
||||
bf, err := b.Lookup("F")
|
||||
if err != nil {
|
||||
log.Fatalf(`b.Lookup("F") failed: %v`, err)
|
||||
}
|
||||
if af.(func() interface{})() != bf.(func() interface{})() {
|
||||
panic("empty interfaces not equal")
|
||||
}
|
||||
|
||||
ag, err := a.Lookup("G")
|
||||
if err != nil {
|
||||
log.Fatalf(`a.Lookup("G") failed: %v`, err)
|
||||
}
|
||||
bg, err := b.Lookup("G")
|
||||
if err != nil {
|
||||
log.Fatalf(`b.Lookup("G") failed: %v`, err)
|
||||
}
|
||||
if ag.(func() iface_i.I)() != bg.(func() iface_i.I)() {
|
||||
panic("nonempty interfaces not equal")
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 "iface_i"
|
||||
|
||||
//go:noinline
|
||||
func F() interface{} {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func G() iface_i.I {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 "iface_i"
|
||||
|
||||
//go:noinline
|
||||
func F() interface{} {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func G() iface_i.I {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 iface_i
|
||||
|
||||
type I interface {
|
||||
M()
|
||||
}
|
||||
|
||||
type T struct {
|
||||
}
|
||||
|
||||
func (t *T) M() {
|
||||
}
|
||||
|
||||
// *T implements I
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright 2017 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 dynamodbstreamsevt
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
var foo json.RawMessage
|
||||
|
||||
type Event struct{}
|
||||
|
||||
func (e *Event) Dummy() {}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// The bug happened like this:
|
||||
// 1) The main binary adds an itab for *json.UnsupportedValueError / error
|
||||
// (concrete type / interface type). This itab goes in hash bucket 0x111.
|
||||
// 2) The plugin adds that same itab again. That makes a cycle in the itab
|
||||
// chain rooted at hash bucket 0x111.
|
||||
// 3) The main binary then asks for the itab for *dynamodbstreamsevt.Event /
|
||||
// json.Unmarshaler. This itab happens to also live in bucket 0x111.
|
||||
// The lookup code goes into an infinite loop searching for this itab.
|
||||
// The code is carefully crafted so that the two itabs are both from the
|
||||
// same bucket, and so that the second itab doesn't exist in
|
||||
// the itab hashmap yet (so the entire linked list must be searched).
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"issue18676/dynamodbstreamsevt"
|
||||
"plugin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
plugin.Open("plugin.so")
|
||||
|
||||
var x interface{} = (*dynamodbstreamsevt.Event)(nil)
|
||||
if _, ok := x.(json.Unmarshaler); !ok {
|
||||
println("something")
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017 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 "C"
|
||||
|
||||
import "issue18676/dynamodbstreamsevt"
|
||||
|
||||
func F(evt *dynamodbstreamsevt.Event) {}
|
||||
@@ -15,8 +15,8 @@ goos=$(go env GOOS)
|
||||
goarch=$(go env GOARCH)
|
||||
|
||||
function cleanup() {
|
||||
rm -f plugin*.so unnamed*.so iface*.so
|
||||
rm -rf host pkg sub iface issue18676
|
||||
rm -f plugin*.so unnamed*.so
|
||||
rm -rf host pkg sub
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
@@ -32,15 +32,3 @@ GOPATH=$(pwd) go build -buildmode=plugin unnamed2.go
|
||||
GOPATH=$(pwd) go build host
|
||||
|
||||
LD_LIBRARY_PATH=$(pwd) ./host
|
||||
|
||||
# Test that types and itabs get properly uniqified.
|
||||
GOPATH=$(pwd) go build -buildmode=plugin iface_a
|
||||
GOPATH=$(pwd) go build -buildmode=plugin iface_b
|
||||
GOPATH=$(pwd) go build iface
|
||||
LD_LIBRARY_PATH=$(pwd) ./iface
|
||||
|
||||
# Test for issue 18676 - make sure we don't add the same itab twice.
|
||||
# The buggy code hangs forever, so use a timeout to check for that.
|
||||
GOPATH=$(pwd) go build -buildmode=plugin -o plugin.so src/issue18676/plugin.go
|
||||
GOPATH=$(pwd) go build -o issue18676 src/issue18676/main.go
|
||||
timeout 10s ./issue18676
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright 2017 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 program segfaulted during libpreinit when built with -msan:
|
||||
// http://golang.org/issue/18707
|
||||
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
func main() {}
|
||||
@@ -68,25 +68,6 @@ fi
|
||||
|
||||
status=0
|
||||
|
||||
testmsanshared() {
|
||||
goos=$(go env GOOS)
|
||||
suffix="-installsuffix testsanitizers"
|
||||
libext="so"
|
||||
if [ "$goos" == "darwin" ]; then
|
||||
libext="dylib"
|
||||
fi
|
||||
go build -msan -buildmode=c-shared $suffix -o ${TMPDIR}/libmsanshared.$libext msan_shared.go
|
||||
|
||||
echo 'int main() { return 0; }' > ${TMPDIR}/testmsanshared.c
|
||||
$CC $(go env GOGCCFLAGS) -fsanitize=memory -o ${TMPDIR}/testmsanshared ${TMPDIR}/testmsanshared.c ${TMPDIR}/libmsanshared.$libext
|
||||
|
||||
if ! LD_LIBRARY_PATH=. ${TMPDIR}/testmsanshared; then
|
||||
echo "FAIL: msan_shared"
|
||||
status=1
|
||||
fi
|
||||
rm -f ${TMPDIR}/{testmsanshared,testmsanshared.c,libmsanshared.$libext}
|
||||
}
|
||||
|
||||
if test "$msan" = "yes"; then
|
||||
if ! go build -msan std; then
|
||||
echo "FAIL: build -msan std"
|
||||
@@ -127,8 +108,6 @@ if test "$msan" = "yes"; then
|
||||
echo "FAIL: msan_fail"
|
||||
status=1
|
||||
fi
|
||||
|
||||
testmsanshared
|
||||
fi
|
||||
|
||||
if test "$tsan" = "yes"; then
|
||||
|
||||
@@ -815,14 +815,3 @@ func TestImplicitInclusion(t *testing.T) {
|
||||
goCmd(t, "install", "-linkshared", "implicitcmd")
|
||||
run(t, "running executable linked against library that contains same package as it", "./bin/implicitcmd")
|
||||
}
|
||||
|
||||
// Tests to make sure that the type fields of empty interfaces and itab
|
||||
// fields of nonempty interfaces are unique even across modules,
|
||||
// so that interface equality works correctly.
|
||||
func TestInterface(t *testing.T) {
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_a")
|
||||
// Note: iface_i gets installed implicitly as a dependency of iface_a.
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_b")
|
||||
goCmd(t, "install", "-linkshared", "iface")
|
||||
run(t, "running type/itab uniqueness tester", "./bin/iface")
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var SlicePtr interface{} = &[]int{}
|
||||
|
||||
var V int = 1
|
||||
|
||||
var HasMask []string = []string{"hi"}
|
||||
|
||||
@@ -19,8 +19,6 @@ func F() *C {
|
||||
return nil
|
||||
}
|
||||
|
||||
var slicePtr interface{} = &[]int{}
|
||||
|
||||
func main() {
|
||||
defer depBase.ImplementedInAsm()
|
||||
// This code below causes various go.itab.* symbols to be generated in
|
||||
@@ -34,11 +32,4 @@ func main() {
|
||||
if reflect.TypeOf(F).Out(0) != reflect.TypeOf(c) {
|
||||
panic("bad reflection results, see golang.org/issue/18252")
|
||||
}
|
||||
|
||||
sp := reflect.New(reflect.TypeOf(slicePtr).Elem())
|
||||
s := sp.Interface()
|
||||
|
||||
if reflect.TypeOf(s) != reflect.TypeOf(slicePtr) {
|
||||
panic("bad reflection results, see golang.org/issue/18729")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 "iface_a"
|
||||
import "iface_b"
|
||||
|
||||
func main() {
|
||||
if iface_a.F() != iface_b.F() {
|
||||
panic("empty interfaces not equal")
|
||||
}
|
||||
if iface_a.G() != iface_b.G() {
|
||||
panic("non-empty interfaces not equal")
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 iface_a
|
||||
|
||||
import "iface_i"
|
||||
|
||||
//go:noinline
|
||||
func F() interface{} {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func G() iface_i.I {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 iface_b
|
||||
|
||||
import "iface_i"
|
||||
|
||||
//go:noinline
|
||||
func F() interface{} {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func G() iface_i.I {
|
||||
return (*iface_i.T)(nil)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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 iface_i
|
||||
|
||||
type I interface {
|
||||
M()
|
||||
}
|
||||
|
||||
type T struct {
|
||||
}
|
||||
|
||||
func (t *T) M() {
|
||||
}
|
||||
|
||||
// *T implements I
|
||||
@@ -99,7 +99,7 @@ func main() {
|
||||
// Approximately 1 in a 100 binaries fail to start. If it happens,
|
||||
// try again. These failures happen for several reasons beyond
|
||||
// our control, but all of them are safe to retry as they happen
|
||||
// before lldb encounters the initial SIGUSR2 stop. As we
|
||||
// before lldb encounters the initial getwd breakpoint. As we
|
||||
// know the tests haven't started, we are not hiding flaky tests
|
||||
// with this retry.
|
||||
for i := 0; i < 5; i++ {
|
||||
@@ -204,11 +204,6 @@ func run(bin string, args []string) (err error) {
|
||||
var opts options
|
||||
opts, args = parseArgs(args)
|
||||
|
||||
// Pass the suffix for the current working directory as the
|
||||
// first argument to the test. For iOS, cmd/go generates
|
||||
// special handling of this argument.
|
||||
args = append([]string{"cwdSuffix=" + pkgpath}, args...)
|
||||
|
||||
// ios-deploy invokes lldb to give us a shell session with the app.
|
||||
s, err := newSession(appdir, args, opts)
|
||||
if err != nil {
|
||||
@@ -229,7 +224,6 @@ func run(bin string, args []string) (err error) {
|
||||
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
|
||||
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
|
||||
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
|
||||
s.do(`process handle SIGUSR2 --stop true --pass false --notify true`) // sent by test harness
|
||||
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
|
||||
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
|
||||
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
|
||||
@@ -242,9 +236,20 @@ func run(bin string, args []string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
s.do(`breakpoint set -n getwd`) // in runtime/cgo/gcc_darwin_arm.go
|
||||
|
||||
started = true
|
||||
|
||||
s.doCmd("run", "stop reason = signal SIGUSR2", 20*time.Second)
|
||||
s.doCmd("run", "stop reason = breakpoint", 20*time.Second)
|
||||
|
||||
// Move the current working directory into the faux gopath.
|
||||
if pkgpath != "src" {
|
||||
s.do(`breakpoint delete 1`)
|
||||
s.do(`expr char* $mem = (char*)malloc(512)`)
|
||||
s.do(`expr $mem = (char*)getwd($mem, 512)`)
|
||||
s.do(`expr $mem = (char*)strcat($mem, "/` + pkgpath + `")`)
|
||||
s.do(`call (void)chdir($mem)`)
|
||||
}
|
||||
|
||||
startTestsLen := s.out.Len()
|
||||
fmt.Fprintln(s.in, `process continue`)
|
||||
@@ -515,11 +520,13 @@ func copyLocalData(dstbase string) (pkgpath string, err error) {
|
||||
|
||||
// Copy timezone file.
|
||||
//
|
||||
// Apps have the zoneinfo.zip in the root of their app bundle,
|
||||
// Typical apps have the zoneinfo.zip in the root of their app bundle,
|
||||
// read by the time package as the working directory at initialization.
|
||||
// As we move the working directory to the GOROOT pkg directory, we
|
||||
// install the zoneinfo.zip file in the pkgpath.
|
||||
if underGoRoot {
|
||||
err := cp(
|
||||
dstbase,
|
||||
filepath.Join(dstbase, pkgpath),
|
||||
filepath.Join(cwd, "lib", "time", "zoneinfo.zip"),
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -303,9 +303,7 @@ func genhash(sym *Sym, t *Type) {
|
||||
typecheckslice(fn.Nbody.Slice(), Etop)
|
||||
Curfn = nil
|
||||
popdcl()
|
||||
if debug_dclstack != 0 {
|
||||
testdclstack()
|
||||
}
|
||||
testdclstack()
|
||||
|
||||
// Disable safemode while compiling this code: the code we
|
||||
// generate internally can refer to unsafe.Pointer.
|
||||
@@ -495,9 +493,7 @@ func geneq(sym *Sym, t *Type) {
|
||||
typecheckslice(fn.Nbody.Slice(), Etop)
|
||||
Curfn = nil
|
||||
popdcl()
|
||||
if debug_dclstack != 0 {
|
||||
testdclstack()
|
||||
}
|
||||
testdclstack()
|
||||
|
||||
// Disable safemode while compiling this code: the code we
|
||||
// generate internally can refer to unsafe.Pointer.
|
||||
|
||||
@@ -217,9 +217,7 @@ func Import(in *bufio.Reader) {
|
||||
typecheckok = tcok
|
||||
resumecheckwidth()
|
||||
|
||||
if debug_dclstack != 0 {
|
||||
testdclstack()
|
||||
}
|
||||
testdclstack() // debugging only
|
||||
}
|
||||
|
||||
func formatErrorf(format string, args ...interface{}) {
|
||||
|
||||
@@ -477,10 +477,6 @@ func escAnalyze(all []*Node, recursive bool) {
|
||||
for _, n := range all {
|
||||
if n.Op == ODCLFUNC {
|
||||
n.Esc = EscFuncPlanned
|
||||
if Debug['m'] > 3 {
|
||||
Dump("escAnalyze", n)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1679,10 +1675,7 @@ func (e *EscState) escflows(dst, src *Node, why *EscStep) {
|
||||
}
|
||||
|
||||
// Don't bother building a graph for scalars.
|
||||
if src.Type != nil && !haspointers(src.Type) && !isReflectHeaderDataField(src) {
|
||||
if Debug['m'] > 3 {
|
||||
fmt.Printf("%v::NOT flows:: %S <- %S\n", linestr(lineno), dst, src)
|
||||
}
|
||||
if src.Type != nil && !haspointers(src.Type) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,11 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
Debug_append int
|
||||
Debug_closure int
|
||||
debug_dclstack int
|
||||
Debug_panic int
|
||||
Debug_slice int
|
||||
Debug_wb int
|
||||
Debug_append int
|
||||
Debug_closure int
|
||||
Debug_panic int
|
||||
Debug_slice int
|
||||
Debug_wb int
|
||||
)
|
||||
|
||||
// Debug arguments.
|
||||
@@ -49,7 +48,6 @@ var debugtab = []struct {
|
||||
{"append", &Debug_append}, // print information about append compilation
|
||||
{"closure", &Debug_closure}, // print information about closure compilation
|
||||
{"disablenil", &disable_checknil}, // disable nil checks
|
||||
{"dclstack", &debug_dclstack}, // run internal dclstack checks
|
||||
{"gcprog", &Debug_gcprog}, // print dump of GC programs
|
||||
{"nil", &Debug_checknil}, // print information about nil checks
|
||||
{"panic", &Debug_panic}, // do not hide any compiler panic
|
||||
@@ -327,6 +325,7 @@ func Main() {
|
||||
timings.Stop()
|
||||
timings.AddEvent(int64(lexlineno-lexlineno0), "lines")
|
||||
|
||||
testdclstack()
|
||||
mkpackage(localpkg.Name) // final import not used checks
|
||||
finishUniverse()
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ func parseFile(filename string) {
|
||||
}
|
||||
|
||||
if nsyntaxerrors == 0 {
|
||||
// Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
|
||||
testdclstack()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ func isliteral(n *Node) bool {
|
||||
}
|
||||
|
||||
func (n *Node) isSimpleName() bool {
|
||||
return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP && n.Class != PEXTERN
|
||||
return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP
|
||||
}
|
||||
|
||||
func litas(l *Node, r *Node, init *Nodes) {
|
||||
|
||||
@@ -3470,13 +3470,8 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line int32, skip
|
||||
if s.WBLineno == 0 {
|
||||
s.WBLineno = left.Line
|
||||
}
|
||||
if t == Types[TUINTPTR] {
|
||||
// Stores to reflect.{Slice,String}Header.Data.
|
||||
s.vars[&memVar] = s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
|
||||
} else {
|
||||
s.storeTypeScalars(t, left, right, skip)
|
||||
s.storeTypePtrsWB(t, left, right)
|
||||
}
|
||||
s.storeTypeScalars(t, left, right, skip)
|
||||
s.storeTypePtrsWB(t, left, right)
|
||||
|
||||
// WB ops will be expanded to branches at writebarrier phase.
|
||||
// To make it easy, we put WB ops at the end of a block, so
|
||||
|
||||
@@ -1833,9 +1833,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
|
||||
funcbody(fn)
|
||||
Curfn = fn
|
||||
popdcl()
|
||||
if debug_dclstack != 0 {
|
||||
testdclstack()
|
||||
}
|
||||
testdclstack()
|
||||
|
||||
// wrappers where T is anonymous (struct or interface) can be duplicated.
|
||||
if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
|
||||
|
||||
11
src/cmd/compile/internal/gc/testdata/arith.go
vendored
11
src/cmd/compile/internal/gc/testdata/arith.go
vendored
@@ -488,17 +488,6 @@ func testLrot() {
|
||||
wantA, wantB, wantC, wantD, ", got", a, b, c, d)
|
||||
failed = true
|
||||
}
|
||||
// Also test inputs with the top bit set, and make sure
|
||||
// sub-word right shift has high bits cleared first.
|
||||
// See issue #19270.
|
||||
wantA, wantB, wantC, wantD = uint8(0xdf), uint16(0xdfff),
|
||||
uint32(0xdfffffff), uint64(0xdfffffffffffffff)
|
||||
a, b, c, d = lrot1_ssa(0xfe, 0xfffe, 0xfffffffe, 0xfffffffffffffffe)
|
||||
if a != wantA || b != wantB || c != wantC || d != wantD {
|
||||
println("lrot1_ssa(0xfe, 0xfffe, 0xfffffffe, 0xfffffffffffffffe)=",
|
||||
wantA, wantB, wantC, wantD, ", got", a, b, c, d)
|
||||
failed = true
|
||||
}
|
||||
x := lrot2_ssa(0xb0000001, 32)
|
||||
wantX := uint32(0xb0000001)
|
||||
if x != wantX {
|
||||
|
||||
@@ -1107,7 +1107,7 @@ OpSwitch:
|
||||
|
||||
case OSLICE, OSLICE3:
|
||||
ok |= Erv
|
||||
n.Left = typecheck(n.Left, Erv)
|
||||
n.Left = typecheck(n.Left, top)
|
||||
low, high, max := n.SliceBounds()
|
||||
hasmax := n.Op.IsSlice3()
|
||||
low = typecheck(low, Erv)
|
||||
@@ -1119,10 +1119,6 @@ OpSwitch:
|
||||
max = indexlit(max)
|
||||
n.SetSliceBounds(low, high, max)
|
||||
l := n.Left
|
||||
if l.Type == nil {
|
||||
n.Type = nil
|
||||
return n
|
||||
}
|
||||
if l.Type.IsArray() {
|
||||
if !islvalue(n.Left) {
|
||||
yyerror("invalid operation %v (slice of unaddressable value)", n)
|
||||
@@ -1135,7 +1131,12 @@ OpSwitch:
|
||||
n.Left = typecheck(n.Left, Erv)
|
||||
l = n.Left
|
||||
}
|
||||
|
||||
t := l.Type
|
||||
if t == nil {
|
||||
n.Type = nil
|
||||
return n
|
||||
}
|
||||
var tp *Type
|
||||
if t.IsString() {
|
||||
if hasmax {
|
||||
|
||||
@@ -57,13 +57,8 @@ func startProfile() {
|
||||
Fatalf("%v", err)
|
||||
}
|
||||
atExit(func() {
|
||||
// Profile all outstanding allocations.
|
||||
runtime.GC()
|
||||
// compilebench parses the memory profile to extract memstats,
|
||||
// which are only written in the legacy pprof format.
|
||||
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
|
||||
const writeLegacyFormat = 1
|
||||
if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
|
||||
runtime.GC() // profile all outstanding allocations
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
Fatalf("%v", err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2071,29 +2071,6 @@ func isstack(n *Node) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isReflectHeaderDataField reports whether l is an expression p.Data
|
||||
// where p has type reflect.SliceHeader or reflect.StringHeader.
|
||||
func isReflectHeaderDataField(l *Node) bool {
|
||||
if l.Type != Types[TUINTPTR] {
|
||||
return false
|
||||
}
|
||||
|
||||
var tsym *Sym
|
||||
switch l.Op {
|
||||
case ODOT:
|
||||
tsym = l.Left.Type.Sym
|
||||
case ODOTPTR:
|
||||
tsym = l.Left.Type.Elem().Sym
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if tsym == nil || l.Sym.Name != "Data" || tsym.Pkg.Path != "reflect" {
|
||||
return false
|
||||
}
|
||||
return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
|
||||
}
|
||||
|
||||
// Do we need a write barrier for the assignment l = r?
|
||||
func needwritebarrier(l *Node, r *Node) bool {
|
||||
if !use_writebarrier {
|
||||
@@ -2104,21 +2081,15 @@ func needwritebarrier(l *Node, r *Node) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// No write barrier for write to stack.
|
||||
if isstack(l) {
|
||||
// No write barrier for write of non-pointers.
|
||||
dowidth(l.Type)
|
||||
|
||||
if !haspointers(l.Type) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Package unsafe's documentation says storing pointers into
|
||||
// reflect.SliceHeader and reflect.StringHeader's Data fields
|
||||
// is valid, even though they have type uintptr (#19168).
|
||||
if isReflectHeaderDataField(l) {
|
||||
return true
|
||||
}
|
||||
|
||||
// No write barrier for write of non-pointers.
|
||||
dowidth(l.Type)
|
||||
if !haspointers(l.Type) {
|
||||
// No write barrier for write to stack.
|
||||
if isstack(l) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -3146,12 +3117,12 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
||||
cmpr = cmpr.Left
|
||||
}
|
||||
|
||||
if !islvalue(cmpl) || !islvalue(cmpr) {
|
||||
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
|
||||
}
|
||||
|
||||
// Chose not to inline. Call equality function directly.
|
||||
if !inline {
|
||||
if !islvalue(cmpl) || !islvalue(cmpr) {
|
||||
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
|
||||
}
|
||||
|
||||
// eq algs take pointers
|
||||
pl := temp(ptrto(t))
|
||||
al := nod(OAS, pl, nod(OADDR, cmpl, nil))
|
||||
|
||||
@@ -424,7 +424,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Reg = v.Args[0].Reg()
|
||||
gc.AddAux2(&p.To, v, sc.Off())
|
||||
case ssa.OpCopy, ssa.OpS390XMOVDconvert, ssa.OpS390XMOVDreg:
|
||||
case ssa.OpCopy, ssa.OpS390XMOVDconvert:
|
||||
if v.Type.IsMemory() {
|
||||
return
|
||||
}
|
||||
@@ -433,11 +433,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
if x != y {
|
||||
opregreg(moveByType(v.Type), y, x)
|
||||
}
|
||||
case ssa.OpS390XMOVDnop:
|
||||
if v.Reg() != v.Args[0].Reg() {
|
||||
v.Fatalf("input[0] and output not in same register %s", v.LongString())
|
||||
}
|
||||
// nothing to do
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
|
||||
@@ -64,7 +64,7 @@ func liveValues(f *Func, reachable []bool) []bool {
|
||||
q = append(q, v)
|
||||
}
|
||||
for _, v := range b.Values {
|
||||
if (opcodeTable[v.Op].call || opcodeTable[v.Op].hasSideEffects) && !live[v.ID] {
|
||||
if opcodeTable[v.Op].call && !live[v.ID] {
|
||||
live[v.ID] = true
|
||||
q = append(q, v)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package ssa
|
||||
|
||||
import (
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/s390x"
|
||||
"cmd/internal/obj/x86"
|
||||
"testing"
|
||||
)
|
||||
@@ -22,10 +21,6 @@ func testConfig(t testing.TB) *Config {
|
||||
return NewConfig("amd64", DummyFrontend{t}, testCtxt, true)
|
||||
}
|
||||
|
||||
func testConfigS390X(t testing.TB) *Config {
|
||||
return NewConfig("s390x", DummyFrontend{t}, obj.Linknew(&s390x.Links390x), true)
|
||||
}
|
||||
|
||||
// DummyFrontend is a test-only frontend.
|
||||
// It assumes 64 bit integers and pointers.
|
||||
type DummyFrontend struct {
|
||||
|
||||
@@ -522,15 +522,15 @@ func init() {
|
||||
// store arg0 to arg1+auxint+aux, arg2=mem.
|
||||
// These ops return a tuple of <old contents of *(arg1+auxint+aux), memory>.
|
||||
// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
|
||||
{name: "XCHGL", argLength: 3, reg: gpstorexchg, asm: "XCHGL", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true},
|
||||
{name: "XCHGQ", argLength: 3, reg: gpstorexchg, asm: "XCHGQ", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true},
|
||||
{name: "XCHGL", argLength: 3, reg: gpstorexchg, asm: "XCHGL", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true},
|
||||
{name: "XCHGQ", argLength: 3, reg: gpstorexchg, asm: "XCHGQ", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true},
|
||||
|
||||
// Atomic adds.
|
||||
// *(arg1+auxint+aux) += arg0. arg2=mem.
|
||||
// Returns a tuple of <old contents of *(arg1+auxint+aux), memory>.
|
||||
// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
|
||||
{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true},
|
||||
{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true},
|
||||
{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true},
|
||||
{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true},
|
||||
{name: "AddTupleFirst32", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||
{name: "AddTupleFirst64", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||
|
||||
@@ -553,12 +553,12 @@ func init() {
|
||||
// JEQ ...
|
||||
// but we can't do that because memory-using ops can't generate flags yet
|
||||
// (flagalloc wants to move flag-generating instructions around).
|
||||
{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
|
||||
// Atomic memory updates.
|
||||
{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, // *(arg0+auxint+aux) &= arg1
|
||||
{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, // *(arg0+auxint+aux) |= arg1
|
||||
{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true}, // *(arg0+auxint+aux) &= arg1
|
||||
{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true}, // *(arg0+auxint+aux) |= arg1
|
||||
}
|
||||
|
||||
var AMD64blocks = []blockData{
|
||||
|
||||
@@ -178,8 +178,8 @@
|
||||
(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SRAconst (SLLconst <config.fe.TypeUInt32()> x [24]) [31])
|
||||
|
||||
(Lrot32 x [c]) -> (SRRconst x [32-c&31])
|
||||
(Lrot16 <t> x [c]) -> (OR (SLLconst <t> x [c&15]) (SRLconst <t> (ZeroExt16to32 x) [16-c&15]))
|
||||
(Lrot8 <t> x [c]) -> (OR (SLLconst <t> x [c&7]) (SRLconst <t> (ZeroExt8to32 x) [8-c&7]))
|
||||
(Lrot16 <t> x [c]) -> (OR (SLLconst <t> x [c&15]) (SRLconst <t> x [16-c&15]))
|
||||
(Lrot8 <t> x [c]) -> (OR (SLLconst <t> x [c&7]) (SRLconst <t> x [8-c&7]))
|
||||
|
||||
// constants
|
||||
(Const8 [val]) -> (MOVWconst [val])
|
||||
|
||||
@@ -529,148 +529,110 @@
|
||||
// can be encoded in the instructions
|
||||
// since this rewriting takes place before stack allocation, the offset to SP is unknown,
|
||||
// so don't do it for args and locals with unaligned offset
|
||||
(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
|
||||
(MOVBload [off1+off2] {sym} ptr mem)
|
||||
(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
|
||||
(MOVBUload [off1+off2] {sym} ptr mem)
|
||||
(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBload [off1+off2] {sym} ptr mem)
|
||||
(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBUload [off1+off2] {sym} ptr mem)
|
||||
(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVHload [off1+off2] {sym} ptr mem)
|
||||
(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVHUload [off1+off2] {sym} ptr mem)
|
||||
(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVWload [off1+off2] {sym} ptr mem)
|
||||
(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVWUload [off1+off2] {sym} ptr mem)
|
||||
(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVDload [off1+off2] {sym} ptr mem)
|
||||
(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(FMOVSload [off1+off2] {sym} ptr mem)
|
||||
(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(FMOVDload [off1+off2] {sym} ptr mem)
|
||||
|
||||
(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(off1+off2) ->
|
||||
(MOVBstore [off1+off2] {sym} ptr val mem)
|
||||
(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVBstore [off1+off2] {sym} ptr val mem)
|
||||
(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVHstore [off1+off2] {sym} ptr val mem)
|
||||
(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVWstore [off1+off2] {sym} ptr val mem)
|
||||
(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVDstore [off1+off2] {sym} ptr val mem)
|
||||
(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(FMOVSstore [off1+off2] {sym} ptr val mem)
|
||||
(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(FMOVDstore [off1+off2] {sym} ptr val mem)
|
||||
(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
|
||||
(MOVBstorezero [off1+off2] {sym} ptr mem)
|
||||
(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBstorezero [off1+off2] {sym} ptr mem)
|
||||
(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVHstorezero [off1+off2] {sym} ptr mem)
|
||||
(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVWstorezero [off1+off2] {sym} ptr mem)
|
||||
(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
&& is32Bit(off1+off2) && !isArg(sym)
|
||||
&& ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) ->
|
||||
&& (off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
|
||||
(MOVDstorezero [off1+off2] {sym} ptr mem)
|
||||
|
||||
(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) ->
|
||||
(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) ->
|
||||
(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
|
||||
(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) ->
|
||||
(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) ->
|
||||
(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
|
||||
(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
|
||||
&& is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2))
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) ->
|
||||
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
|
||||
(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
|
||||
// store zero
|
||||
|
||||
@@ -456,16 +456,16 @@ func init() {
|
||||
|
||||
// atomic stores.
|
||||
// store arg1 to arg0. arg2=mem. returns memory. auxint must be zero.
|
||||
{name: "STLR", argLength: 3, reg: gpstore, asm: "STLR", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "STLRW", argLength: 3, reg: gpstore, asm: "STLRW", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "STLR", argLength: 3, reg: gpstore, asm: "STLR", faultOnNilArg0: true},
|
||||
{name: "STLRW", argLength: 3, reg: gpstore, asm: "STLRW", faultOnNilArg0: true},
|
||||
|
||||
// atomic exchange.
|
||||
// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.
|
||||
// LDAXR (Rarg0), Rout
|
||||
// STLXR Rarg1, (Rarg0), Rtmp
|
||||
// CBNZ Rtmp, -2(PC)
|
||||
{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic add.
|
||||
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
|
||||
@@ -473,8 +473,8 @@ func init() {
|
||||
// ADD Rarg1, Rout
|
||||
// STLXR Rout, (Rarg0), Rtmp
|
||||
// CBNZ Rtmp, -3(PC)
|
||||
{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic compare and swap.
|
||||
// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
|
||||
@@ -490,8 +490,8 @@ func init() {
|
||||
// STLXR Rarg2, (Rarg0), Rtmp
|
||||
// CBNZ Rtmp, -4(PC)
|
||||
// CSET EQ, Rout
|
||||
{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic and/or.
|
||||
// *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero.
|
||||
@@ -499,8 +499,8 @@ func init() {
|
||||
// AND/OR Rarg1, Rtmp
|
||||
// STLXRB Rtmp, (Rarg0), Rtmp
|
||||
// CBNZ Rtmp, -3(PC)
|
||||
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "ORR", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "ORR", faultOnNilArg0: true},
|
||||
}
|
||||
|
||||
blocks := []blockData{
|
||||
|
||||
@@ -119,8 +119,8 @@ func init() {
|
||||
fp01 = regInfo{inputs: nil, outputs: []regMask{fp}}
|
||||
fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
|
||||
fp1flags = regInfo{inputs: []regMask{fp}}
|
||||
fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}, clobbers: buildReg("F15")} // int-float conversion uses F15 as tmp
|
||||
gpfp = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}, clobbers: buildReg("F15")}
|
||||
fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
|
||||
gpfp = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
|
||||
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
|
||||
fp2flags = regInfo{inputs: []regMask{fp, fp}}
|
||||
fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
|
||||
|
||||
@@ -404,7 +404,8 @@
|
||||
(ANDconst <config.fe.TypeUInt32()> [3] ptr)))
|
||||
(NORconst [0] <config.fe.TypeUInt32()> (SLL <config.fe.TypeUInt32()>
|
||||
(MOVWconst [0xff]) (SLLconst <config.fe.TypeUInt32()> [3]
|
||||
(ANDconst <config.fe.TypeUInt32()> [3] ptr))))) mem)
|
||||
(ANDconst <config.fe.TypeUInt32()> [3]
|
||||
(XORconst <config.fe.TypeUInt32()> [3] ptr)))))) mem)
|
||||
|
||||
// AtomicOr8(ptr,val) -> LoweredAtomicOr(ptr&^3,uint32(val) << (((ptr^3) & 3) * 8))
|
||||
(AtomicOr8 ptr val mem) && config.BigEndian ->
|
||||
|
||||
@@ -267,8 +267,8 @@ func init() {
|
||||
// SYNC
|
||||
// MOVW Rarg1, (Rarg0)
|
||||
// SYNC
|
||||
{name: "LoweredAtomicStore", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStorezero", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicStore", argLength: 3, reg: gpstore, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicStorezero", argLength: 2, reg: gpstore0, faultOnNilArg0: true},
|
||||
|
||||
// atomic exchange.
|
||||
// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
|
||||
@@ -278,7 +278,7 @@ func init() {
|
||||
// SC Rtmp, (Rarg0)
|
||||
// BEQ Rtmp, -3(PC)
|
||||
// SYNC
|
||||
{name: "LoweredAtomicExchange", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicExchange", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic add.
|
||||
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
|
||||
@@ -289,8 +289,8 @@ func init() {
|
||||
// BEQ Rtmp, -3(PC)
|
||||
// SYNC
|
||||
// ADDU Rarg1, Rout
|
||||
{name: "LoweredAtomicAdd", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAddconst", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAdd", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicAddconst", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic compare and swap.
|
||||
// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
|
||||
@@ -308,7 +308,7 @@ func init() {
|
||||
// SC Rout, (Rarg0)
|
||||
// BEQ Rout, -4(PC)
|
||||
// SYNC
|
||||
{name: "LoweredAtomicCas", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicCas", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true},
|
||||
|
||||
// atomic and/or.
|
||||
// *arg0 &= (|=) arg1. arg2=mem. returns memory.
|
||||
@@ -318,8 +318,8 @@ func init() {
|
||||
// SC Rtmp, (Rarg0)
|
||||
// BEQ Rtmp, -3(PC)
|
||||
// SYNC
|
||||
{name: "LoweredAtomicAnd", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicOr", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicAnd", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicOr", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true},
|
||||
|
||||
// large or unaligned zeroing
|
||||
// arg0 = address of memory to zero (in R1, changed as side effect)
|
||||
|
||||
@@ -338,9 +338,9 @@
|
||||
(Geq32F x y) -> (FGreaterEqual (FCMPU x y))
|
||||
(Geq64F x y) -> (FGreaterEqual (FCMPU x y))
|
||||
|
||||
(Geq8U x y) -> (GreaterEqual (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
||||
(Geq16U x y) -> (GreaterEqual (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
|
||||
(Geq32U x y) -> (GreaterEqual (CMPWU x y))
|
||||
(Geq8U x y) -> (GreaterEqual (CMPU (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
||||
(Geq16U x y) -> (GreaterEqual (CMPU (ZeroExt16to32 x) (ZeroExt16to32 y)))
|
||||
(Geq32U x y) -> (GreaterEqual (CMPU x y))
|
||||
(Geq64U x y) -> (GreaterEqual (CMPU x y))
|
||||
|
||||
// Absorb pseudo-ops into blocks.
|
||||
|
||||
@@ -312,12 +312,9 @@
|
||||
|
||||
// Lowering loads
|
||||
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVDload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) -> (MOVWload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) -> (MOVWZload ptr mem)
|
||||
(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) -> (MOVHload ptr mem)
|
||||
(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) -> (MOVHZload ptr mem)
|
||||
(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) -> (MOVBload ptr mem)
|
||||
(Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) -> (MOVBZload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitInt(t) -> (MOVWZload ptr mem)
|
||||
(Load <t> ptr mem) && is16BitInt(t) -> (MOVHZload ptr mem)
|
||||
(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) -> (MOVBZload ptr mem)
|
||||
(Load <t> ptr mem) && is32BitFloat(t) -> (FMOVSload ptr mem)
|
||||
(Load <t> ptr mem) && is64BitFloat(t) -> (FMOVDload ptr mem)
|
||||
|
||||
@@ -440,7 +437,7 @@
|
||||
(If (MOVDGTnoinv (MOVDconst [0]) (MOVDconst [1]) cmp) yes no) -> (GTF cmp yes no)
|
||||
(If (MOVDGEnoinv (MOVDconst [0]) (MOVDconst [1]) cmp) yes no) -> (GEF cmp yes no)
|
||||
|
||||
(If cond yes no) -> (NE (CMPWconst [0] (MOVBZreg <config.fe.TypeBool()> cond)) yes no)
|
||||
(If cond yes no) -> (NE (CMPWconst [0] (MOVBZreg cond)) yes no)
|
||||
|
||||
// ***************************
|
||||
// Above: lowering rules
|
||||
@@ -448,28 +445,16 @@
|
||||
// ***************************
|
||||
// TODO: Should the optimizations be a separate pass?
|
||||
|
||||
// Fold unnecessary type conversions.
|
||||
(MOVDreg <t> x) && t.Compare(x.Type) == CMPeq -> x
|
||||
(MOVDnop <t> x) && t.Compare(x.Type) == CMPeq -> x
|
||||
|
||||
// Propagate constants through type conversions.
|
||||
(MOVDreg (MOVDconst [c])) -> (MOVDconst [c])
|
||||
(MOVDnop (MOVDconst [c])) -> (MOVDconst [c])
|
||||
|
||||
// If a register move has only 1 use, just use the same register without emitting instruction.
|
||||
// MOVDnop doesn't emit instruction, only for ensuring the type.
|
||||
(MOVDreg x) && x.Uses == 1 -> (MOVDnop x)
|
||||
|
||||
// Fold sign extensions into conditional moves of constants.
|
||||
// Designed to remove the MOVBZreg inserted by the If lowering.
|
||||
(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
|
||||
|
||||
// Fold boolean tests into blocks.
|
||||
(NE (CMPWconst [0] (MOVDLT (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no) -> (LT cmp yes no)
|
||||
@@ -587,46 +572,46 @@
|
||||
(MOVDNE x y (InvertFlags cmp)) -> (MOVDNE x y cmp)
|
||||
|
||||
// don't extend after proper load
|
||||
(MOVBreg x:(MOVBload _ _)) -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVBZload _ _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVBload _ _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVBZload _ _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVHload _ _)) -> (MOVDreg x)
|
||||
(MOVHZreg x:(MOVBZload _ _)) -> (MOVDreg x)
|
||||
(MOVHZreg x:(MOVHZload _ _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVBload _ _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVBZload _ _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVHload _ _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVHZload _ _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVWload _ _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVBZload _ _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVHZload _ _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVWZload _ _)) -> (MOVDreg x)
|
||||
(MOVBreg x:(MOVBload _ _)) -> x
|
||||
(MOVBZreg x:(MOVBZload _ _)) -> x
|
||||
(MOVHreg x:(MOVBload _ _)) -> x
|
||||
(MOVHreg x:(MOVBZload _ _)) -> x
|
||||
(MOVHreg x:(MOVHload _ _)) -> x
|
||||
(MOVHZreg x:(MOVBZload _ _)) -> x
|
||||
(MOVHZreg x:(MOVHZload _ _)) -> x
|
||||
(MOVWreg x:(MOVBload _ _)) -> x
|
||||
(MOVWreg x:(MOVBZload _ _)) -> x
|
||||
(MOVWreg x:(MOVHload _ _)) -> x
|
||||
(MOVWreg x:(MOVHZload _ _)) -> x
|
||||
(MOVWreg x:(MOVWload _ _)) -> x
|
||||
(MOVWZreg x:(MOVBZload _ _)) -> x
|
||||
(MOVWZreg x:(MOVHZload _ _)) -> x
|
||||
(MOVWZreg x:(MOVWZload _ _)) -> x
|
||||
|
||||
// don't extend if argument is already extended
|
||||
(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) -> (MOVDreg x)
|
||||
(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) -> (MOVDreg x)
|
||||
(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> (MOVDreg x)
|
||||
(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> (MOVDreg x)
|
||||
(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> (MOVDreg x)
|
||||
(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> (MOVDreg x)
|
||||
(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) -> x
|
||||
(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) -> x
|
||||
(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> x
|
||||
(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> x
|
||||
(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> x
|
||||
(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> x
|
||||
|
||||
// fold double extensions
|
||||
(MOVBreg x:(MOVBreg _)) -> (MOVDreg x)
|
||||
(MOVBZreg x:(MOVBZreg _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVBreg _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVBZreg _)) -> (MOVDreg x)
|
||||
(MOVHreg x:(MOVHreg _)) -> (MOVDreg x)
|
||||
(MOVHZreg x:(MOVBZreg _)) -> (MOVDreg x)
|
||||
(MOVHZreg x:(MOVHZreg _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVBreg _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVBZreg _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVHreg _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVHreg _)) -> (MOVDreg x)
|
||||
(MOVWreg x:(MOVWreg _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVBZreg _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVHZreg _)) -> (MOVDreg x)
|
||||
(MOVWZreg x:(MOVWZreg _)) -> (MOVDreg x)
|
||||
(MOVBreg x:(MOVBreg _)) -> x
|
||||
(MOVBZreg x:(MOVBZreg _)) -> x
|
||||
(MOVHreg x:(MOVBreg _)) -> x
|
||||
(MOVHreg x:(MOVBZreg _)) -> x
|
||||
(MOVHreg x:(MOVHreg _)) -> x
|
||||
(MOVHZreg x:(MOVBZreg _)) -> x
|
||||
(MOVHZreg x:(MOVHZreg _)) -> x
|
||||
(MOVWreg x:(MOVBreg _)) -> x
|
||||
(MOVWreg x:(MOVBZreg _)) -> x
|
||||
(MOVWreg x:(MOVHreg _)) -> x
|
||||
(MOVWreg x:(MOVHreg _)) -> x
|
||||
(MOVWreg x:(MOVWreg _)) -> x
|
||||
(MOVWZreg x:(MOVBZreg _)) -> x
|
||||
(MOVWZreg x:(MOVHZreg _)) -> x
|
||||
(MOVWZreg x:(MOVWZreg _)) -> x
|
||||
|
||||
// fold extensions into constants
|
||||
(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64(int8(c))])
|
||||
@@ -656,10 +641,10 @@
|
||||
(MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
|
||||
|
||||
// replace load from same location as preceding store with copy
|
||||
(MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
|
||||
(MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
|
||||
(MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
|
||||
(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
|
||||
(MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
|
||||
(MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
|
||||
(MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
|
||||
(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
|
||||
|
||||
// Don't extend before storing
|
||||
(MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem)
|
||||
@@ -900,9 +885,9 @@
|
||||
(MOVDEQ y _ (FlagLT)) -> y
|
||||
(MOVDEQ y _ (FlagGT)) -> y
|
||||
|
||||
(MOVDNE y _ (FlagEQ)) -> y
|
||||
(MOVDNE _ x (FlagLT)) -> x
|
||||
(MOVDNE _ x (FlagGT)) -> x
|
||||
(MOVDNE _ y (FlagEQ)) -> y
|
||||
(MOVDNE x _ (FlagLT)) -> x
|
||||
(MOVDNE x _ (FlagGT)) -> x
|
||||
|
||||
(MOVDLT y _ (FlagEQ)) -> y
|
||||
(MOVDLT _ x (FlagLT)) -> x
|
||||
|
||||
@@ -311,9 +311,6 @@ func init() {
|
||||
{name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"}, // zero extend arg0 from int16 to int64
|
||||
{name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"}, // sign extend arg0 from int32 to int64
|
||||
{name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"}, // zero extend arg0 from int32 to int64
|
||||
{name: "MOVDreg", argLength: 1, reg: gp11sp, asm: "MOVD"}, // move from arg0
|
||||
|
||||
{name: "MOVDnop", argLength: 1, reg: gp11, resultInArg0: true}, // nop, return arg0 in same register
|
||||
|
||||
{name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
|
||||
|
||||
@@ -429,14 +426,14 @@ func init() {
|
||||
|
||||
// Atomic stores. These are just normal stores.
|
||||
// store arg1 to arg0+auxint+aux. arg2=mem.
|
||||
{name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true},
|
||||
{name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true},
|
||||
|
||||
// Atomic adds.
|
||||
// *(arg0+auxint+aux) += arg1. arg2=mem.
|
||||
// Returns a tuple of <old contents of *(arg0+auxint+aux), memory>.
|
||||
{name: "LAA", argLength: 3, reg: gpstorelaa, asm: "LAA", typ: "(UInt32,Mem)", aux: "SymOff", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LAAG", argLength: 3, reg: gpstorelaa, asm: "LAAG", typ: "(UInt64,Mem)", aux: "SymOff", faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LAA", argLength: 3, reg: gpstorelaa, asm: "LAA", typ: "(UInt32,Mem)", aux: "SymOff", faultOnNilArg0: true},
|
||||
{name: "LAAG", argLength: 3, reg: gpstorelaa, asm: "LAAG", typ: "(UInt64,Mem)", aux: "SymOff", faultOnNilArg0: true},
|
||||
{name: "AddTupleFirst32", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||
{name: "AddTupleFirst64", argLength: 2}, // arg0=tuple <x,y>. Returns <x+arg1,y>.
|
||||
|
||||
@@ -461,13 +458,13 @@ func init() {
|
||||
// BEQ ...
|
||||
// but we can't do that because memory-using ops can't generate flags yet
|
||||
// (flagalloc wants to move flag-generating instructions around).
|
||||
{name: "LoweredAtomicCas32", argLength: 4, reg: cas, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicCas64", argLength: 4, reg: cas, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicCas32", argLength: 4, reg: cas, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicCas64", argLength: 4, reg: cas, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
|
||||
// Lowered atomic swaps, emulated using compare-and-swap.
|
||||
// store arg1 to arg0+auxint+aux, arg2=mem.
|
||||
{name: "LoweredAtomicExchange32", argLength: 3, reg: exchange, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicExchange64", argLength: 3, reg: exchange, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
|
||||
{name: "LoweredAtomicExchange32", argLength: 3, reg: exchange, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
{name: "LoweredAtomicExchange64", argLength: 3, reg: exchange, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true},
|
||||
|
||||
// find leftmost one
|
||||
{
|
||||
|
||||
@@ -460,20 +460,20 @@ var genericOps = []opData{
|
||||
// Atomic loads return a new memory so that the loads are properly ordered
|
||||
// with respect to other loads and stores.
|
||||
// TODO: use for sync/atomic at some point.
|
||||
{name: "AtomicLoad32", argLength: 2, typ: "(UInt32,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicStore32", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStore64", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
|
||||
{name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
|
||||
{name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
|
||||
{name: "AtomicAdd64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
|
||||
{name: "AtomicCompareAndSwap32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Returns true iff store happens and new memory.
|
||||
{name: "AtomicCompareAndSwap64", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2. Returns true iff store happens and new memory.
|
||||
{name: "AtomicAnd8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory.
|
||||
{name: "AtomicOr8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory.
|
||||
{name: "AtomicLoad32", argLength: 2, typ: "(UInt32,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"}, // Load from arg0. arg1=memory. Returns loaded value and new memory.
|
||||
{name: "AtomicStore32", argLength: 3, typ: "Mem"}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStore64", argLength: 3, typ: "Mem"}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem"}, // Store arg1 to *arg0. arg2=memory. Returns memory.
|
||||
{name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)"}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
|
||||
{name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)"}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
|
||||
{name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)"}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
|
||||
{name: "AtomicAdd64", argLength: 3, typ: "(UInt64,Mem)"}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
|
||||
{name: "AtomicCompareAndSwap32", argLength: 4, typ: "(Bool,Mem)"}, // if *arg0==arg1, then set *arg0=arg2. Returns true iff store happens and new memory.
|
||||
{name: "AtomicCompareAndSwap64", argLength: 4, typ: "(Bool,Mem)"}, // if *arg0==arg1, then set *arg0=arg2. Returns true iff store happens and new memory.
|
||||
{name: "AtomicAnd8", argLength: 3, typ: "Mem"}, // *arg0 &= arg1. arg2=memory. Returns memory.
|
||||
{name: "AtomicOr8", argLength: 3, typ: "Mem"}, // *arg0 |= arg1. arg2=memory. Returns memory.
|
||||
}
|
||||
|
||||
// kind control successors implicit exit
|
||||
|
||||
@@ -52,7 +52,6 @@ type opData struct {
|
||||
faultOnNilArg0 bool // this op will fault if arg0 is nil (and aux encodes a small offset)
|
||||
faultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset)
|
||||
usesScratch bool // this op requires scratch memory space
|
||||
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
||||
}
|
||||
|
||||
type blockData struct {
|
||||
@@ -209,9 +208,6 @@ func genOp() {
|
||||
if v.usesScratch {
|
||||
fmt.Fprintln(w, "usesScratch: true,")
|
||||
}
|
||||
if v.hasSideEffects {
|
||||
fmt.Fprintln(w, "hasSideEffects: true,")
|
||||
}
|
||||
if a.name == "generic" {
|
||||
fmt.Fprintln(w, "generic:true,")
|
||||
fmt.Fprintln(w, "},") // close op
|
||||
|
||||
@@ -33,24 +33,13 @@ type loop struct {
|
||||
|
||||
// outerinner records that outer contains inner
|
||||
func (sdom SparseTree) outerinner(outer, inner *loop) {
|
||||
// There could be other outer loops found in some random order,
|
||||
// locate the new outer loop appropriately among them.
|
||||
oldouter := inner.outer
|
||||
for oldouter != nil && sdom.isAncestor(outer.header, oldouter.header) {
|
||||
inner = oldouter
|
||||
oldouter = inner.outer
|
||||
}
|
||||
if outer == oldouter {
|
||||
return
|
||||
}
|
||||
if oldouter != nil {
|
||||
outer.outer = oldouter
|
||||
}
|
||||
|
||||
inner.outer = outer
|
||||
outer.isInner = false
|
||||
if inner.containsCall {
|
||||
outer.setContainsCall()
|
||||
if oldouter == nil || sdom.isAncestorEq(oldouter.header, outer.header) {
|
||||
inner.outer = outer
|
||||
outer.isInner = false
|
||||
if inner.containsCall {
|
||||
outer.setContainsCall()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ssa
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoopConditionS390X(t *testing.T) {
|
||||
// Test that a simple loop condition does not generate a conditional
|
||||
// move (issue #19227).
|
||||
//
|
||||
// MOVDLT is generated when Less64 is lowered but should be
|
||||
// optimized into an LT branch.
|
||||
//
|
||||
// For example, compiling the following loop:
|
||||
//
|
||||
// for i := 0; i < N; i++ {
|
||||
// sum += 3
|
||||
// }
|
||||
//
|
||||
// should generate assembly similar to:
|
||||
// loop:
|
||||
// CMP R0, R1
|
||||
// BGE done
|
||||
// ADD $3, R4
|
||||
// ADD $1, R1
|
||||
// BR loop
|
||||
// done:
|
||||
//
|
||||
// rather than:
|
||||
// loop:
|
||||
// MOVD $0, R2
|
||||
// MOVD $1, R3
|
||||
// CMP R0, R1
|
||||
// MOVDLT R2, R3
|
||||
// CMPW R2, $0
|
||||
// BNE done
|
||||
// ADD $3, R4
|
||||
// ADD $1, R1
|
||||
// BR loop
|
||||
// done:
|
||||
//
|
||||
c := testConfigS390X(t)
|
||||
fun := Fun(c, "entry",
|
||||
Bloc("entry",
|
||||
Valu("mem", OpInitMem, TypeMem, 0, nil),
|
||||
Valu("SP", OpSP, TypeUInt64, 0, nil),
|
||||
Valu("Nptr", OpOffPtr, TypeInt64Ptr, 8, nil, "SP"),
|
||||
Valu("ret", OpOffPtr, TypeInt64Ptr, 16, nil, "SP"),
|
||||
Valu("N", OpLoad, TypeInt64, 0, nil, "Nptr", "mem"),
|
||||
Valu("starti", OpConst64, TypeInt64, 0, nil),
|
||||
Valu("startsum", OpConst64, TypeInt64, 0, nil),
|
||||
Goto("b1")),
|
||||
Bloc("b1",
|
||||
Valu("phii", OpPhi, TypeInt64, 0, nil, "starti", "i"),
|
||||
Valu("phisum", OpPhi, TypeInt64, 0, nil, "startsum", "sum"),
|
||||
Valu("cmp1", OpLess64, TypeBool, 0, nil, "phii", "N"),
|
||||
If("cmp1", "b2", "b3")),
|
||||
Bloc("b2",
|
||||
Valu("c1", OpConst64, TypeInt64, 1, nil),
|
||||
Valu("i", OpAdd64, TypeInt64, 0, nil, "phii", "c1"),
|
||||
Valu("c3", OpConst64, TypeInt64, 3, nil),
|
||||
Valu("sum", OpAdd64, TypeInt64, 0, nil, "phisum", "c3"),
|
||||
Goto("b1")),
|
||||
Bloc("b3",
|
||||
Valu("store", OpStore, TypeMem, 8, nil, "ret", "phisum", "mem"),
|
||||
Exit("store")))
|
||||
CheckFunc(fun.f)
|
||||
Compile(fun.f)
|
||||
CheckFunc(fun.f)
|
||||
|
||||
checkOpcodeCounts(t, fun.f, map[Op]int{
|
||||
OpS390XMOVDLT: 0,
|
||||
OpS390XMOVDGT: 0,
|
||||
OpS390XMOVDLE: 0,
|
||||
OpS390XMOVDGE: 0,
|
||||
OpS390XMOVDEQ: 0,
|
||||
OpS390XMOVDNE: 0,
|
||||
OpS390XCMP: 1,
|
||||
OpS390XCMPWconst: 0,
|
||||
})
|
||||
|
||||
fun.f.Free()
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func nilcheckelim(f *Func) {
|
||||
}
|
||||
}
|
||||
|
||||
// Next, eliminate any redundant nil checks in this block.
|
||||
// Next, process values in the block.
|
||||
i := 0
|
||||
for _, v := range b.Values {
|
||||
b.Values[i] = v
|
||||
@@ -105,10 +105,13 @@ func nilcheckelim(f *Func) {
|
||||
f.Config.Warnl(v.Line, "removed nil check")
|
||||
}
|
||||
v.reset(OpUnknown)
|
||||
// TODO: f.freeValue(v)
|
||||
i--
|
||||
continue
|
||||
}
|
||||
// Record the fact that we know ptr is non nil, and remember to
|
||||
// undo that information when this dominator subtree is done.
|
||||
nonNilValues[ptr.ID] = true
|
||||
work = append(work, bp{op: ClearPtr, ptr: ptr})
|
||||
}
|
||||
}
|
||||
for j := i; j < len(b.Values); j++ {
|
||||
@@ -116,21 +119,6 @@ func nilcheckelim(f *Func) {
|
||||
}
|
||||
b.Values = b.Values[:i]
|
||||
|
||||
// Finally, find redundant nil checks for subsequent blocks.
|
||||
// Note that we can't add these until the loop above is done, as the
|
||||
// values in the block are not ordered in any way when this pass runs.
|
||||
// This was the cause of issue #18725.
|
||||
for _, v := range b.Values {
|
||||
if v.Op != OpNilCheck {
|
||||
continue
|
||||
}
|
||||
ptr := v.Args[0]
|
||||
// Record the fact that we know ptr is non nil, and remember to
|
||||
// undo that information when this dominator subtree is done.
|
||||
nonNilValues[ptr.ID] = true
|
||||
work = append(work, bp{op: ClearPtr, ptr: ptr})
|
||||
}
|
||||
|
||||
// Add all dominated blocks to the work list.
|
||||
for w := sdom[node.block.ID].child; w != nil; w = sdom[w.ID].sibling {
|
||||
work = append(work, bp{op: Work, block: w})
|
||||
|
||||
@@ -34,7 +34,6 @@ type opInfo struct {
|
||||
faultOnNilArg0 bool // this op will fault if arg0 is nil (and aux encodes a small offset)
|
||||
faultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset)
|
||||
usesScratch bool // this op requires scratch memory space
|
||||
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
|
||||
}
|
||||
|
||||
type inputInfo struct {
|
||||
|
||||
@@ -1473,8 +1473,6 @@ const (
|
||||
OpS390XMOVHZreg
|
||||
OpS390XMOVWreg
|
||||
OpS390XMOVWZreg
|
||||
OpS390XMOVDreg
|
||||
OpS390XMOVDnop
|
||||
OpS390XMOVDconst
|
||||
OpS390XCFDBRA
|
||||
OpS390XCGDBRA
|
||||
@@ -7307,7 +7305,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultInArg0: true,
|
||||
faultOnNilArg1: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AXCHGL,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7325,7 +7322,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultInArg0: true,
|
||||
faultOnNilArg1: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AXCHGQ,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7344,7 +7340,6 @@ var opcodeTable = [...]opInfo{
|
||||
resultInArg0: true,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg1: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AXADDL,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7363,7 +7358,6 @@ var opcodeTable = [...]opInfo{
|
||||
resultInArg0: true,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg1: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AXADDQ,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7391,7 +7385,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 4,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.ACMPXCHGL,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7412,7 +7405,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 4,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.ACMPXCHGQ,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7433,7 +7425,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AANDB,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -7448,7 +7439,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: x86.AORB,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -10083,7 +10073,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
@@ -10097,7 +10086,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
@@ -10111,7 +10099,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
@@ -10125,7 +10112,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
@@ -10139,7 +10125,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
@@ -10153,7 +10138,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
@@ -10167,7 +10151,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
@@ -10181,7 +10164,6 @@ var opcodeTable = [...]opInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
clobbers: 2147483648, // F15
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
@@ -12673,7 +12655,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "STLR",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: arm64.ASTLR,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -12686,7 +12667,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "STLRW",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: arm64.ASTLRW,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -12700,7 +12680,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12716,7 +12695,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12732,7 +12710,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12748,7 +12725,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12765,7 +12741,6 @@ var opcodeTable = [...]opInfo{
|
||||
resultNotInArgs: true,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12783,7 +12758,6 @@ var opcodeTable = [...]opInfo{
|
||||
resultNotInArgs: true,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
|
||||
@@ -12799,7 +12773,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicAnd8",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: arm64.AAND,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -12812,7 +12785,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicOr8",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: arm64.AORR,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -14003,7 +13975,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicStore",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
@@ -14015,7 +13986,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicStorezero",
|
||||
argLen: 2,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 140738025226238}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 SP g R31 SB
|
||||
@@ -14027,7 +13997,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
@@ -14043,7 +14012,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
@@ -14060,7 +14028,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 2,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 140738025226238}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 SP g R31 SB
|
||||
@@ -14075,7 +14042,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 4,
|
||||
resultNotInArgs: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{1, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
|
||||
@@ -14091,7 +14057,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicAnd",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: mips.AAND,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -14104,7 +14069,6 @@ var opcodeTable = [...]opInfo{
|
||||
name: "LoweredAtomicOr",
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: mips.AOR,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -18606,32 +18570,6 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MOVDreg",
|
||||
argLen: 1,
|
||||
asm: s390x.AMOVD,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 54271}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MOVDnop",
|
||||
argLen: 1,
|
||||
resultInArg0: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MOVDconst",
|
||||
auxType: auxInt64,
|
||||
@@ -19534,7 +19472,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.AMOVW,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19549,7 +19486,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.AMOVD,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19563,7 +19499,6 @@ var opcodeTable = [...]opInfo{
|
||||
auxType: auxSymOff,
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ALAA,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19580,7 +19515,6 @@ var opcodeTable = [...]opInfo{
|
||||
auxType: auxSymOff,
|
||||
argLen: 3,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ALAAG,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19608,7 +19542,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 4,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ACS,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19629,7 +19562,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 4,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ACSG,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19650,7 +19582,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ACS,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -19669,7 +19600,6 @@ var opcodeTable = [...]opInfo{
|
||||
argLen: 3,
|
||||
clobberFlags: true,
|
||||
faultOnNilArg0: true,
|
||||
hasSideEffects: true,
|
||||
asm: s390x.ACSG,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
@@ -21457,70 +21387,59 @@ var opcodeTable = [...]opInfo{
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicStore32",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicStore32",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicStore64",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicStore64",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicStorePtrNoWB",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicStorePtrNoWB",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicExchange32",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicExchange32",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicExchange64",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicExchange64",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicAdd32",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicAdd32",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicAdd64",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicAdd64",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicCompareAndSwap32",
|
||||
argLen: 4,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicCompareAndSwap32",
|
||||
argLen: 4,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicCompareAndSwap64",
|
||||
argLen: 4,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicCompareAndSwap64",
|
||||
argLen: 4,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicAnd8",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicAnd8",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
{
|
||||
name: "AtomicOr8",
|
||||
argLen: 3,
|
||||
hasSideEffects: true,
|
||||
generic: true,
|
||||
name: "AtomicOr8",
|
||||
argLen: 3,
|
||||
generic: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -14517,7 +14517,7 @@ func rewriteValueARM_OpLrot16(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Lrot16 <t> x [c])
|
||||
// cond:
|
||||
// result: (OR (SLLconst <t> x [c&15]) (SRLconst <t> (ZeroExt16to32 x) [16-c&15]))
|
||||
// result: (OR (SLLconst <t> x [c&15]) (SRLconst <t> x [16-c&15]))
|
||||
for {
|
||||
t := v.Type
|
||||
c := v.AuxInt
|
||||
@@ -14529,9 +14529,7 @@ func rewriteValueARM_OpLrot16(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpARMSRLconst, t)
|
||||
v1.AuxInt = 16 - c&15
|
||||
v2 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32())
|
||||
v2.AddArg(x)
|
||||
v1.AddArg(v2)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
@@ -14556,7 +14554,7 @@ func rewriteValueARM_OpLrot8(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Lrot8 <t> x [c])
|
||||
// cond:
|
||||
// result: (OR (SLLconst <t> x [c&7]) (SRLconst <t> (ZeroExt8to32 x) [8-c&7]))
|
||||
// result: (OR (SLLconst <t> x [c&7]) (SRLconst <t> x [8-c&7]))
|
||||
for {
|
||||
t := v.Type
|
||||
c := v.AuxInt
|
||||
@@ -14568,9 +14566,7 @@ func rewriteValueARM_OpLrot8(v *Value, config *Config) bool {
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpARMSRLconst, t)
|
||||
v1.AuxInt = 8 - c&7
|
||||
v2 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32())
|
||||
v2.AddArg(x)
|
||||
v1.AddArg(v2)
|
||||
v1.AddArg(x)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -2625,7 +2625,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (FMOVDload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2637,7 +2637,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVDload)
|
||||
@@ -2648,7 +2648,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2661,7 +2661,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVDload)
|
||||
@@ -2677,7 +2677,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (FMOVDstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2690,7 +2690,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVDstore)
|
||||
@@ -2702,7 +2702,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2716,7 +2716,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVDstore)
|
||||
@@ -2733,7 +2733,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (FMOVSload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2745,7 +2745,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVSload)
|
||||
@@ -2756,7 +2756,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2769,7 +2769,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVSload)
|
||||
@@ -2785,7 +2785,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (FMOVSstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2798,7 +2798,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVSstore)
|
||||
@@ -2810,7 +2810,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -2824,7 +2824,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64FMOVSstore)
|
||||
@@ -3511,7 +3511,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2)
|
||||
// cond:
|
||||
// result: (MOVBUload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3523,9 +3523,6 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBUload)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
@@ -3534,7 +3531,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3547,7 +3544,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBUload)
|
||||
@@ -3626,7 +3623,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2)
|
||||
// cond:
|
||||
// result: (MOVBload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3638,9 +3635,6 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBload)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
@@ -3649,7 +3643,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3662,7 +3656,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBload)
|
||||
@@ -3741,7 +3735,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2)
|
||||
// cond:
|
||||
// result: (MOVBstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3754,9 +3748,6 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
@@ -3766,7 +3757,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3780,7 +3771,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBstore)
|
||||
@@ -3945,7 +3936,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2)
|
||||
// cond:
|
||||
// result: (MOVBstorezero [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3957,9 +3948,6 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
@@ -3968,7 +3956,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
|
||||
// cond: canMergeSym(sym1,sym2)
|
||||
// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -3981,7 +3969,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
|
||||
if !(canMergeSym(sym1, sym2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVBstorezero)
|
||||
@@ -3997,7 +3985,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVDload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4009,7 +3997,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDload)
|
||||
@@ -4020,7 +4008,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4033,7 +4021,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDload)
|
||||
@@ -4100,7 +4088,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVDstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4113,7 +4101,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDstore)
|
||||
@@ -4125,7 +4113,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4139,7 +4127,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDstore)
|
||||
@@ -4178,7 +4166,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVDstorezero [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4190,7 +4178,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDstorezero)
|
||||
@@ -4201,7 +4189,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4214,7 +4202,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVDstorezero)
|
||||
@@ -4230,7 +4218,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVHUload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4242,7 +4230,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHUload)
|
||||
@@ -4253,7 +4241,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4266,7 +4254,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHUload)
|
||||
@@ -4369,7 +4357,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVHload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4381,7 +4369,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHload)
|
||||
@@ -4392,7 +4380,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4405,7 +4393,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHload)
|
||||
@@ -4532,7 +4520,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVHstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4545,7 +4533,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHstore)
|
||||
@@ -4557,7 +4545,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4571,7 +4559,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHstore)
|
||||
@@ -4694,7 +4682,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVHstorezero [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4706,7 +4694,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHstorezero)
|
||||
@@ -4717,7 +4705,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4730,7 +4718,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVHstorezero)
|
||||
@@ -4746,7 +4734,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVWUload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4758,7 +4746,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWUload)
|
||||
@@ -4769,7 +4757,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4782,7 +4770,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWUload)
|
||||
@@ -4909,7 +4897,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVWload [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4921,7 +4909,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWload)
|
||||
@@ -4932,7 +4920,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -4945,7 +4933,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWload)
|
||||
@@ -5120,7 +5108,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVWstore [off1+off2] {sym} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -5133,7 +5121,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWstore)
|
||||
@@ -5145,7 +5133,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -5159,7 +5147,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
|
||||
ptr := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWstore)
|
||||
@@ -5240,7 +5228,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
|
||||
// cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym))
|
||||
// cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
|
||||
// result: (MOVWstorezero [off1+off2] {sym} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -5252,7 +5240,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
|
||||
off2 := v_0.AuxInt
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) {
|
||||
if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWstorezero)
|
||||
@@ -5263,7 +5251,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
|
||||
// cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2)))
|
||||
// cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
|
||||
// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
@@ -5276,7 +5264,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
|
||||
sym2 := v_0.Aux
|
||||
ptr := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) {
|
||||
if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARM64MOVWstorezero)
|
||||
|
||||
@@ -712,7 +712,7 @@ func rewriteValueMIPS_OpAtomicAnd8(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (AtomicAnd8 ptr val mem)
|
||||
// cond: !config.BigEndian
|
||||
// result: (LoweredAtomicAnd (AND <config.fe.TypeUInt32().PtrTo()> (MOVWconst [^3]) ptr) (OR <config.fe.TypeUInt32()> (SLL <config.fe.TypeUInt32()> (ZeroExt8to32 val) (SLLconst <config.fe.TypeUInt32()> [3] (ANDconst <config.fe.TypeUInt32()> [3] ptr))) (NORconst [0] <config.fe.TypeUInt32()> (SLL <config.fe.TypeUInt32()> (MOVWconst [0xff]) (SLLconst <config.fe.TypeUInt32()> [3] (ANDconst <config.fe.TypeUInt32()> [3] ptr))))) mem)
|
||||
// result: (LoweredAtomicAnd (AND <config.fe.TypeUInt32().PtrTo()> (MOVWconst [^3]) ptr) (OR <config.fe.TypeUInt32()> (SLL <config.fe.TypeUInt32()> (ZeroExt8to32 val) (SLLconst <config.fe.TypeUInt32()> [3] (ANDconst <config.fe.TypeUInt32()> [3] ptr))) (NORconst [0] <config.fe.TypeUInt32()> (SLL <config.fe.TypeUInt32()> (MOVWconst [0xff]) (SLLconst <config.fe.TypeUInt32()> [3] (ANDconst <config.fe.TypeUInt32()> [3] (XORconst <config.fe.TypeUInt32()> [3] ptr)))))) mem)
|
||||
for {
|
||||
ptr := v.Args[0]
|
||||
val := v.Args[1]
|
||||
@@ -750,7 +750,10 @@ func rewriteValueMIPS_OpAtomicAnd8(v *Value, config *Config) bool {
|
||||
v10.AuxInt = 3
|
||||
v11 := b.NewValue0(v.Line, OpMIPSANDconst, config.fe.TypeUInt32())
|
||||
v11.AuxInt = 3
|
||||
v11.AddArg(ptr)
|
||||
v12 := b.NewValue0(v.Line, OpMIPSXORconst, config.fe.TypeUInt32())
|
||||
v12.AuxInt = 3
|
||||
v12.AddArg(ptr)
|
||||
v11.AddArg(v12)
|
||||
v10.AddArg(v11)
|
||||
v8.AddArg(v10)
|
||||
v7.AddArg(v8)
|
||||
|
||||
@@ -1543,12 +1543,12 @@ func rewriteValuePPC64_OpGeq16U(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Geq16U x y)
|
||||
// cond:
|
||||
// result: (GreaterEqual (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
|
||||
// result: (GreaterEqual (CMPU (ZeroExt16to32 x) (ZeroExt16to32 y)))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpPPC64GreaterEqual)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
|
||||
v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32())
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
@@ -1598,12 +1598,12 @@ func rewriteValuePPC64_OpGeq32U(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Geq32U x y)
|
||||
// cond:
|
||||
// result: (GreaterEqual (CMPWU x y))
|
||||
// result: (GreaterEqual (CMPU x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpPPC64GreaterEqual)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@@ -1687,12 +1687,12 @@ func rewriteValuePPC64_OpGeq8U(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Geq8U x y)
|
||||
// cond:
|
||||
// result: (GreaterEqual (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
||||
// result: (GreaterEqual (CMPU (ZeroExt8to32 x) (ZeroExt8to32 y)))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpPPC64GreaterEqual)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
|
||||
v1 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32())
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
|
||||
@@ -524,10 +524,6 @@ func rewriteValueS390X(v *Value, config *Config) bool {
|
||||
return rewriteValueS390X_OpS390XMOVDload(v, config)
|
||||
case OpS390XMOVDloadidx:
|
||||
return rewriteValueS390X_OpS390XMOVDloadidx(v, config)
|
||||
case OpS390XMOVDnop:
|
||||
return rewriteValueS390X_OpS390XMOVDnop(v, config)
|
||||
case OpS390XMOVDreg:
|
||||
return rewriteValueS390X_OpS390XMOVDreg(v, config)
|
||||
case OpS390XMOVDstore:
|
||||
return rewriteValueS390X_OpS390XMOVDstore(v, config)
|
||||
case OpS390XMOVDstoreconst:
|
||||
@@ -3240,28 +3236,13 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: is32BitInt(t) && isSigned(t)
|
||||
// result: (MOVWload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32BitInt(t) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVWload)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: is32BitInt(t) && !isSigned(t)
|
||||
// cond: is32BitInt(t)
|
||||
// result: (MOVWZload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is32BitInt(t) && !isSigned(t)) {
|
||||
if !(is32BitInt(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVWZload)
|
||||
@@ -3270,28 +3251,13 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: is16BitInt(t) && isSigned(t)
|
||||
// result: (MOVHload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16BitInt(t) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVHload)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: is16BitInt(t) && !isSigned(t)
|
||||
// cond: is16BitInt(t)
|
||||
// result: (MOVHZload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16BitInt(t) && !isSigned(t)) {
|
||||
if !(is16BitInt(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVHZload)
|
||||
@@ -3300,28 +3266,13 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: is8BitInt(t) && isSigned(t)
|
||||
// result: (MOVBload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is8BitInt(t) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVBload)
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: (t.IsBoolean() || (is8BitInt(t) && !isSigned(t)))
|
||||
// cond: (t.IsBoolean() || is8BitInt(t))
|
||||
// result: (MOVBZload ptr mem)
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) {
|
||||
if !(t.IsBoolean() || is8BitInt(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVBZload)
|
||||
@@ -7851,7 +7802,7 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
|
||||
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
@@ -7867,7 +7818,8 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value, config *Config) bool {
|
||||
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -8024,7 +7976,7 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDLT {
|
||||
@@ -8043,13 +7995,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDLE {
|
||||
@@ -8068,13 +8021,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDGT {
|
||||
@@ -8093,13 +8047,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDGE {
|
||||
@@ -8118,13 +8073,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDEQ {
|
||||
@@ -8143,13 +8099,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDNE {
|
||||
@@ -8168,13 +8125,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDGTnoinv {
|
||||
@@ -8193,13 +8151,14 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _))
|
||||
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVDGEnoinv {
|
||||
@@ -8218,25 +8177,27 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVBZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(Arg <t>))
|
||||
// cond: is8BitInt(t) && !isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -8246,19 +8207,21 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
|
||||
if !(is8BitInt(t) && !isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBZreg x:(MOVBZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -8386,19 +8349,20 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVBreg x:(MOVBload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBreg x:(Arg <t>))
|
||||
// cond: is8BitInt(t) && isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -8408,19 +8372,21 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value, config *Config) bool {
|
||||
if !(is8BitInt(t) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBreg x:(MOVBreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -9881,11 +9847,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
|
||||
v.AddArg(cmp)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDNE y _ (FlagEQ))
|
||||
// match: (MOVDNE _ y (FlagEQ))
|
||||
// cond:
|
||||
// result: y
|
||||
for {
|
||||
y := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v_2 := v.Args[2]
|
||||
if v_2.Op != OpS390XFlagEQ {
|
||||
break
|
||||
@@ -9895,11 +9861,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
|
||||
v.AddArg(y)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDNE _ x (FlagLT))
|
||||
// match: (MOVDNE x _ (FlagLT))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[1]
|
||||
x := v.Args[0]
|
||||
v_2 := v.Args[2]
|
||||
if v_2.Op != OpS390XFlagLT {
|
||||
break
|
||||
@@ -9909,11 +9875,11 @@ func rewriteValueS390X_OpS390XMOVDNE(v *Value, config *Config) bool {
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDNE _ x (FlagGT))
|
||||
// match: (MOVDNE x _ (FlagGT))
|
||||
// cond:
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[1]
|
||||
x := v.Args[0]
|
||||
v_2 := v.Args[2]
|
||||
if v_2.Op != OpS390XFlagGT {
|
||||
break
|
||||
@@ -10029,7 +9995,7 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _))
|
||||
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
@@ -10045,7 +10011,8 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value, config *Config) bool {
|
||||
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -10197,82 +10164,6 @@ func rewriteValueS390X_OpS390XMOVDloadidx(v *Value, config *Config) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueS390X_OpS390XMOVDnop(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDnop <t> x)
|
||||
// cond: t.Compare(x.Type) == CMPeq
|
||||
// result: x
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
if !(t.Compare(x.Type) == CMPeq) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDnop (MOVDconst [c]))
|
||||
// cond:
|
||||
// result: (MOVDconst [c])
|
||||
for {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpS390XMOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_0.AuxInt
|
||||
v.reset(OpS390XMOVDconst)
|
||||
v.AuxInt = c
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueS390X_OpS390XMOVDreg(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDreg <t> x)
|
||||
// cond: t.Compare(x.Type) == CMPeq
|
||||
// result: x
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
if !(t.Compare(x.Type) == CMPeq) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDreg (MOVDconst [c]))
|
||||
// cond:
|
||||
// result: (MOVDconst [c])
|
||||
for {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpS390XMOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_0.AuxInt
|
||||
v.reset(OpS390XMOVDconst)
|
||||
v.AuxInt = c
|
||||
return true
|
||||
}
|
||||
// match: (MOVDreg x)
|
||||
// cond: x.Uses == 1
|
||||
// result: (MOVDnop x)
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if !(x.Uses == 1) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDnop)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueS390X_OpS390XMOVDstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
@@ -11021,7 +10912,7 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
|
||||
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
@@ -11037,7 +10928,8 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value, config *Config) bool {
|
||||
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -11194,31 +11086,33 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVHZreg x:(MOVBZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHZreg x:(MOVHZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHZreg x:(Arg <t>))
|
||||
// cond: (is8BitInt(t) || is16BitInt(t)) && !isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -11228,31 +11122,34 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value, config *Config) bool {
|
||||
if !((is8BitInt(t) || is16BitInt(t)) && !isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHZreg x:(MOVBZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHZreg x:(MOVHZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -11380,43 +11277,46 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVHreg x:(MOVBload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(MOVBZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(MOVHload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(Arg <t>))
|
||||
// cond: (is8BitInt(t) || is16BitInt(t)) && isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -11426,43 +11326,47 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value, config *Config) bool {
|
||||
if !((is8BitInt(t) || is16BitInt(t)) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(MOVBreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(MOVBZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHreg x:(MOVHreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -12406,7 +12310,7 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _))
|
||||
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
@@ -12422,7 +12326,8 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value, config *Config) bool {
|
||||
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -12579,43 +12484,46 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVWZreg x:(MOVBZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(MOVHZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(MOVWZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVWZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(Arg <t>))
|
||||
// cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -12625,43 +12533,47 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value, config *Config) bool {
|
||||
if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(MOVBZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(MOVHZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWZreg x:(MOVWZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVWZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -12789,67 +12701,72 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (MOVWreg x:(MOVBload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVBZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVHload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVHZload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHZload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVWload _ _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVWload {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(Arg <t>))
|
||||
// cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpArg {
|
||||
@@ -12859,67 +12776,73 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value, config *Config) bool {
|
||||
if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVBreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVBZreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVBZreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVHreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVHreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVHreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWreg x:(MOVWreg _))
|
||||
// cond:
|
||||
// result: (MOVDreg x)
|
||||
// result: x
|
||||
for {
|
||||
x := v.Args[0]
|
||||
if x.Op != OpS390XMOVWreg {
|
||||
break
|
||||
}
|
||||
v.reset(OpS390XMOVDreg)
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@@ -18242,7 +18165,7 @@ func rewriteBlockS390X(b *Block, config *Config) bool {
|
||||
}
|
||||
// match: (If cond yes no)
|
||||
// cond:
|
||||
// result: (NE (CMPWconst [0] (MOVBZreg <config.fe.TypeBool()> cond)) yes no)
|
||||
// result: (NE (CMPWconst [0] (MOVBZreg cond)) yes no)
|
||||
for {
|
||||
v := b.Control
|
||||
_ = v
|
||||
@@ -18252,7 +18175,7 @@ func rewriteBlockS390X(b *Block, config *Config) bool {
|
||||
b.Kind = BlockS390XNE
|
||||
v0 := b.NewValue0(v.Line, OpS390XCMPWconst, TypeFlags)
|
||||
v0.AuxInt = 0
|
||||
v1 := b.NewValue0(v.Line, OpS390XMOVBZreg, config.fe.TypeBool())
|
||||
v1 := b.NewValue0(v.Line, OpS390XMOVBZreg, config.fe.TypeUInt64())
|
||||
v1.AddArg(cond)
|
||||
v0.AddArg(v1)
|
||||
b.SetControl(v0)
|
||||
|
||||
@@ -14,7 +14,6 @@ const (
|
||||
ScoreMemory
|
||||
ScoreDefault
|
||||
ScoreFlags
|
||||
ScoreSelectCall
|
||||
ScoreControl // towards bottom of block
|
||||
)
|
||||
|
||||
@@ -111,25 +110,10 @@ func schedule(f *Func) {
|
||||
// We want all the vardefs next.
|
||||
score[v.ID] = ScoreVarDef
|
||||
case v.Type.IsMemory():
|
||||
// Don't schedule independent operations after call to those functions.
|
||||
// runtime.selectgo will jump to next instruction after this call,
|
||||
// causing extra execution of those operations. Prevent it, by setting
|
||||
// priority to high value.
|
||||
if (v.Op == OpAMD64CALLstatic || v.Op == OpPPC64CALLstatic ||
|
||||
v.Op == OpARMCALLstatic || v.Op == OpARM64CALLstatic ||
|
||||
v.Op == Op386CALLstatic || v.Op == OpMIPS64CALLstatic ||
|
||||
v.Op == OpS390XCALLstatic || v.Op == OpMIPSCALLstatic) &&
|
||||
(isSameSym(v.Aux, "runtime.selectrecv") ||
|
||||
isSameSym(v.Aux, "runtime.selectrecv2") ||
|
||||
isSameSym(v.Aux, "runtime.selectsend") ||
|
||||
isSameSym(v.Aux, "runtime.selectdefault")) {
|
||||
score[v.ID] = ScoreSelectCall
|
||||
} else {
|
||||
// Schedule stores as early as possible. This tends to
|
||||
// reduce register pressure. It also helps make sure
|
||||
// VARDEF ops are scheduled before the corresponding LEA.
|
||||
score[v.ID] = ScoreMemory
|
||||
}
|
||||
// Schedule stores as early as possible. This tends to
|
||||
// reduce register pressure. It also helps make sure
|
||||
// VARDEF ops are scheduled before the corresponding LEA.
|
||||
score[v.ID] = ScoreMemory
|
||||
case v.Op == OpSelect0 || v.Op == OpSelect1:
|
||||
// Schedule the pseudo-op of reading part of a tuple
|
||||
// immediately after the tuple-generating op, since
|
||||
|
||||
@@ -35,7 +35,7 @@ func writebarrier(f *Func) {
|
||||
valueLoop:
|
||||
for i, v := range b.Values {
|
||||
switch v.Op {
|
||||
case OpStoreWB, OpMoveWB, OpMoveWBVolatile, OpZeroWB:
|
||||
case OpStoreWB, OpMoveWB, OpMoveWBVolatile:
|
||||
if IsStackAddr(v.Args[0]) {
|
||||
switch v.Op {
|
||||
case OpStoreWB:
|
||||
|
||||
@@ -1634,8 +1634,6 @@ func (p *parser) stmtBody(context string) []Stmt {
|
||||
return body
|
||||
}
|
||||
|
||||
var dummyCond = &Name{Value: "false"}
|
||||
|
||||
func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleStmt) {
|
||||
if p.tok == _Lbrace {
|
||||
return
|
||||
@@ -1682,8 +1680,7 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
|
||||
case *ExprStmt:
|
||||
cond = s.X
|
||||
default:
|
||||
p.syntax_error(fmt.Sprintf("%s used as value", String(s)))
|
||||
cond = dummyCond // avoid follow-up error for if statements
|
||||
p.error("invalid condition, tag, or type switch guard")
|
||||
}
|
||||
|
||||
p.xnest = outer
|
||||
|
||||
5
src/cmd/dist/test.go
vendored
5
src/cmd/dist/test.go
vendored
@@ -15,6 +15,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -353,7 +354,7 @@ func (t *tester) registerTests() {
|
||||
|
||||
// This test needs its stdout/stderr to be terminals, so we don't run it from cmd/go's tests.
|
||||
// See issue 18153.
|
||||
if t.goos == "linux" {
|
||||
if runtime.GOOS == "linux" {
|
||||
t.tests = append(t.tests, distTest{
|
||||
name: "cmd_go_test_terminal",
|
||||
heading: "cmd/go terminal test",
|
||||
@@ -567,7 +568,7 @@ func (t *tester) registerTests() {
|
||||
if t.gohostos == "linux" && t.goarch == "amd64" {
|
||||
t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", "main.go")
|
||||
}
|
||||
if t.goos == "linux" && t.goarch == "amd64" {
|
||||
if t.gohostos == "linux" && t.goarch == "amd64" {
|
||||
t.registerTest("testsanitizers", "../misc/cgo/testsanitizers", "./test.bash")
|
||||
}
|
||||
if t.hasBash() && t.goos != "android" && !t.iOS() && t.gohostos != "windows" {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// clean remove object files
|
||||
// doc show documentation for package or symbol
|
||||
// env print Go environment information
|
||||
// bug start a bug report
|
||||
// bug print information for bug reports
|
||||
// fix run go tool fix on packages
|
||||
// fmt run gofmt on package sources
|
||||
// generate generate Go files by processing source
|
||||
@@ -324,14 +324,15 @@
|
||||
// each named variable on its own line.
|
||||
//
|
||||
//
|
||||
// Start a bug report
|
||||
// Print information for bug reports
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go bug
|
||||
//
|
||||
// Bug opens the default browser and starts a new bug report.
|
||||
// The report includes useful system information.
|
||||
// Bug prints information that helps file effective bug reports.
|
||||
//
|
||||
// Bugs may be reported at https://golang.org/issue/new.
|
||||
//
|
||||
//
|
||||
// Run go tool fix on packages
|
||||
|
||||
@@ -20,10 +20,11 @@ import (
|
||||
var cmdBug = &Command{
|
||||
Run: runBug,
|
||||
UsageLine: "bug",
|
||||
Short: "start a bug report",
|
||||
Short: "print information for bug reports",
|
||||
Long: `
|
||||
Bug opens the default browser and starts a new bug report.
|
||||
The report includes useful system information.
|
||||
Bug prints information that helps file effective bug reports.
|
||||
|
||||
Bugs may be reported at https://golang.org/issue/new.
|
||||
`,
|
||||
}
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ func downloadPackage(p *Package) error {
|
||||
return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
|
||||
}
|
||||
// Guard against people setting GOPATH=$GOROOT.
|
||||
if filepath.Clean(list[0]) == filepath.Clean(goroot) {
|
||||
if list[0] == goroot {
|
||||
return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(list[0], "src/cmd/go/alldocs.go")); err == nil {
|
||||
|
||||
@@ -1683,111 +1683,173 @@ func homeEnvName() string {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultGOPATH(t *testing.T) {
|
||||
// Test go env missing GOPATH shows default.
|
||||
func TestMissingGOPATHEnvShowsDefault(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.parallel()
|
||||
tg.tempDir("home/go")
|
||||
tg.setenv(homeEnvName(), tg.path("home"))
|
||||
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.run("env", "GOPATH")
|
||||
tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
|
||||
|
||||
tg.setenv("GOROOT", tg.path("home/go"))
|
||||
tg.run("env", "GOPATH")
|
||||
tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
|
||||
|
||||
tg.setenv("GOROOT", tg.path("home/go")+"/")
|
||||
tg.run("env", "GOPATH")
|
||||
tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
|
||||
want := filepath.Join(os.Getenv(homeEnvName()), "go")
|
||||
got := strings.TrimSpace(tg.getStdout())
|
||||
if got != want {
|
||||
t.Errorf("got %q; want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultGOPATHGet(t *testing.T) {
|
||||
// Test go get missing GOPATH causes go get to warn if directory doesn't exist.
|
||||
func TestMissingGOPATHGetWarnsIfNotExists(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
t.Skip("skipping because git binary not found")
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
// setenv variables for test and defer deleting temporary home directory.
|
||||
tg.setenv("GOPATH", "")
|
||||
tmp, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tmp home: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
tg.setenv(homeEnvName(), tmp)
|
||||
|
||||
tg.run("get", "-v", "github.com/golang/example/hello")
|
||||
|
||||
want := fmt.Sprintf("created GOPATH=%s; see 'go help gopath'", filepath.Join(tmp, "go"))
|
||||
got := strings.TrimSpace(tg.getStderr())
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("got %q; want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Test go get missing GOPATH causes no warning if directory exists.
|
||||
func TestMissingGOPATHGetDoesntWarnIfExists(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
t.Skip("skipping because git binary not found")
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
// setenv variables for test and defer resetting them.
|
||||
tg.setenv("GOPATH", "")
|
||||
tmp, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tmp home: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
if err := os.Mkdir(filepath.Join(tmp, "go"), 0777); err != nil {
|
||||
t.Fatalf("could not create $HOME/go: %v", err)
|
||||
}
|
||||
|
||||
tg.setenv(homeEnvName(), tmp)
|
||||
|
||||
tg.run("get", "github.com/golang/example/hello")
|
||||
|
||||
got := strings.TrimSpace(tg.getStderr())
|
||||
if got != "" {
|
||||
t.Errorf("got %q; wants empty", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Test go get missing GOPATH fails if pointed file is not a directory.
|
||||
func TestMissingGOPATHGetFailsIfItsNotDirectory(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
// setenv variables for test and defer resetting them.
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.tempDir("home")
|
||||
tg.setenv(homeEnvName(), tg.path("home"))
|
||||
tmp, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tmp home: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
// warn for creating directory
|
||||
tg.run("get", "-v", "github.com/golang/example/hello")
|
||||
tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
|
||||
path := filepath.Join(tmp, "go")
|
||||
if err := ioutil.WriteFile(path, nil, 0777); err != nil {
|
||||
t.Fatalf("could not create GOPATH at %s: %v", path, err)
|
||||
}
|
||||
tg.setenv(homeEnvName(), tmp)
|
||||
|
||||
// no warning if directory already exists
|
||||
tg.must(os.RemoveAll(tg.path("home/go")))
|
||||
tg.tempDir("home/go")
|
||||
tg.run("get", "github.com/golang/example/hello")
|
||||
tg.grepStderrNot(".", "expected no output on standard error")
|
||||
const pkg = "github.com/golang/example/hello"
|
||||
tg.runFail("get", pkg)
|
||||
|
||||
// error if $HOME/go is a file
|
||||
tg.must(os.RemoveAll(tg.path("home/go")))
|
||||
tg.tempFile("home/go", "")
|
||||
tg.runFail("get", "github.com/golang/example/hello")
|
||||
tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
|
||||
msg := "not a directory"
|
||||
if runtime.GOOS == "windows" {
|
||||
msg = "The system cannot find the path specified."
|
||||
}
|
||||
want := fmt.Sprintf("package %s: mkdir %s: %s", pkg, filepath.Join(tmp, "go"), msg)
|
||||
got := strings.TrimSpace(tg.getStderr())
|
||||
if got != want {
|
||||
t.Errorf("got %q; wants %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
|
||||
// Test go install of missing package when missing GOPATH fails and shows default GOPATH.
|
||||
func TestMissingGOPATHInstallMissingPackageFailsAndShowsDefault(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.tempDir("home")
|
||||
tg.setenv(homeEnvName(), tg.path("home"))
|
||||
|
||||
tg.runFail("install", "github.com/golang/example/hello")
|
||||
tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
|
||||
// setenv variables for test and defer resetting them.
|
||||
tg.setenv("GOPATH", "")
|
||||
tmp, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tmp home: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
if err := os.Mkdir(filepath.Join(tmp, "go"), 0777); err != nil {
|
||||
t.Fatalf("could not create $HOME/go: %v", err)
|
||||
}
|
||||
tg.setenv(homeEnvName(), tmp)
|
||||
|
||||
const pkg = "github.com/golang/example/hello"
|
||||
tg.runFail("install", pkg)
|
||||
|
||||
pkgPath := filepath.Join(strings.Split(pkg, "/")...)
|
||||
want := fmt.Sprintf("can't load package: package %s: cannot find package \"%s\" in any of:", pkg, pkg) +
|
||||
fmt.Sprintf("\n\t%s (from $GOROOT)", filepath.Join(runtime.GOROOT(), "src", pkgPath)) +
|
||||
fmt.Sprintf("\n\t%s (from $GOPATH)", filepath.Join(tmp, "go", "src", pkgPath))
|
||||
|
||||
got := strings.TrimSpace(tg.getStderr())
|
||||
if got != want {
|
||||
t.Errorf("got %q; wants %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 4186. go get cannot be used to download packages to $GOROOT.
|
||||
// Test that without GOPATH set, go get should fail.
|
||||
func TestGoGetIntoGOROOT(t *testing.T) {
|
||||
func TestWithoutGOPATHGoGetFails(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.parallel()
|
||||
tg.tempDir("src")
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.setenv("GOROOT", tg.path("."))
|
||||
tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
|
||||
}
|
||||
|
||||
// Fails because GOROOT=GOPATH
|
||||
// Test that with GOPATH=$GOROOT, go get should fail.
|
||||
func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.parallel()
|
||||
tg.tempDir("src")
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
tg.setenv("GOROOT", tg.path("."))
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
|
||||
tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
|
||||
|
||||
// Fails because GOROOT=GOPATH after cleaning.
|
||||
tg.setenv("GOPATH", tg.path(".")+"/")
|
||||
tg.setenv("GOROOT", tg.path("."))
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
|
||||
tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
|
||||
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
tg.setenv("GOROOT", tg.path(".")+"/")
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
|
||||
tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
|
||||
|
||||
// Fails because GOROOT=$HOME/go so default GOPATH unset.
|
||||
tg.tempDir("home/go")
|
||||
tg.setenv(homeEnvName(), tg.path("home"))
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.setenv("GOROOT", tg.path("home/go"))
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
|
||||
|
||||
tg.setenv(homeEnvName(), tg.path("home")+"/")
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.setenv("GOROOT", tg.path("home/go"))
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
|
||||
|
||||
tg.setenv(homeEnvName(), tg.path("home"))
|
||||
tg.setenv("GOPATH", "")
|
||||
tg.setenv("GOROOT", tg.path("home/go")+"/")
|
||||
tg.runFail("get", "-d", "github.com/golang/example/hello")
|
||||
tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
|
||||
tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
|
||||
}
|
||||
|
||||
func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
|
||||
@@ -2227,24 +2289,6 @@ func TestTestEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTestRaceInstall(t *testing.T) {
|
||||
if !canRace {
|
||||
t.Skip("no race detector")
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
|
||||
|
||||
tg.tempDir("pkg")
|
||||
pkgdir := tg.path("pkg")
|
||||
tg.run("install", "-race", "-pkgdir="+pkgdir, "std")
|
||||
tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg")
|
||||
if tg.getStderr() != "" {
|
||||
t.Error("go test -i -race: rebuilds cached packages")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDryRunWithCgo(t *testing.T) {
|
||||
if !canCgo {
|
||||
t.Skip("skipping because cgo not enabled")
|
||||
@@ -3700,13 +3744,6 @@ func TestMatchesOnlySubtestParallelIsOK(t *testing.T) {
|
||||
tg.grepBoth(okPattern, "go test did not say ok")
|
||||
}
|
||||
|
||||
// Issue 18845
|
||||
func TestBenchTimeout(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
|
||||
}
|
||||
|
||||
func TestLinkXImportPathEscape(t *testing.T) {
|
||||
// golang.org/issue/16710
|
||||
tg := testgo(t)
|
||||
@@ -3750,26 +3787,3 @@ GLOBL ·constants<>(SB),8,$8
|
||||
tg.setenv("GOPATH", tg.path("go"))
|
||||
tg.run("build", "p")
|
||||
}
|
||||
|
||||
// Issue 18778.
|
||||
func TestDotDotDotOutsideGOPATH(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
tg.tempFile("pkgs/a.go", `package x`)
|
||||
tg.tempFile("pkgs/a_test.go", `package x_test
|
||||
import "testing"
|
||||
func TestX(t *testing.T) {}`)
|
||||
|
||||
tg.tempFile("pkgs/a/a.go", `package a`)
|
||||
tg.tempFile("pkgs/a/a_test.go", `package a_test
|
||||
import "testing"
|
||||
func TestA(t *testing.T) {}`)
|
||||
|
||||
tg.cd(tg.path("pkgs"))
|
||||
tg.run("build", "./...")
|
||||
tg.run("test", "./...")
|
||||
tg.run("list", "./...")
|
||||
tg.grepStdout("pkgs$", "expected package not listed")
|
||||
tg.grepStdout("pkgs/a", "expected package not listed")
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ func main() {
|
||||
// Diagnose common mistake: GOPATH==GOROOT.
|
||||
// This setting is equivalent to not setting GOPATH at all,
|
||||
// which is not what most people want when they do it.
|
||||
if gopath := buildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) {
|
||||
if gopath := buildContext.GOPATH; gopath == runtime.GOROOT() {
|
||||
fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
|
||||
} else {
|
||||
for _, p := range filepath.SplitList(gopath) {
|
||||
|
||||
@@ -429,7 +429,7 @@ func setErrorPos(p *Package, importPos []token.Position) *Package {
|
||||
func cleanImport(path string) string {
|
||||
orig := path
|
||||
path = pathpkg.Clean(path)
|
||||
if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
|
||||
if strings.HasPrefix(orig, "./") && path != ".." && path != "." && !strings.HasPrefix(path, "../") {
|
||||
path = "./" + path
|
||||
}
|
||||
return path
|
||||
@@ -955,6 +955,10 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
||||
if p.Name == "main" && goarch == "arm" {
|
||||
importPaths = append(importPaths, "math")
|
||||
}
|
||||
// In coverage atomic mode everything depends on sync/atomic.
|
||||
if testCoverMode == "atomic" && (!p.Standard || (p.ImportPath != "runtime/cgo" && p.ImportPath != "runtime/race" && p.ImportPath != "sync/atomic")) {
|
||||
importPaths = append(importPaths, "sync/atomic")
|
||||
}
|
||||
}
|
||||
|
||||
// Runtime and its internal packages depend on runtime/internal/sys,
|
||||
|
||||
@@ -545,10 +545,6 @@ func runTest(cmd *Command, args []string) {
|
||||
|
||||
// Prepare build + run + print actions for all packages being tested.
|
||||
for _, p := range pkgs {
|
||||
// sync/atomic import is inserted by the cover tool. See #18486
|
||||
if testCover && testCoverMode == "atomic" {
|
||||
ensureImport(p, "sync/atomic")
|
||||
}
|
||||
buildTest, runTest, printTest, err := b.test(p)
|
||||
if err != nil {
|
||||
str := err.Error()
|
||||
@@ -640,23 +636,6 @@ func runTest(cmd *Command, args []string) {
|
||||
b.do(root)
|
||||
}
|
||||
|
||||
// ensures that package p imports the named package.
|
||||
func ensureImport(p *Package, pkg string) {
|
||||
for _, d := range p.deps {
|
||||
if d.Name == pkg {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
a := loadPackage(pkg, &importStack{})
|
||||
if a.Error != nil {
|
||||
fatalf("load %s: %v", pkg, a.Error)
|
||||
}
|
||||
computeStale(a)
|
||||
|
||||
p.imports = append(p.imports, a)
|
||||
}
|
||||
|
||||
func contains(x []string, s string) bool {
|
||||
for _, t := range x {
|
||||
if t == s {
|
||||
@@ -915,13 +894,9 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
|
||||
|
||||
if buildContext.GOOS == "darwin" {
|
||||
if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" {
|
||||
t.IsIOS = true
|
||||
t.NeedOS = true
|
||||
t.NeedCgo = true
|
||||
}
|
||||
}
|
||||
if t.TestMain == nil {
|
||||
t.NeedOS = true
|
||||
}
|
||||
|
||||
for _, cp := range pmain.imports {
|
||||
if len(cp.coverVars) > 0 {
|
||||
@@ -1368,8 +1343,7 @@ type testFuncs struct {
|
||||
NeedTest bool
|
||||
ImportXtest bool
|
||||
NeedXtest bool
|
||||
NeedOS bool
|
||||
IsIOS bool
|
||||
NeedCgo bool
|
||||
Cover []coverInfo
|
||||
}
|
||||
|
||||
@@ -1470,7 +1444,7 @@ var testmainTmpl = template.Must(template.New("main").Parse(`
|
||||
package main
|
||||
|
||||
import (
|
||||
{{if .NeedOS}}
|
||||
{{if not .TestMain}}
|
||||
"os"
|
||||
{{end}}
|
||||
"testing"
|
||||
@@ -1486,10 +1460,8 @@ import (
|
||||
_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
|
||||
{{end}}
|
||||
|
||||
{{if .IsIOS}}
|
||||
"os/signal"
|
||||
{{if .NeedCgo}}
|
||||
_ "runtime/cgo"
|
||||
"syscall"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
@@ -1551,32 +1523,6 @@ func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts
|
||||
{{end}}
|
||||
|
||||
func main() {
|
||||
{{if .IsIOS}}
|
||||
// Send a SIGUSR2, which will be intercepted by LLDB to
|
||||
// tell the test harness that installation was successful.
|
||||
// See misc/ios/go_darwin_arm_exec.go.
|
||||
signal.Notify(make(chan os.Signal), syscall.SIGUSR2)
|
||||
syscall.Kill(0, syscall.SIGUSR2)
|
||||
signal.Reset(syscall.SIGUSR2)
|
||||
|
||||
// The first argument supplied to an iOS test is an offset
|
||||
// suffix for the current working directory.
|
||||
// Process it here, and remove it from os.Args.
|
||||
const hdr = "cwdSuffix="
|
||||
if len(os.Args) < 2 || len(os.Args[1]) <= len(hdr) || os.Args[1][:len(hdr)] != hdr {
|
||||
panic("iOS test not passed a working directory suffix")
|
||||
}
|
||||
suffix := os.Args[1][len(hdr):]
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := os.Chdir(dir + "/" + suffix); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Args = append([]string{os.Args[0]}, os.Args[2:]...)
|
||||
{{end}}
|
||||
|
||||
{{if .CoverEnabled}}
|
||||
testing.RegisterCover(testing.Cover{
|
||||
Mode: {{printf "%q" .CoverMode}},
|
||||
|
||||
10
src/cmd/go/testdata/timeoutbench_test.go
vendored
10
src/cmd/go/testdata/timeoutbench_test.go
vendored
@@ -1,10 +0,0 @@
|
||||
package timeoutbench_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func BenchmarkSleep1s(b *testing.B) {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
// Copyright 2017 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 (
|
||||
"cmd/internal/objfile"
|
||||
"debug/dwarf"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDWARF(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("DWARF is not supported on Windows")
|
||||
}
|
||||
|
||||
testenv.MustHaveCGO(t)
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
if runtime.GOOS == "plan9" {
|
||||
t.Skip("skipping on plan9; no DWARF symbol table in executables")
|
||||
}
|
||||
|
||||
out, err := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Stale}}", "cmd/link").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go list: %v\n%s", err, out)
|
||||
}
|
||||
if string(out) != "false\n" {
|
||||
t.Fatalf("cmd/link is stale - run go install cmd/link")
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "go-link-TestDWARF")
|
||||
if err != nil {
|
||||
t.Fatal("TempDir failed: ", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
for _, prog := range []string{"testprog", "testprogcgo"} {
|
||||
t.Run(prog, func(t *testing.T) {
|
||||
exe := filepath.Join(tmpDir, prog+".exe")
|
||||
dir := "../../runtime/testdata/" + prog
|
||||
out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, dir).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go build -o %v %v: %v\n%s", exe, dir, err, out)
|
||||
}
|
||||
|
||||
f, err := objfile.Open(exe)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
syms, err := f.Symbols()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var addr uint64
|
||||
for _, sym := range syms {
|
||||
if sym.Name == "main.main" {
|
||||
addr = sym.Addr
|
||||
break
|
||||
}
|
||||
}
|
||||
if addr == 0 {
|
||||
t.Fatal("cannot find main.main in symbols")
|
||||
}
|
||||
|
||||
d, err := f.DWARF()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// TODO: We'd like to use filepath.Join here.
|
||||
// Also related: golang.org/issue/19784.
|
||||
wantFile := path.Join(prog, "main.go")
|
||||
wantLine := 24
|
||||
r := d.Reader()
|
||||
var line dwarf.LineEntry
|
||||
for {
|
||||
cu, err := r.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cu == nil {
|
||||
break
|
||||
}
|
||||
if cu.Tag != dwarf.TagCompileUnit {
|
||||
r.SkipChildren()
|
||||
continue
|
||||
}
|
||||
lr, err := d.LineReader(cu)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for {
|
||||
err := lr.Next(&line)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if line.Address == addr {
|
||||
if !strings.HasSuffix(line.File.Name, wantFile) || line.Line != wantLine {
|
||||
t.Errorf("%#x is %s:%d, want %s:%d", addr, line.File.Name, line.Line, filepath.Join("...", wantFile), wantLine)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Fatalf("did not find file:line for %#x (main.main)", addr)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -238,8 +238,6 @@ func determineLinkMode(ctxt *Link) {
|
||||
Linkmode = LinkExternal
|
||||
} else if iscgo && externalobj {
|
||||
Linkmode = LinkExternal
|
||||
} else if Buildmode == BuildmodePIE {
|
||||
Linkmode = LinkExternal // https://golang.org/issue/18968
|
||||
} else {
|
||||
Linkmode = LinkInternal
|
||||
}
|
||||
|
||||
@@ -1080,7 +1080,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
|
||||
epcs = s
|
||||
|
||||
dsym := ctxt.Syms.Lookup(dwarf.InfoPrefix+s.Name, int(s.Version))
|
||||
dsym.Attr |= AttrHidden | AttrReachable
|
||||
dsym.Attr |= AttrHidden
|
||||
dsym.Type = obj.SDWARFINFO
|
||||
for _, r := range dsym.R {
|
||||
if r.Type == obj.R_DWARFREF && r.Sym.Size == 0 {
|
||||
|
||||
@@ -430,10 +430,6 @@ func (ctxt *Link) loadlib() {
|
||||
// We now have enough information to determine the link mode.
|
||||
determineLinkMode(ctxt)
|
||||
|
||||
if Headtype == obj.Hdarwin && Linkmode == LinkExternal {
|
||||
*FlagTextAddr = 0
|
||||
}
|
||||
|
||||
if Linkmode == LinkExternal && SysArch.Family == sys.PPC64 {
|
||||
toc := ctxt.Syms.Lookup(".TOC.", 0)
|
||||
toc.Type = obj.SDYNIMPORT
|
||||
@@ -1002,10 +998,6 @@ func (l *Link) hostlink() {
|
||||
|
||||
if !*FlagS && !debug_s {
|
||||
argv = append(argv, "-gdwarf-2")
|
||||
} else if Headtype == obj.Hdarwin {
|
||||
// Recent versions of macOS print
|
||||
// ld: warning: option -s is obsolete and being ignored
|
||||
// so do not pass any arguments.
|
||||
} else {
|
||||
argv = append(argv, "-s")
|
||||
}
|
||||
@@ -1227,7 +1219,7 @@ func (l *Link) hostlink() {
|
||||
l.Logf("%s", out)
|
||||
}
|
||||
|
||||
if !*FlagS && !*FlagW && !debug_s && Headtype == obj.Hdarwin {
|
||||
if !*FlagS && !debug_s && Headtype == obj.Hdarwin {
|
||||
// Skip combining dwarf on arm.
|
||||
if !SysArch.InFamily(sys.ARM, sys.ARM64) {
|
||||
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
|
||||
|
||||
@@ -449,7 +449,7 @@ func Asmbmacho(ctxt *Link) {
|
||||
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
|
||||
} else {
|
||||
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
|
||||
ms.vsize = Segdwarf.Vaddr + Segdwarf.Length - Segtext.Vaddr
|
||||
ms.vsize = ms.filesize
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
|
||||
var realdwarf, linkseg *macho.Segment
|
||||
var dwarfstart, linkstart int64
|
||||
var dwarfaddr, linkaddr int64
|
||||
var linkoffset uint32
|
||||
|
||||
const (
|
||||
@@ -42,7 +41,8 @@ const (
|
||||
LC_DYLIB_CODE_SIGN_DRS = 0x2B
|
||||
LC_ENCRYPTION_INFO_64 = 0x2C
|
||||
|
||||
pageAlign = 12 // 4096 = 1 << 12
|
||||
dwarfMinAlign = 6 // 64 = 1 << 6
|
||||
pageAlign = 12 // 4096 = 1 << 12
|
||||
)
|
||||
|
||||
type loadCmd struct {
|
||||
@@ -157,13 +157,16 @@ func machoCombineDwarf(inexe, dsym, outexe string) error {
|
||||
}
|
||||
|
||||
// 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)
|
||||
maxalign := uint32(dwarfMinAlign) //
|
||||
for _, sect := range dwarfm.Sections {
|
||||
if sect.Align > maxalign {
|
||||
maxalign = sect.Align
|
||||
}
|
||||
}
|
||||
dwarfstart = machoCalcStart(realdwarf.Offset, linkseg.Offset, maxalign)
|
||||
if _, err = outf.Seek(dwarfstart, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
dwarfaddr = int64((linkseg.Addr + linkseg.Memsz + 1<<pageAlign - 1) &^ (1<<pageAlign - 1))
|
||||
|
||||
if _, err = dwarff.Seek(int64(realdwarf.Offset), 0); err != nil {
|
||||
return err
|
||||
@@ -274,10 +277,10 @@ func machoUpdateSegment(r loadCmdReader, seg, sect interface{}) error {
|
||||
return err
|
||||
}
|
||||
// There shouldn't be any sections, but just to make sure...
|
||||
return machoUpdateSections(r, segValue, reflect.ValueOf(sect), uint64(linkoffset), 0)
|
||||
return machoUpdateSections(r, segValue, reflect.ValueOf(sect), uint64(linkoffset))
|
||||
}
|
||||
|
||||
func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset, deltaAddr uint64) error {
|
||||
func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, delta uint64) error {
|
||||
iseg := reflect.Indirect(seg)
|
||||
nsect := iseg.FieldByName("Nsect").Uint()
|
||||
if nsect == 0 {
|
||||
@@ -288,20 +291,16 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset,
|
||||
isect := reflect.Indirect(sect)
|
||||
offsetField := isect.FieldByName("Offset")
|
||||
reloffField := isect.FieldByName("Reloff")
|
||||
addrField := isect.FieldByName("Addr")
|
||||
sectSize := int64(isect.Type().Size())
|
||||
for i := uint64(0); i < nsect; i++ {
|
||||
if err := r.ReadAt(sectOffset, sect.Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
if offsetField.Uint() != 0 {
|
||||
offsetField.SetUint(offsetField.Uint() + deltaOffset)
|
||||
offsetField.SetUint(offsetField.Uint() + delta)
|
||||
}
|
||||
if reloffField.Uint() != 0 {
|
||||
reloffField.SetUint(reloffField.Uint() + deltaOffset)
|
||||
}
|
||||
if addrField.Uint() != 0 {
|
||||
addrField.SetUint(addrField.Uint() + deltaAddr)
|
||||
reloffField.SetUint(reloffField.Uint() + delta)
|
||||
}
|
||||
if err := r.WriteAt(sectOffset, sect.Interface()); err != nil {
|
||||
return err
|
||||
@@ -328,30 +327,15 @@ func machoUpdateDwarfHeader(r *loadCmdReader) error {
|
||||
if err := r.ReadAt(0, seg); err != nil {
|
||||
return err
|
||||
}
|
||||
segv := reflect.ValueOf(seg).Elem()
|
||||
|
||||
segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
|
||||
segv.FieldByName("Addr").SetUint(uint64(dwarfaddr))
|
||||
|
||||
deltaOffset := uint64(dwarfstart) - realdwarf.Offset
|
||||
deltaAddr := uint64(dwarfaddr) - realdwarf.Addr
|
||||
|
||||
// If we set Memsz to 0 (and might as well set Addr too),
|
||||
// then the xnu kernel will bail out halfway through load_segment
|
||||
// and not apply further sanity checks that we might fail in the future.
|
||||
// We don't need the DWARF information actually available in memory.
|
||||
// But if we do this for buildmode=c-shared then the user-space
|
||||
// dynamic loader complains about memsz < filesz. Sigh.
|
||||
if Buildmode != BuildmodeCShared {
|
||||
segv.FieldByName("Addr").SetUint(0)
|
||||
segv.FieldByName("Memsz").SetUint(0)
|
||||
deltaAddr = 0
|
||||
}
|
||||
segValue := reflect.ValueOf(seg)
|
||||
offset := reflect.Indirect(segValue).FieldByName("Offset")
|
||||
|
||||
delta := uint64(dwarfstart) - realdwarf.Offset
|
||||
offset.SetUint(offset.Uint() + delta)
|
||||
if err := r.WriteAt(0, seg); err != nil {
|
||||
return err
|
||||
}
|
||||
return machoUpdateSections(*r, segv, reflect.ValueOf(sect), deltaOffset, deltaAddr)
|
||||
return machoUpdateSections(*r, segValue, reflect.ValueOf(sect), delta)
|
||||
}
|
||||
|
||||
func machoUpdateLoadCommand(r loadCmdReader, cmd interface{}, fields ...string) error {
|
||||
|
||||
@@ -168,7 +168,7 @@ func container(s *Symbol) int {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
if Buildmode == BuildmodePlugin && Headtype == obj.Hdarwin && onlycsymbol(s) {
|
||||
if Buildmode == BuildmodePlugin && onlycsymbol(s) {
|
||||
return 1
|
||||
}
|
||||
// We want to generate func table entries only for the "lowest level" symbols,
|
||||
|
||||
@@ -87,7 +87,6 @@ func genplt(ctxt *ld.Link) {
|
||||
//
|
||||
// This assumes "case 1" from the ABI, where the caller needs
|
||||
// us to save and restore the TOC pointer.
|
||||
var stubs []*ld.Symbol
|
||||
for _, s := range ctxt.Textp {
|
||||
for i := range s.R {
|
||||
r := &s.R[i]
|
||||
@@ -109,7 +108,7 @@ func genplt(ctxt *ld.Link) {
|
||||
if stub.Size == 0 {
|
||||
// Need outer to resolve .TOC.
|
||||
stub.Outer = s
|
||||
stubs = append(stubs, stub)
|
||||
ctxt.Textp = append(ctxt.Textp, stub)
|
||||
gencallstub(ctxt, 1, stub, r.Sym)
|
||||
}
|
||||
|
||||
@@ -122,11 +121,6 @@ func genplt(ctxt *ld.Link) {
|
||||
ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
|
||||
}
|
||||
}
|
||||
// Put call stubs at the beginning (instead of the end).
|
||||
// So when resolving the relocations to calls to the stubs,
|
||||
// the addresses are known and trampolines can be inserted
|
||||
// when necessary.
|
||||
ctxt.Textp = append(stubs, ctxt.Textp...)
|
||||
}
|
||||
|
||||
func genaddmoduledata(ctxt *ld.Link) {
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
func TestLargeText(t *testing.T) {
|
||||
if testing.Short() || (obj.GOARCH != "ppc64le" && obj.GOARCH != "ppc64" && obj.GOARCH != "arm") {
|
||||
t.Skipf("Skipping large text section test in short mode or on %s", obj.GOARCH)
|
||||
t.Skip("Skipping large text section test in short mode or on %s", obj.GOARCH)
|
||||
}
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
|
||||
@@ -204,6 +204,12 @@ func TestMTF(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
digits = mustLoadFile("testdata/e.txt.bz2")
|
||||
twain = mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
|
||||
random = mustLoadFile("testdata/random.data.bz2")
|
||||
)
|
||||
|
||||
func benchmarkDecode(b *testing.B, compressed []byte) {
|
||||
// Determine the uncompressed size of testfile.
|
||||
uncompressedSize, err := io.Copy(ioutil.Discard, NewReader(bytes.NewReader(compressed)))
|
||||
@@ -221,18 +227,6 @@ func benchmarkDecode(b *testing.B, compressed []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecodeDigits(b *testing.B) {
|
||||
digits := mustLoadFile("testdata/e.txt.bz2")
|
||||
b.ResetTimer()
|
||||
benchmarkDecode(b, digits)
|
||||
}
|
||||
func BenchmarkDecodeTwain(b *testing.B) {
|
||||
twain := mustLoadFile("testdata/Mark.Twain-Tom.Sawyer.txt.bz2")
|
||||
b.ResetTimer()
|
||||
benchmarkDecode(b, twain)
|
||||
}
|
||||
func BenchmarkDecodeRand(b *testing.B) {
|
||||
random := mustLoadFile("testdata/random.data.bz2")
|
||||
b.ResetTimer()
|
||||
benchmarkDecode(b, random)
|
||||
}
|
||||
func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
|
||||
func BenchmarkDecodeTwain(b *testing.B) { benchmarkDecode(b, twain) }
|
||||
func BenchmarkDecodeRand(b *testing.B) { benchmarkDecode(b, random) }
|
||||
|
||||
@@ -136,17 +136,14 @@ func (d *compressor) fillDeflate(b []byte) int {
|
||||
delta := d.hashOffset - 1
|
||||
d.hashOffset -= delta
|
||||
d.chainHead -= delta
|
||||
|
||||
// Iterate over slices instead of arrays to avoid copying
|
||||
// the entire table onto the stack (Issue #18625).
|
||||
for i, v := range d.hashPrev[:] {
|
||||
for i, v := range d.hashPrev {
|
||||
if int(v) > delta {
|
||||
d.hashPrev[i] = uint32(int(v) - delta)
|
||||
} else {
|
||||
d.hashPrev[i] = 0
|
||||
}
|
||||
}
|
||||
for i, v := range d.hashHead[:] {
|
||||
for i, v := range d.hashHead {
|
||||
if int(v) > delta {
|
||||
d.hashHead[i] = uint32(int(v) - delta)
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
@@ -865,33 +864,3 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxStackSize(t *testing.T) {
|
||||
// This test must not run in parallel with other tests as debug.SetMaxStack
|
||||
// affects all goroutines.
|
||||
n := debug.SetMaxStack(1 << 16)
|
||||
defer debug.SetMaxStack(n)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
defer wg.Wait()
|
||||
|
||||
b := make([]byte, 1<<20)
|
||||
for level := HuffmanOnly; level <= BestCompression; level++ {
|
||||
// Run in separate goroutine to increase probability of stack regrowth.
|
||||
wg.Add(1)
|
||||
go func(level int) {
|
||||
defer wg.Done()
|
||||
zw, err := NewWriter(ioutil.Discard, level)
|
||||
if err != nil {
|
||||
t.Errorf("level %d, NewWriter() = %v, want nil", level, err)
|
||||
}
|
||||
if n, err := zw.Write(b); n != len(b) || err != nil {
|
||||
t.Errorf("level %d, Write() = (%d, %v), want (%d, nil)", level, n, err, len(b))
|
||||
}
|
||||
if err := zw.Close(); err != nil {
|
||||
t.Errorf("level %d, Close() = %v, want nil", level, err)
|
||||
}
|
||||
zw.Reset(ioutil.Discard)
|
||||
}(level)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ func newDeflateFast() *deflateFast {
|
||||
func (e *deflateFast) encode(dst []token, src []byte) []token {
|
||||
// Ensure that e.cur doesn't wrap.
|
||||
if e.cur > 1<<30 {
|
||||
e.resetAll()
|
||||
*e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
|
||||
}
|
||||
|
||||
// This check isn't in the Snappy implementation, but there, the caller
|
||||
@@ -265,21 +265,6 @@ func (e *deflateFast) reset() {
|
||||
|
||||
// Protect against e.cur wraparound.
|
||||
if e.cur > 1<<30 {
|
||||
e.resetAll()
|
||||
}
|
||||
}
|
||||
|
||||
// resetAll resets the deflateFast struct and is only called in rare
|
||||
// situations to prevent integer overflow. It manually resets each field
|
||||
// to avoid causing large stack growth.
|
||||
//
|
||||
// See https://golang.org/issue/18636.
|
||||
func (e *deflateFast) resetAll() {
|
||||
// This is equivalent to:
|
||||
// *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
|
||||
e.cur = maxStoreBlockSize
|
||||
e.prev = e.prev[:0]
|
||||
for i := range e.table {
|
||||
e.table[i] = tableEntry{}
|
||||
*e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,11 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestGZIPFilesHaveZeroMTimes checks that every .gz file in the tree
|
||||
// has a zero MTIME. This is a requirement for the Debian maintainers
|
||||
// to be able to have deterministic packages.
|
||||
//
|
||||
// See https://golang.org/issue/14937.
|
||||
// Per golang.org/issue/14937, check that every .gz file
|
||||
// in the tree has a zero mtime.
|
||||
func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
|
||||
// To avoid spurious false positives due to untracked GZIP files that
|
||||
// may be in the user's GOROOT (Issue 18604), we only run this test on
|
||||
// the builders, which should have a clean checkout of the tree.
|
||||
if testenv.Builder() == "" {
|
||||
t.Skip("skipping test on non-builder")
|
||||
if testing.Short() && testenv.Builder() == "" {
|
||||
t.Skip("skipping in short mode")
|
||||
}
|
||||
goroot, err := filepath.EvalSymlinks(runtime.GOROOT())
|
||||
if err != nil {
|
||||
|
||||
@@ -95,7 +95,7 @@ func TestSignAndVerify(t *testing.T) {
|
||||
func TestSigningWithDegenerateKeys(t *testing.T) {
|
||||
// Signing with degenerate private keys should not cause an infinite
|
||||
// loop.
|
||||
badKeys := []struct {
|
||||
badKeys := []struct{
|
||||
p, q, g, y, x string
|
||||
}{
|
||||
{"00", "01", "00", "00", "00"},
|
||||
@@ -105,7 +105,7 @@ func TestSigningWithDegenerateKeys(t *testing.T) {
|
||||
for i, test := range badKeys {
|
||||
priv := PrivateKey{
|
||||
PublicKey: PublicKey{
|
||||
Parameters: Parameters{
|
||||
Parameters: Parameters {
|
||||
P: fromHex(test.p),
|
||||
Q: fromHex(test.q),
|
||||
G: fromHex(test.g),
|
||||
|
||||
@@ -300,29 +300,6 @@ var p224BaseMultTests = []baseMultTest{
|
||||
},
|
||||
}
|
||||
|
||||
type scalarMultTest struct {
|
||||
k string
|
||||
xIn, yIn string
|
||||
xOut, yOut string
|
||||
}
|
||||
|
||||
var p256MultTests = []scalarMultTest{
|
||||
{
|
||||
"2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
|
||||
"023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
|
||||
"f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
|
||||
"4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
|
||||
"a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
|
||||
},
|
||||
{
|
||||
"313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
|
||||
"cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
|
||||
"a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
|
||||
"831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
|
||||
"93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
|
||||
},
|
||||
}
|
||||
|
||||
func TestBaseMult(t *testing.T) {
|
||||
p224 := P224()
|
||||
for i, e := range p224BaseMultTests {
|
||||
@@ -402,19 +379,6 @@ func TestP256Mult(t *testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for i, e := range p256MultTests {
|
||||
x, _ := new(big.Int).SetString(e.xIn, 16)
|
||||
y, _ := new(big.Int).SetString(e.yIn, 16)
|
||||
k, _ := new(big.Int).SetString(e.k, 16)
|
||||
expectedX, _ := new(big.Int).SetString(e.xOut, 16)
|
||||
expectedY, _ := new(big.Int).SetString(e.yOut, 16)
|
||||
|
||||
xx, yy := p256.ScalarMult(x, y, k.Bytes())
|
||||
if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
|
||||
t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfinity(t *testing.T) {
|
||||
|
||||
@@ -1314,12 +1314,12 @@ TEXT p256SubInternal(SB),NOSPLIT,$0
|
||||
ADCQ p256const0<>(SB), acc5
|
||||
ADCQ $0, acc6
|
||||
ADCQ p256const1<>(SB), acc7
|
||||
ANDQ $1, mul0
|
||||
ADCQ $0, mul0
|
||||
|
||||
CMOVQEQ acc0, acc4
|
||||
CMOVQEQ acc1, acc5
|
||||
CMOVQEQ acc2, acc6
|
||||
CMOVQEQ acc3, acc7
|
||||
CMOVQNE acc0, acc4
|
||||
CMOVQNE acc1, acc5
|
||||
CMOVQNE acc2, acc6
|
||||
CMOVQNE acc3, acc7
|
||||
|
||||
RET
|
||||
/* ---------------------------------------*/
|
||||
|
||||
@@ -84,15 +84,15 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
|
||||
|
||||
@@ -563,7 +563,6 @@ func (c *Config) Clone() *Config {
|
||||
Certificates: c.Certificates,
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
GetClientCertificate: c.GetClientCertificate,
|
||||
GetConfigForClient: c.GetConfigForClient,
|
||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user