Compare commits

..

13 Commits

Author SHA1 Message Date
Rick Hudson
1d4942afe0 [dev.garbage] runtime: determine if an object is public
ROC (request oriented collector) needs to determine
if an object is visible to other goroutines, i.e.
public. In a later CL this will be used by the write
barrier and the publishing logic to distinguish between
local and public objects and act accordingly.

Change-Id: I6a80da9deb21f57e831a2ec04e41477f997a8c33
Reviewed-on: https://go-review.googlesource.com/25056
Reviewed-by: Austin Clements <austin@google.com>
2017-05-25 18:05:53 +00:00
Austin Clements
8b25a00e6d Merge branch 'master' into dev.garbage
Change-Id: I36274cf72b8e1908efc8e375cab7880d7b0b3f43
2017-01-11 11:34:07 -05:00
Austin Clements
42afbd9e63 Merge branch 'master' into dev.garbage
Sync to 1.8 beta 1.

Change-Id: Iddd3773babd8fe50aed791ef7150d0c7c455cc8d
2016-12-05 12:15:50 -05:00
Austin Clements
f9f6c90ed1 [dev.garbage] Merge branch 'master' into dev.garbage
This merges master as of the Go 1.7 release.

Change-Id: I95ac0f96a0837173a2b8d7e8aaadf6fecc1baeaf
2016-08-25 11:55:08 -04:00
Rick Hudson
69161e279e [dev.garbage] runtime: Add GODEBUG=gcroc=n
Add command line boilerplace that turns the ROC algorithm on.
gcroc=0 or not specified:
	does not turn ROC on but some benign code may run.
gcroc=1
	simply turns the algorithm on
gcroc>1
	same as gcroc but with increasing levels of diagnostics
	being turned on. Expect gcroc>1 to not be as performant as
	gcroc=1

Change-Id: I6348b6768f7a3f8c2f69ef01ea20efebf992029e
Reviewed-on: https://go-review.googlesource.com/21368
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-26 13:21:53 +00:00
Austin Clements
fb4c718209 [dev.garbage] Merge branch 'master' into dev.garbage
Change-Id: I8ba4b012d82921f9521f471b1c0b5a1f6149a986
2016-07-19 17:54:41 -04:00
Austin Clements
81b74bf9c5 [dev.garbage] runtime: make _TinySizeClass an int8 to prevent use as spanClass
Currently _TinySizeClass is untyped, which means it can accidentally
be used as a spanClass (not that I would know this from experience or
anything). Make it an int8 to avoid this mix up.

Change-Id: I1e69eccee436ea5aa45e9a9828a013e369e03f1a
Reviewed-on: https://go-review.googlesource.com/24372
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
2016-06-23 16:26:08 +00:00
Austin Clements
edb54c300f [dev.garbage] runtime: eliminate heapBitsSetTypeNoScan
It's no longer necessary to maintain the bitmap of noscan objects
since we now use the span metadata to determine that they're noscan
instead of the bitmap.

The combined effect of segregating noscan spans and the follow-on
optimizations is almost no effect on the go1 benchmarks and a 1.19%
improvement in the garbage benchmark:

name              old time/op  new time/op  delta
XBenchGarbage-12  2.13ms ± 2%  2.11ms ± 1%  -1.19%  (p=0.000 n=19+20)

name                      old time/op    new time/op    delta
BinaryTree17-12              2.42s ± 1%     2.41s ± 1%  -0.50%  (p=0.001 n=20+17)
Fannkuch11-12                2.14s ± 0%     2.12s ± 0%  -0.91%  (p=0.000 n=20+17)
FmtFprintfEmpty-12          45.2ns ± 0%    45.2ns ± 1%    ~     (p=0.677 n=16+19)
FmtFprintfString-12          131ns ± 0%     132ns ± 1%  +0.57%  (p=0.000 n=16+20)
FmtFprintfInt-12             126ns ± 1%     126ns ± 0%    ~     (p=0.078 n=18+16)
FmtFprintfIntInt-12          199ns ± 0%     195ns ± 0%  -2.19%  (p=0.000 n=14+20)
FmtFprintfPrefixedInt-12     196ns ± 1%     196ns ± 0%    ~     (p=0.155 n=19+16)
FmtFprintfFloat-12           254ns ± 0%     253ns ± 0%  -0.50%  (p=0.000 n=14+19)
FmtManyArgs-12               803ns ± 1%     798ns ± 0%  -0.71%  (p=0.000 n=18+19)
GobDecode-12                7.11ms ± 1%    7.07ms ± 1%  -0.50%  (p=0.024 n=18+19)
GobEncode-12                5.87ms ± 0%    5.86ms ± 1%    ~     (p=0.113 n=19+20)
Gzip-12                      218ms ± 1%     218ms ± 1%    ~     (p=0.879 n=19+20)
Gunzip-12                   37.2ms ± 0%    37.3ms ± 0%  +0.14%  (p=0.047 n=19+20)
HTTPClientServer-12         80.5µs ± 6%    82.8µs ± 8%  +2.91%  (p=0.008 n=19+20)
JSONEncode-12               15.4ms ± 1%    15.4ms ± 1%  -0.32%  (p=0.003 n=18+19)
JSONDecode-12               55.1ms ± 1%    53.0ms ± 1%  -3.87%  (p=0.000 n=18+20)
Mandelbrot200-12            4.08ms ± 1%    4.10ms ± 1%  +0.34%  (p=0.001 n=19+17)
GoParse-12                  3.20ms ± 1%    3.21ms ± 1%    ~     (p=0.138 n=19+19)
RegexpMatchEasy0_32-12      70.6ns ± 2%    70.4ns ± 2%    ~     (p=0.343 n=20+20)
RegexpMatchEasy0_1K-12       240ns ± 0%     242ns ± 2%  +0.88%  (p=0.000 n=15+20)
RegexpMatchEasy1_32-12      70.5ns ± 1%    70.2ns ± 3%    ~     (p=0.053 n=18+20)
RegexpMatchEasy1_1K-12       374ns ± 1%     374ns ± 1%    ~     (p=0.705 n=20+19)
RegexpMatchMedium_32-12      108ns ± 1%     108ns ± 1%    ~     (p=0.854 n=20+19)
RegexpMatchMedium_1K-12     33.5µs ± 1%    33.6µs ± 2%    ~     (p=0.897 n=18+20)
RegexpMatchHard_32-12       1.76µs ± 1%    1.75µs ± 1%    ~     (p=0.771 n=18+18)
RegexpMatchHard_1K-12       52.8µs ± 1%    52.8µs ± 1%    ~     (p=0.678 n=17+19)
Revcomp-12                   381ms ± 1%     380ms ± 0%    ~     (p=0.320 n=20+16)
Template-12                 65.6ms ± 1%    65.1ms ± 2%  -0.75%  (p=0.003 n=20+20)
TimeParse-12                 324ns ± 1%     326ns ± 1%  +0.72%  (p=0.000 n=18+18)
TimeFormat-12                342ns ± 0%     343ns ± 1%  +0.22%  (p=0.004 n=15+18)
[Geo mean]                  52.4µs         52.3µs       -0.18%

Change-Id: Ic77faaa15cdac3bfbbb0032dde5c204e05a0fd8e
Reviewed-on: https://go-review.googlesource.com/23702
Reviewed-by: Rick Hudson <rlh@golang.org>
2016-06-15 21:17:15 +00:00
Austin Clements
312aa09996 [dev.garbage] runtime: eliminate heapBits.hasPointers
This is no longer necessary now that we can more efficiently consult
the span's noscan bit.

Change-Id: Id0b00b278533660973f45eb6efa5b00f373d58af
Reviewed-on: https://go-review.googlesource.com/23701
Reviewed-by: Rick Hudson <rlh@golang.org>
2016-06-15 21:17:04 +00:00
Austin Clements
d491e550c3 [dev.garbage] runtime: separate spans of noscan objects
Currently, we mix objects with pointers and objects without pointers
("noscan" objects) together in memory. As a result, for every object
we grey, we have to check that object's heap bits to find out if it's
noscan, which adds to the per-object cost of GC. This also hurts the
TLB footprint of the garbage collector because it decreases the
density of scannable objects at the page level.

This commit improves the situation by using separate spans for noscan
objects. This will allow a much simpler noscan check (in a follow up
CL), eliminate the need to clear the bitmap of noscan objects (in a
follow up CL), and improves TLB footprint by increasing the density of
scannable objects.

This is also a step toward eliminating dead bits, since the current
noscan check depends on checking the dead bit of the first word.

This has no effect on the heap size of the garbage benchmark.

We'll measure the performance change of this after the follow-up
optimizations.

Change-Id: I13bdc4869538ece5649a8d2a41c6605371618e40
Reviewed-on: https://go-review.googlesource.com/23700
Reviewed-by: Rick Hudson <rlh@golang.org>
2016-06-15 21:16:53 +00:00
Austin Clements
641c32dafa [dev.garbage] Merge branch 'master' into dev.garbage
Change-Id: I7ab2afca656e8c145804d9823cd084b8a85bccd7
2016-06-06 10:01:41 -04:00
Austin Clements
2e495a1df6 [dev.garbage] Merge branch 'master' into dev.garbage
Change-Id: I35edefb4464566601850081ecc84dd3535d60ceb
2016-05-16 14:29:53 -04:00
Austin Clements
344476d23c [dev.garbage] Merge branch 'master' into dev.garbage
Change-Id: I2e04fd9e7071efe33ce76f2f10a8dbde53ba90b9
2016-05-09 14:49:54 -04:00
195 changed files with 1616 additions and 4919 deletions

View File

@@ -5,37 +5,39 @@ reliable, and efficient software.
![Gopher image](doc/gopher/fiveyears.jpg)
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.

View File

@@ -1 +0,0 @@
go1.8.2

View File

@@ -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 &lt;dev@chimeracoder.net&gt;
<li>Andrew Gerrand &lt;adg@golang.org&gt;
<li>Dave Cheney &lt;dave@cheney.net&gt;
<li>Jason Buberel &lt;jbuberel@google.com&gt;
<li>Peggy Li &lt;peggyli.224@gmail.com&gt;
<li>Sarah Adams &lt;sadams.codes@gmail.com&gt;
<li>Steve Francia &lt;steve.francia@gmail.com&gt;
@@ -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>

View File

@@ -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>

View File

@@ -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 &mdash; for example,
if you start contributing code on behalf of a new company &mdash; 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 &ldquo;The Go
Authors&rdquo;&mdash;the copyright holders&mdash;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>&lt;branch&gt;</i>
</pre>
<p>
from any directory in your Go repository to commit the changes so far.
The name <i>&lt;branch&gt;</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 &lt;email@address.com&gt;"
</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 &amp;&amp;
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&mdash;the people&mdash;are;
the <a href="/AUTHORS"><code>AUTHORS</code></a> file defines
who &ldquo;The Go Authors&rdquo;&mdash;the copyright holders&mdash;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>

View File

@@ -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&lt;*testing.T&gt;
</pre>
<p>
That <code>struct hchan&lt;*testing.T&gt;</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&lt;*testing.T&gt;</code> is the runtime-internal representation of a channel. It is currently empty, or gdb would have pretty-printed it's contents.
</p>
<p>

View File

@@ -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>

View File

@@ -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>.

View File

@@ -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>

View File

@@ -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>

View File

@@ -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:\&gt; <b>cd %USERPROFILE%\go\src\hello</b>
C:\Users\Gopher\go\src\hello&gt; <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&gt; <b>hello</b>
hello, world
</pre>

View File

@@ -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)
}
}

View File

@@ -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;
}
*/

View File

@@ -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

View File

@@ -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")
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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() {}

View File

@@ -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")
}
}

View File

@@ -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) {}

View File

@@ -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

View File

@@ -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() {}

View File

@@ -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

View File

@@ -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")
}

View File

@@ -5,8 +5,6 @@ import (
"reflect"
)
var SlicePtr interface{} = &[]int{}
var V int = 1
var HasMask []string = []string{"hi"}

View File

@@ -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")
}
}

View File

@@ -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")
}
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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{}) {

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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()
}
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)
}
})

View File

@@ -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))

View File

@@ -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())

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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{

View File

@@ -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])

View File

@@ -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

View File

@@ -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{

View File

@@ -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}}

View File

@@ -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 ->

View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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
{

View File

@@ -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

View File

@@ -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

View File

@@ -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()
}
}
}

View File

@@ -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()
}

View File

@@ -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})

View File

@@ -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 {

View File

@@ -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,
},
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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" {

View File

@@ -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

View File

@@ -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.
`,
}

View File

@@ -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 {

View File

@@ -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")
}

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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}},

View File

@@ -1,10 +0,0 @@
package timeoutbench_test
import (
"testing"
"time"
)
func BenchmarkSleep1s(b *testing.B) {
time.Sleep(1 * time.Second)
}

View File

@@ -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)
})
}
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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")

View File

@@ -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
}
}

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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) }

View File

@@ -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 {

View File

@@ -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)
}
}

View File

@@ -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]}
}
}

View File

@@ -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 {

View File

@@ -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),

View File

@@ -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) {

View File

@@ -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
/* ---------------------------------------*/

View File

@@ -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},

View File

@@ -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